"Roy T. Fielding" <[EMAIL PROTECTED]> writes: > > I'm sure there's a great reason for setting B_EOUT flag here, but it > > sure does suck if you have data waiting to be sent to the client since > > setting B_EOUT convinces ap_bclose() not to write any more data. > > It is only set when the connection is aborted or the fd is gone, > both indicating that we can't write any more data. I think you > need to figure out why the conditional above it is false and > then fix the root of the problem. My guess is that > > r->connection->aborted > > is being set incorrectly somewhere.
r->connection->aborted isn't being set. We skip the lingering close path and because ap_read_request() returns NULL (i.e., r is NULL when we see whether to do lingering close). But current_conn is still valid and current_conn->aborted isn't set. The client is doing this: write lastfd "GET /silly?send_chunks HTTP/1.1\r\nHost: 127.0.0.1\r\n\r\n" shutdown lastfd 1 read the response Here is how Apache interacts with this client: read(3, "GET /silly?send_chunks HTTP/1.1\r"..., 4096) = 52 write(3, "HTTP/1.1 200 OK\r\nDate: Sat, 19 O"..., 152) = 152 writev(3, [{"1400f\r\n", 7}, {"IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII"..., 81935}, {"\r\n", 2}], 3) = 81944 write(3, "1 \r\nI\r\n", 8) = 8 select(4, [3], NULL, NULL, {0, 0}) = 1 (in [3], left {0, 0}) select(4, [3], NULL, NULL, {0, 0}) = 1 (in [3], left {0, 0}) read(3, "", 4096) = 0 close(3) Here is another patch which respects the aborted flag and makes a semi-gratuitous cleanup so that there is only one set of code for this. Index: src/main/http_main.c =================================================================== RCS file: /home/cvs/apache-1.3/src/main/http_main.c,v retrieving revision 1.594 diff -u -r1.594 http_main.c --- src/main/http_main.c 1 Oct 2002 14:24:23 -0000 1.594 +++ src/main/http_main.c 19 Oct 2002 11:32:12 -0000 @@ -4178,6 +4178,34 @@ ap_server_config_defines = ap_make_array(pcommands, 1, sizeof(char *)); } +/* + * Close the connection, being careful to send out whatever is still + * in our buffers. If possible, try to avoid a hard close until the + * client has ACKed our FIN and/or has stopped sending us data. + */ +static void close_connection(request_rec *r, BUFF *conn_io, int aborted) +{ +#ifdef NO_LINGCLOSE + ap_bclose(conn_io); /* just close it */ +#else + if (r && r->connection + && !r->connection->aborted + && r->connection->client + && (r->connection->client->fd >= 0)) { + lingering_close(r); + } + else { + if (aborted) { + /* we've already hit an error doing I/O with client, so + * don't try to write any buffered data during ap_bclose() + */ + ap_bsetflag(conn_io, B_EOUT, 1); + } + ap_bclose(conn_io); + } +#endif /* NO_LINGCLOSE */ +} + #ifndef MULTITHREAD /***************************************************************** * Child process main loop. @@ -4646,28 +4674,7 @@ usr1_just_die = 1; signal(SIGUSR1, usr1_handler); } - - /* - * Close the connection, being careful to send out whatever is still - * in our buffers. If possible, try to avoid a hard close until the - * client has ACKed our FIN and/or has stopped sending us data. - */ - -#ifdef NO_LINGCLOSE - ap_bclose(conn_io); /* just close it */ -#else - if (r && r->connection - && !r->connection->aborted - && r->connection->client - && (r->connection->client->fd >= 0)) { - - lingering_close(r); - } - else { - ap_bsetflag(conn_io, B_EOUT, 1); - ap_bclose(conn_io); - } -#endif + close_connection(r, conn_io, current_conn && current_conn->aborted); } } @@ -5954,28 +5961,8 @@ ap_sync_scoreboard_image(); } - /* - * Close the connection, being careful to send out whatever is still - * in our buffers. If possible, try to avoid a hard close until the - * client has ACKed our FIN and/or has stopped sending us data. - */ ap_kill_cleanups_for_socket(ptrans, csd); - -#ifdef NO_LINGCLOSE - ap_bclose(conn_io); /* just close it */ -#else - if (r && r->connection - && !r->connection->aborted - && r->connection->client - && (r->connection->client->fd >= 0)) { - - lingering_close(r); - } - else { - ap_bsetflag(conn_io, B_EOUT, 1); - ap_bclose(conn_io); - } -#endif + close_connection(r, conn_io, current_conn && current_conn->aborted); } ap_destroy_pool(ptrans); (void) ap_update_child_status(child_num, SERVER_DEAD, NULL); Thanks for your response! -- Jeff Trawick | [EMAIL PROTECTED] Born in Roswell... married an alien...