[mod_proxy,mod_scgi] shutdown remote only if local (#2743)
shutdown(fd, SHUT_WR) after sending request to proxy or SCGI only if remote is local and platform is not *BSD or Darwin. The reason this fix is special-casing *BSD and Darwin is that the Single Unix Specification and POSIX.1-2013 clearly specify that POLLHUP event should be returned by poll only when the stream is no longer writable. A half-closed socket that is still writable clearly does not match that condition, yet that is what I am seeing on Darwin (El Capitan), and presumably what others are seeing on *BSD, from which Apple originally inherited the Darwin TCP stack. Single Unix Specification (SUSv2) from 1997 (yes, that is nearly 20 years ago): http://pubs.opengroup.org/onlinepubs/007908799/xsh/poll.html POLLHUP The device has been disconnected. This event and POLLOUT are mutually exclusive; a stream can never be writable if a hangup has occurred. However, this event and POLLIN, POLLRDNORM, POLLRDBAND or POLLPRI are not mutually exclusive. This flag is only valid in the revents bitmask; it is ignored in the events member. Updated version of The Open Group Base Specifications Issue 7 (published in 2013): http://pubs.opengroup.org/onlinepubs/9699919799/ POLLHUP A device has been disconnected, or a pipe or FIFO has been closed by the last process that had it open for writing. Once set, the hangup state of a FIFO shall persist until some process opens the FIFO for writing or until all read-only file descriptors for the FIFO are closed. This event and POLLOUT are mutually-exclusive; a stream can never be writable if a hangup has occurred. However, this event and POLLIN, POLLRDNORM, POLLRDBAND, or POLLPRI are not mutually-exclusive. This flag is only valid in the revents bitmask; it shall be ignored in the events member. x-ref: "1.4.40/41 mod_proxy, mod_scgi may trigger POLLHUP on *BSD,Darwin" https://redmine.lighttpd.net/issues/2743personal/stbuehler/mod-csrf-old
parent
156bea3859
commit
1de652f40b
|
@ -854,7 +854,20 @@ static handler_t proxy_write_request(server *srv, handler_ctx *hctx) {
|
|||
|
||||
if (hctx->wb->bytes_out == hctx->wb_reqlen) {
|
||||
fdevent_event_clr(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
|
||||
shutdown(hctx->fd, SHUT_WR);/* future: remove if HTTP/1.1 request */
|
||||
#if (defined(__APPLE__) && defined(__MACH__)) \
|
||||
|| defined(__FreeBSD__) || defined(__NetBSD__) \
|
||||
|| defined(__OpenBSD__) || defined(__DragonflyBSD__)
|
||||
/*(*BSD stack on remote might signal POLLHUP and remote
|
||||
* might treat as socket error instead of half-close)*/
|
||||
#else
|
||||
/*(remote could be different machine running affected OS,
|
||||
* so only issue shutdown for known local sockets)*/
|
||||
if ( '/' == host->host->ptr[0]
|
||||
|| buffer_is_equal_string(host->host, CONST_STR_LEN("127.0.0.1"))
|
||||
|| buffer_is_equal_string(host->host, CONST_STR_LEN("::1"))) {
|
||||
shutdown(hctx->fd, SHUT_WR);/* future: remove if HTTP/1.1 request */
|
||||
}
|
||||
#endif
|
||||
proxy_set_state(srv, hctx, PROXY_STATE_READ);
|
||||
} else {
|
||||
off_t wblen = hctx->wb->bytes_in - hctx->wb->bytes_out;
|
||||
|
|
|
@ -2438,7 +2438,20 @@ static handler_t scgi_write_request(server *srv, handler_ctx *hctx) {
|
|||
|
||||
if (hctx->wb->bytes_out == hctx->wb_reqlen) {
|
||||
fdevent_event_clr(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
|
||||
shutdown(hctx->fd, SHUT_WR);
|
||||
#if (defined(__APPLE__) && defined(__MACH__)) \
|
||||
|| defined(__FreeBSD__) || defined(__NetBSD__) \
|
||||
|| defined(__OpenBSD__) || defined(__DragonflyBSD__)
|
||||
/*(*BSD stack on remote might signal POLLHUP and remote
|
||||
* might treat as socket error instead of half-close)*/
|
||||
#else
|
||||
/*(remote could be different machine running affected OS,
|
||||
* so only issue shutdown for known local sockets)*/
|
||||
if ( '/' == host->host->ptr[0]
|
||||
|| buffer_is_equal_string(host->host, CONST_STR_LEN("127.0.0.1"))
|
||||
|| buffer_is_equal_string(host->host, CONST_STR_LEN("::1"))) {
|
||||
shutdown(hctx->fd, SHUT_WR);
|
||||
}
|
||||
#endif
|
||||
scgi_set_state(srv, hctx, FCGI_STATE_READ);
|
||||
} else {
|
||||
off_t wblen = hctx->wb->bytes_in - hctx->wb->bytes_out;
|
||||
|
|
Loading…
Reference in New Issue