Browse Source

Fix HUP detection in close-state if event-backend doesn't support FDEVENT_HUP (like select or poll on FreeBSD)

git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@2712 152afb58-edef-0310-8abb-c4023f1b3aa9
svn/tags/lighttpd-1.4.26
Stefan Bühler 12 years ago
parent
commit
914e499723
  1. 1
      NEWS
  2. 50
      src/connections.c

1
NEWS

@ -13,6 +13,7 @@ NEWS
* Fix fd leaks in mod_cgi (fds not closed on pipe/fork failures, found by Rodrigo, fixes #2158, #2159)
* Fix segfault with broken rewrite/redirect patterns (fixes #2140, found by crypt)
* Append to previous buffer in con read (fixes #2147, found by liming, CVE-2010-0295)
* Fix HUP detection in close-state if event-backend doesn't support FDEVENT_HUP (like select or poll on FreeBSD)
- 1.4.25 - 2009-11-21
* mod_magnet: fix pairs() for normal tables and strings (fixes #1307)

50
src/connections.c

@ -1245,28 +1245,12 @@ static handler_t connection_handle_fdevent(void *s, void *context, int revents)
if (con->state == CON_STATE_CLOSE) {
/* flush the read buffers */
int b;
int len;
char buf[1024];
if (ioctl(con->fd, FIONREAD, &b)) {
log_error_write(srv, __FILE__, __LINE__, "ss",
"ioctl() failed", strerror(errno));
}
if (b > 0) {
char buf[1024];
#if 0
log_error_write(srv, __FILE__, __LINE__, "sdd",
"CLOSE-read()", con->fd, b);
#endif
/* */
read(con->fd, buf, sizeof(buf));
} else {
/* nothing to read - yet. But that doesn't
* mean something won't show up in our buffers
* sometime soon, so we can't quite until
* poll() gives us the HUP notification.
*/
len = read(con->fd, buf, sizeof(buf));
if (len == 0 || (len < 0 && errno != EAGAIN && errno != EINTR) ) {
con->close_timeout_ts = srv->cur_ts - (HTTP_LINGER_TIMEOUT+1);
}
}
@ -1388,7 +1372,6 @@ int connection_state_machine(server *srv, connection *con) {
while (done == 0) {
size_t ostate = con->state;
int b;
switch (con->state) {
case CON_STATE_REQUEST_START: /* transient */
@ -1621,25 +1604,14 @@ int connection_state_machine(server *srv, connection *con) {
* still have unread data, and closing before reading
* it will make the client not see all our output.
*/
if (ioctl(con->fd, FIONREAD, &b)) {
log_error_write(srv, __FILE__, __LINE__, "ss",
"ioctl() failed", strerror(errno));
}
if (b > 0) {
{
int len;
char buf[1024];
#if 0
log_error_write(srv, __FILE__, __LINE__, "sdd",
"CLOSE-read()", con->fd, b);
#endif
/* */
read(con->fd, buf, sizeof(buf));
} else {
/* nothing to read - yet. But that doesn't
* mean something won't show up in our buffers
* sometime soon, so we can't quite until
* poll() gives us the HUP notification.
*/
len = read(con->fd, buf, sizeof(buf));
if (len == 0 || (len < 0 && errno != EAGAIN && errno != EINTR) ) {
con->close_timeout_ts = srv->cur_ts - (HTTP_LINGER_TIMEOUT+1);
}
}
if (srv->cur_ts - con->close_timeout_ts > HTTP_LINGER_TIMEOUT) {

Loading…
Cancel
Save