-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom Plugin in Response Phase has sideeffect to if-match/etag handling #13430
Comments
Hi @TGeb-EV , Could you provide more details about your custom plugin? thank you. And I could not reproduce this, it looks like that Kong 3.7.1 code base works smoothly for my custom plugin. I did following things: ============================
|
This case ist the case if you only use etag for simple caching. There is another use-case to use this also for optimistic locking. You want to update a resource by a put with is given etag (if-macth content), and if the etag matches you will get the updated resource with a new etag. so your test service should return a different etag as the put request., That does not work in my setup (similar to yours, but with a express service to exclude nginx caching behavior interferences). |
Update - The Plugin configuration have to be activated, but the bug ist with activated plugin contantly there. |
Hi @TGeb-EV , And still I could not reproduce it with PUT to update the resource, what I did as following: 1> Update the resource with a new file via PUT method (kong-dev) haix@kong:~/workspace/371$ curl -X PUT -T "/home/haix/workspace/371/index.html" --header 'If-Match: "66a7566e-267"' -i http://localhost:8000/mock/index.html 2> Check the ETag value for the updated resource (kong-dev) haix@kong:~/workspace/371$ curl -i http://localhost:8000/mock
(kong-dev) haix@kong:~/workspace/371$ 3> Get the updated resource with header "If-Match" (kong-dev) haix@kong:~/workspace/371$ curl --header 'If-Match: "66a84c11-101"' -i http://localhost:8000/mock
(kong-dev) haix@kong:~/workspace/371$ 4> Get the updated resource with header "If-None-Match" (kong-dev) haix@kong:~/workspace/371$ curl --header 'If-None-Match: "66a84c11-101"' -i http://localhost:8000/mock (kong-dev) haix@kong:~/workspace/371$ |
Per my local setup, the behavior of Kong and upstream service do really conform to HTTP standards. According to following text from rfc9110, it looks like that either "2xx" or "412" is permitted by the stardard. "An origin server that evaluates an If-Match condition MUST NOT perform the requested method if the condition evaluates to false. Instead, the origin server MAY indicate that the conditional request failed by responding with a 412 (Precondition Failed) status code. Alternatively, if the request is a state-changing operation that appears to have already been applied to the selected representation, the origin server MAY respond with a 2xx (Successful) status code (i.e., the change requested by the user agent has already succeeded, but the user agent might not be aware of it, perhaps because the prior response was lost or an equivalent change was made by some other user agent). Allowing an origin server to send a success response when a change request appears to have already been applied is more efficient for many authoring use cases, but comes with some risk if multiple user agents are making change requests that are very similar but not cooperative. For example, multiple user agents writing to a common resource as a semaphore (e.g., a nonatomic increment) are likely to collide and potentially lose important state transitions. For those kinds of resources, an origin server is better off being stringent in sending 412 for every failed precondition on an unsafe method. In other cases, excluding the ETag field from a success response might encourage the user agent to perform a GET as its next request to eliminate confusion about the resource's current state." https://www.rfc-editor.org/rfc/rfc9110.html#name-if-match |
Did you tried my request flow? The behavior is different with or without plugin. Both flows (yours and mine) are kind of standard conform, but this is not consistent. The precondition do not fail, the if-match is matching, but the response is with another etag, so kong says this is not matching, but kong should do nothing. For me this is a bug and the kong response phase is not usable. This unexpected behavior is a risk to us and maybe other usecases are also affected or has side effects. The additional GET request in the rfc is a recommendation not a MUST. In our usecase the additional GET request makes really no sense (I understand the concerns). I programmed our needed plugin now in another phase and it works. |
@xianghai2 would you take a look at it again? |
back to this. Hi @TGeb-EV, which phase/function was your plugin implemented for? for me, it looks like that my plugin of the access phase or reponse funtion has no such issue. thanks. |
Kong Docker Image Build files including plugin source code: Custom Service for testing, called testservice in compose: Docker compose with configured custom Docker Images and Custom Plugin
If you delete the Plugin configuration, the first request after deletion also fails with 412. A further call seems to be a 200 then. Now you have everything to work with. You have mabe only to adjust the image names for Kong and the testservice in the docker-compose file Log of compose for a few requests where you see, that the service answers with 200 and Kong with 412, you also see the creation and deletion requests of the plugin configuration: |
THe 412 error code is returned by nginx/openresty, and kong redirect its page content, so Its the default bebaviour of nginx/openresty. And we could not disable this default behaviour. Check the source code of nginx: |
@chobits , why is it working with plugins in other phases or without such a plugin? This behavior should be the case everytime if you are right! Also I tried to disable Proxy Caching for nginx. In a nginx only setup, the nginx is working without this behavior if I disabled the caching or / if-modified-since. And why is it only when a Plugin in response phase is used? |
Hi @TGeb-EV , that's probably due to the ETag conformance behavior of response phase plugin or cache. And your upstream test service(index.js) may want to be something like following to conform to expected ETag behavior:
|
Hi @xianghai2 , PUT a changed Entity (same ID) to the service with a if-Match header (value "v1") -> the service checks if the etag ist correct like the following
The service answers with 200 and the new etag value. The Kong then responds with 412 and an error message. If you now say it is OK, and that the behavior should change only by adding an empty plugin, I will not agree, but I am done with this discussion. |
Let's close this as the dissussoin was done. thanks. |
If you don't want to fix it, it is OK to me. |
Is there an existing issue for this?
Kong version (
$ kong version
)3.7.1
Current Behavior
A custom plugin in response phase has sideeffect to if-match/etag handling.
A global configured plugin (enabled or not) leads to 412 responses if Requests with "If-Match) header are incoming
Expected Behavior
The if-match header should be ignored, with and without the configured plugin. Without everything works as intended
Steps To Reproduce
`local TestPlugin = {
PRIORITY = 850,
VERSION = '0.0.1'
}
function TestPlugin:response(conf)
end
return TestPlugin
`
2. Create a global plugin configuration for this plugin
3. configure some service connected directly to host (no Kong upstream/LB functionality)
4. make a request with a "if-match" header to the service trough kong
5. the response is a 412
6. if the plugin is configured and deactivated the response is 412
7. if the plugin configuration is deleted everything works as intended
8. disabling proxy caching changes nothing
Anything else?
No response
The text was updated successfully, but these errors were encountered: