I've done additional tests, and I'm probably misunderstanding some stuff… :/
First, it seems to me that Varnish do consume the entire payload *before*
sending anything to the backend (naively, I was thinking that varnish would
start the backend request "sooner").
So, I set-up ngynx as a "dumb" backend to absorbe the post payloads.
Additionally, I told ngynx to have a very small POST size limit, and send 413.
If curl-ing ngynx with a (too) big payload, ngynx immediately validates the
content-length and sends the 413 answer. The upload stops gracefully without
much content being sent, and curl happily reads the 413.
Interestingly, if I use that setup as a backend to Varnish to workaround my
problem (as I described in the previous mail), Varnish ends-up again with
5 FetchError c backend write error: 32 (Broken pipe)
and does 503.
Meaning to me that it couldn't handle ngynx answer… while curl can…
</confused>
- Olivier
Le 15 sept. 2011 à 04:13, Olivier G a écrit :
> Hi there.
>
> I have a problem with calling "error" and POST requests.
>
> Reproducing is rather simple - use a default varnish install, then just do:
>
> sub vcl_recv{
> error 413 "Whatever";
> }
>
> Now, curl your server by posting a (small) payload.
> -> (might) work, and the client (might) get a 413 answer
>
> Now, curl your server by posting a (somewhat huge ~ 1MB) payload.
> -> curl will end-up with a "broken pipe" without getting any answer.
>
> Browsers (at least Firefox and Chrome) doing XHR in the same setup will
> end-up in the same state (readyState 4, status 0) (without being able to read
> the answer).
>
> On the other hand, Varnishlog demonstrates that the answer clearly is sent,
> and everything is normal from Varnish POV.
>
>
> Interestingly, even Varnish as a client (if pointing a backend to the Varnish
> sending the error in recv), exhibits:
> 5 FetchError c backend write error: 32 (Broken pipe)
> and returns a 503 no matter the actual code sent by the "backend".
> … which makes me think that varnish (server) behavior in that case is wrong.
>
>
> Also:
> If you do the "error" in "vcl_pass", you get the same problem.
> If you "error" in "vcl_fetch", though… things work as expected.
>
>
>
> So, it looks to me like:
> 1- varnish doesn't read the request body before it actually queries the
> backend (in which case it passes it), or before it gets out of hit (in which
> case the body is dropped - though, if the request has a body, it's quite
> likely we will call "pass"...)
> 2- calling "error" means Varnish closes the tcp connection immediately
> 3- a client that finds itself in a position where the connection is closed
> *before it has time to write the entire request* just stops here and fail
> 4- calling "error" means Varnish doesn't wait for the entire request body to
> be available/consumed (if it hasn't been already)
>
>
> Assuming I'm correct in these assumptions, then it means that "error" when
> handling requests with a body is NOT usable at all before having queried a
> backend.
>
>
> I'm not sure this behavior is intended - if it is, then maybe the
> documentation should be updated? (I couldn't find a reference to that problem
> in here: https://www.varnish-cache.org/docs/3.0/reference/vcl.html), and
> error is clearly mentioned as being usable in recv, etc.
> If it's not, then possibly the solution would be that the error routine
> actually makes sure that the entire request body has been sent.
>
>
>
> Right now, I'm workarounding by calling "error" inside vcl_fetch after having
> queried a dumb backend which only purpose is to force varnish to consume the
> body - though this is quite convoluted and suboptimal.
>
>
> What do you guys think?
>
>
> Thanks a lot!
>
> - Olivier
_______________________________________________
varnish-misc mailing list
[email protected]
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-misc