Nginx 0.7.6 sends original POST body in proxied GET subrequests from SSI

Apologies if you get this twice, apparently the first time I sent it my
confirmation hadn’t been processed yet.

I have a PHP script (proxied via Apache) that accepts file uploads.
These
are then processed by an external batch processor, which may take a long
time. To not keep the PHP script waiting for the batch process to
complete,
it writes a temporary file containing SSI include requests, and gives
that
file back to nginx via X-Accel-Redirect. This way nginx can wait for
completion (when the first SSI include becomes ready), and then send the
second SSI include to another PHP script that reports the batch process
result to the browser.

However, when contacting the second PHP script, nginx resends the
original
POST body even though the subrequest correctly uses the GET method
(since
0.6.26). I have verified this using tcpdump, the GET request has a
Content-Length header equal to the original POST body length, and a
Content-Type of e.g. “multipart/form-data;
boundary=----------uwPZJQ9jJJ0O7Q94Bs8ae1”, followed by the POST body.

Apparently this confuses PHP or Apache, so it closes the connection
before
nginx is ready, which causes nginx to consider the SSI include to have
failed, with the following log message:

2008/07/08 14:29:34 [error] 14064#0: *16 upstream prematurely closed
connection while reading response header from upstream, client: […]

The basic setup works fine when doing a POST without a file upload. But
still, I think nginx should send neither Content-Length, Content-Type
nor
the POST body content in a GET subrequest (i.e., afaict, any of them).

I’ve tried to fix it by clearing sr->request_body in line 1789 of
ngx_http_core_module.c, but while that gets rid of the actual body
content,
the Content-Length and Content-Type headers are still there and I’ve
been
unable to remove these from the subrequest.

Any help is welcome, thanks.

On Tue, Jul 08, 2008 at 04:22:45PM +0200, piespy wrote:

result to the browser.
failed, with the following log message:
ngx_http_core_module.c, but while that gets rid of the actual body content,
the Content-Length and Content-Type headers are still there and I’ve been
unable to remove these from the subrequest.

Any help is welcome, thanks.

location /subrequest {
proxy_pass_request_body off;

On 7/8/08, Igor S. [email protected] wrote:

location /subrequest {
proxy_pass_request_body off;

Thanks. That wasn’t enough though, I also needed
“proxy_pass_request_headers off” or it would still send the
Content-Type and Content-Length headers even though it wasn’t sending
the corresponding body (making the request invalid according to RFC
2616). And then I had to manually set the Host header again. (I
suppose I could also just have hidden the Content-* headers instead.)

Probably “proxy_pass_request_body off” should also automatically
remove the Content-* headers referring to the body, or at least the
documentation changed to say that they need to be removed when doing
this to avoid invalid requests.

I also think that this removal of the request body should be the
default behaviour for subrequests, since nobody expects a GET request
to have a body.

By the way, I was surprised to see, reading RFC 2616 now, that request
bodies are apparently allowed (or rather, not prohibited) with any of
the request methods it documents, including GET or even HEAD. This
seems counter-productive.