Bug 61090 - mod_proxy gives 502 on early HTTP response (3xx, 4xx, 5xx)
Summary: mod_proxy gives 502 on early HTTP response (3xx, 4xx, 5xx)
Status: NEW
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_proxy_http (show other bugs)
Version: 2.4.25
Hardware: PC Mac OS X 10.1
: P2 normal (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-05-12 21:30 UTC by felipe
Modified: 2017-05-15 21:12 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description felipe 2017-05-12 21:30:48 UTC
I’ve got an upstream application that sits behind mod_proxy. When a client POSTs a file upload via a form, that gets proxied to my application: mod_proxy appears to spool part of the file upload, then it starts sending..

The problem is that my application occasionally sends back a 307 or 308. My application, once it receives the headers and determines that it needs to redirect, sends the 307 response then close()s its side of the connection.

From what I can see in the strace output between Apache and my application, though, Apache never poll()s to see if the upstream endpoint has sent a response. It just keeps sending the file upload, which eventually gives back ECONNRESET, in response to which I get errors in my Apache log, and the client gets a nasty 502 error.

It seems like Apache should be poll()ing for a read event on the upstream connection to detect whether it should stop proxying and instead forward on the response?
Comment 1 felipe 2017-05-15 16:34:17 UTC
This actually happens on any early HTTP response, not just on 307s.
Comment 2 felipe 2017-05-15 16:48:31 UTC
Note that RFC 2616/8.2.4 specifies that clients SHOULD implement behavior such as this task describes:

-------------
 If at any point an error status is received, the client

      - SHOULD NOT continue and

      - SHOULD close the connection if it has not completed sending the
        request message.
Comment 3 Eric Covener 2017-05-15 17:10:21 UTC
(In reply to felipe from comment #2)
> Note that RFC 2616/8.2.4 specifies that clients SHOULD implement behavior
> such as this task describes:
> 
> -------------
>  If at any point an error status is received, the client
> 
>       - SHOULD NOT continue and
> 
>       - SHOULD close the connection if it has not completed sending the
>         request message.

I think the PR is a useful requirement, but AFAICT this guidance above was not carried forward to httpbis (and even in 2616 there is no requirement to poll for a status code mid-request, so we cannot say it has been received).

See 7230 6.6 for expectations on how connections are safely torn down.
Comment 4 felipe 2017-05-15 18:41:41 UTC
Whether the upstream application does a “staged” shutdown as 7230/6.6 envisions or does an abrupt close(), the change in mod_proxy would be the same, wouldn’t it?

Maybe mod_proxy wouldn’t necessarily have to poll() for a read event unless ECONNRESET is received? I’m not sure of the performance implications of poll()ing for 2 events regularly rather than just one, but I’d think that would be the simplest way to handle the situation.
Comment 5 Eric Covener 2017-05-15 18:51:10 UTC
(In reply to felipe from comment #4)
> Whether the upstream application does a “staged” shutdown as 7230/6.6
> envisions or does an abrupt close(), the change in mod_proxy would be the
> same, wouldn’t it?

I don't think so, my assumption is that if the server had read the body, there would be no RST and the response would be read and returned as if it was a function of the body (as in a normal flow)

> 
> Maybe mod_proxy wouldn’t necessarily have to poll() for a read event unless
> ECONNRESET is received? I’m not sure of the performance implications of
> poll()ing for 2 events regularly rather than just one, but I’d think that
> would be the simplest way to handle the situation.

Seems like there is/was a risk in waiting for the write failure, the unread response might not still be given back to mod_proxy if the stack has seen the RST.
Comment 6 felipe 2017-05-15 21:12:54 UTC
(In reply to Eric Covener from comment #5)
> (In reply to felipe from comment #4)
> > Whether the upstream application does a “staged” shutdown as 7230/6.6
> > envisions or does an abrupt close(), the change in mod_proxy would be the
> > same, wouldn’t it?
> 
> I don't think so, my assumption is that if the server had read the body,
> there would be no RST and the response would be read and returned as if it
> was a function of the body (as in a normal flow)

Having the server read the (entire) POST body is wasteful, though: the client is “waiting for nothing”.

> 
> > 
> > Maybe mod_proxy wouldn’t necessarily have to poll() for a read event unless
> > ECONNRESET is received? I’m not sure of the performance implications of
> > poll()ing for 2 events regularly rather than just one, but I’d think that
> > would be the simplest way to handle the situation.
> 
> Seems like there is/was a risk in waiting for the write failure, the unread
> response might not still be given back to mod_proxy if the stack has seen
> the RST.

It’s definitely a less clean approach, true.