On Tue, Aug 2, 2016 at 4:07 PM, Luca Toscano <[email protected]> wrote: > > 2016-08-02 15:23 GMT+02:00 Yann Ylavic <[email protected]>: >> >> If that's correct, we indeed shouldn't break until we got >> AP_FCGI_END_REQUEST, so that we can reuse the connection when all goes >> well. > > This was exactly what I way trying to do with this commit, but only when the > connection is reused. It has an annoying downside, like introducing a bit of > latency between the HTTP headers flush to the client and the end of the > request for the use case described below (but it works well).
If I understand well the below, even if we don't reuse the connection we should not close it under the backend when we turn a response to a 304. > >> >> But since it's a 304 (or a 204 which should be handled the same here), >> we don't expect any body between the header and AP_FCGI_END_REQUEST, >> so if that happens (something else than AP_FCGI_END_REQUEST is read >> while ignore_body == 1), we must bail out with conn->close=1 to avoid >> reusing the connection for any further request. >> If the response header has not been forwarded already, we could either >> respond with a BAD_GATEWAY instead or forward it before leaving >> (possibly be lenient with CGIs). > > There is one case in which a mod_proxy_fcgi returns a 304 but there is also > body to read/process, namely when a "regular" FCGI response is returned by a > backend script with a Last-Modified header and the client uses something > like If-Modified-Since. In this case ap_scan_script_header_err_brigade_ex > (through ap_scan_script_header_err_core_ex -> ap_meets_conditions) sets the > "status" variable in mod_proxy_fcgi to HTTP_NOT_MODIFIED, OK, I missed that. > but the > message-body has been sent anyway. No, nothing is sent to the client yet (!seen_end_of_headers). > I am not sure if the FCGI script would be > in violation of the RFC behaving like this but if not it is a valid use > case. The CGI does nothing special, it just does not handle pre-conditions and httpd will do that for it. So we need to detect whether the 304 is a CGI Status or ours. It seems that in the former case r->status is 304, whereas in the latter case this is the local variable 'status' only. We could possibly set "cgi_status = r->status" in mod_proxy_fcgi and bail out if anything is read but AP_FCGI_END_REQUEST when cgi_status == [23]04. Otherwise let ignore_body suck up the response body (if any) so that the connection can be reused if all goes well until the next request.
