httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Roy T. Fielding" <field...@kiwi.ICS.UCI.EDU>
Subject [PATCH] Fix more timeout sillyness
Date Tue, 01 Apr 1997 11:58:17 GMT
More bugs found while trying to fix something else.  Using a single handler
for both timeouts and SIGPIPEs is a really bad idea, but I didn't change
that part.  Calling shutdown is unreliable, so we avoid it when possible.
Using soft_timeout requires that the sender check for an aborted connection
rather than continuing after an EINTR, which is almost never the case.
Timeouts that used to be initiated before send_http_header (and never
killed) are now initiated only within or around the routines that actually
do the sending, and not allowed to propagate above the caller.

I haven't checked the proxy for the same conditions (no more time).
I have a hunch that the reason the proxy gets a lot of lingering_close
errors is because somewhere it is faking socket i/o using the
file cache, which would result in an error when lingering_close
attempts to shutdown(lsd,1) and lsd is not a socket.  However, I haven't
found it yet, and will be in all-day meetings for the rest of the
week starting in 5 hours (yikes).

.....Roy

Index: http_main.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_main.c,v
retrieving revision 1.133
diff -c -r1.133 http_main.c
*** http_main.c	1997/03/22 23:51:02	1.133
--- http_main.c	1997/04/01 11:37:21
***************
*** 420,427 ****
  static int alarms_blocked = 0;
  static int alarm_pending = 0;
  
- void abort_connection (conn_rec *);
- 
  void timeout(sig)			/* Also called on SIGPIPE */
  int sig;
  {
--- 420,425 ----
***************
*** 473,478 ****
--- 471,478 ----
  	if (!current_conn->keptalive) 
              log_transaction(log_req);
  
+         if (sig == SIGPIPE)
+             bsetflag(timeout_req->connection->client, B_EOUT, 1);
  	bclose(timeout_req->connection->client);
      
  	if (!standalone) exit(0);
***************
*** 482,489 ****
  	siglongjmp(jmpbuffer,1);
  #endif
      }
!     else {
! 	abort_connection (current_conn);
      }
  }
  
--- 482,493 ----
  	siglongjmp(jmpbuffer,1);
  #endif
      }
!     else {   /* abort the connection */
!         if (sig == SIGPIPE)
!             bsetflag(current_conn->client, B_EOUT, 1);
!         else
!             bflush(current_conn->client);
!         current_conn->aborted = 1;
      }
  }
  
***************
*** 1233,1239 ****
  #else
      kill(-pgrp,SIGKILL);
  #endif
-     shutdown(sd,2);
      close(sd);
      exit(1);
  }
--- 1237,1242 ----
***************
*** 1521,1534 ****
      }
  }
  
- void abort_connection (conn_rec *c)
- {
-     /* Make sure further I/O DOES NOT HAPPEN */
-     shutdown (c->client->fd, 2);
-     signal (SIGPIPE, SIG_IGN);	/* Ignore further complaints */
-     c->aborted = 1;
- }
- 
  conn_rec *new_connection (pool *p, server_rec *server, BUFF *inout,
  			  const struct sockaddr_in *remaddr,
  			  const struct sockaddr_in *saddr,
--- 1524,1529 ----
***************
*** 1809,1818 ****
              lingering_close(r);
          }
          else {
-             /* if the connection was aborted by a soft_timeout, it has
-              * already been shutdown() so we don't need to go through
-              * lingering_close
-              */
              bsetflag(conn_io, B_EOUT, 1);
              bclose(conn_io);
          }
--- 1804,1809 ----
Index: http_protocol.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_protocol.c,v
retrieving revision 1.110
diff -c -r1.110 http_protocol.c
*** http_protocol.c	1997/03/20 23:30:50	1.110
--- http_protocol.c	1997/04/01 11:37:21
***************
*** 1079,1085 ****
      /* Get the original request */
      while (r->prev) r = r->prev;
  
!     soft_timeout ("send TRACE", r);
  
      r->content_type = "message/http";
      send_http_header(r);
--- 1079,1085 ----
      /* Get the original request */
      while (r->prev) r = r->prev;
  
!     hard_timeout("send TRACE", r);
  
      r->content_type = "message/http";
      send_http_header(r);
***************
*** 1102,1108 ****
  
      if (r->assbackwards) return DECLINED;
  
!     soft_timeout("send OPTIONS", r);
  
      basic_http_header(r);
  
--- 1102,1108 ----
  
      if (r->assbackwards) return DECLINED;
  
!     hard_timeout("send OPTIONS", r);
  
      basic_http_header(r);
  
***************
*** 1156,1162 ****
       */
      r->headers_out=overlay_tables(r->pool, r->err_headers_out, r->headers_out);
      
!     soft_timeout("send headers", r);
  
      basic_http_header(r);
  
--- 1156,1162 ----
       */
      r->headers_out=overlay_tables(r->pool, r->err_headers_out, r->headers_out);
      
!     hard_timeout("send headers", r);
  
      basic_http_header(r);
  
***************
*** 1221,1227 ****
      /* Turn off chunked encoding */
  
      if (r->chunked) {
!         soft_timeout("send ending chunk", r);
          bsetflag(r->connection->client, B_CHUNK, 0);
  	bputs("0\015\012", r->connection->client);
  	/* If we had footer "headers", we'd send them now */
--- 1221,1227 ----
      /* Turn off chunked encoding */
  
      if (r->chunked) {
!         hard_timeout("send ending chunk", r);
          bsetflag(r->connection->client, B_CHUNK, 0);
  	bputs("0\015\012", r->connection->client);
  	/* If we had footer "headers", we'd send them now */
***************
*** 1485,1497 ****
  long send_fd_length(FILE *f, request_rec *r, long length)
  {
      char buf[IOBUFSIZE];
!     long total_bytes_sent;
      register int n, w, o, len;
      conn_rec *c = r->connection;
      
      if (length == 0) return 0;
  
!     total_bytes_sent = 0;
      while (!r->connection->aborted) {
  	if ((length > 0) && (total_bytes_sent + IOBUFSIZE) > length)
  	    len = length - total_bytes_sent;
--- 1485,1498 ----
  long send_fd_length(FILE *f, request_rec *r, long length)
  {
      char buf[IOBUFSIZE];
!     long total_bytes_sent = 0;
      register int n, w, o, len;
      conn_rec *c = r->connection;
      
      if (length == 0) return 0;
  
!     soft_timeout("send file", r);
! 
      while (!r->connection->aborted) {
  	if ((length > 0) && (total_bytes_sent + IOBUFSIZE) > length)
  	    len = length - total_bytes_sent;
***************
*** 1517,1522 ****
--- 1518,1524 ----
          }
      }
      
+     kill_timeout(r);
      SET_BYTES_SENT(r);
      return total_bytes_sent;
  }
***************
*** 1609,1615 ****
  	if (status == HTTP_NOT_MODIFIED) {
  	    r->headers_out = overlay_tables(r->pool, r->err_headers_out,
  	                                             r->headers_out);
! 	    soft_timeout("send 304", r);
  
  	    basic_http_header(r);
  	    set_keepalive(r);
--- 1611,1617 ----
  	if (status == HTTP_NOT_MODIFIED) {
  	    r->headers_out = overlay_tables(r->pool, r->err_headers_out,
  	                                             r->headers_out);
! 	    hard_timeout("send 304", r);
  
  	    basic_http_header(r);
  	    set_keepalive(r);
***************
*** 1647,1653 ****
  	}
      }
      
!     soft_timeout("send error body", r);
  
      if ((custom_response = response_code_string (r, idx))) {
          /*
--- 1649,1655 ----
  	}
      }
      
!     hard_timeout("send error body", r);
  
      if ((custom_response = response_code_string (r, idx))) {
          /*
Index: http_core.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_core.c,v
retrieving revision 1.75
diff -c -r1.75 http_core.c
*** http_core.c	1997/04/01 05:00:19	1.75
--- http_core.c	1997/04/01 11:37:22
***************
*** 1333,1340 ****
        table_set (r->headers_out, "Content-MD5", md5digest(r->pool, f));
      }
  
-     soft_timeout ("send", r);
- 
      rangestatus = set_byterange(r);
      send_http_header (r);
      
--- 1333,1338 ----
Index: mod_asis.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_asis.c,v
retrieving revision 1.12
diff -c -r1.12 mod_asis.c
*** mod_asis.c	1997/03/07 14:15:37	1.12
--- mod_asis.c	1997/04/01 11:37:22
***************
*** 97,103 ****
  	return OK;
      }
      
-     soft_timeout ("send", r);
      send_http_header (r);
      if (!r->header_only) send_fd (f, r);
  
--- 97,102 ----
Index: mod_cgi.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_cgi.c,v
retrieving revision 1.36
diff -c -r1.36 mod_cgi.c
*** mod_cgi.c	1997/04/01 06:17:52	1.36
--- mod_cgi.c	1997/04/01 11:37:22
***************
*** 518,530 ****
  	    return REDIRECT;
  	}
  	
- 	hard_timeout ("send script output", r);
  	send_http_header(r);
!         if(!r->header_only) send_fd (script_in, r);
  	/* Soak up stderr */
  	while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_err) != NULL)
  	  continue;
! 	kill_timeout (r);
  	pfclose (r->main ? r->main->pool : r->pool, script_in);
  	pfclose (r->main ? r->main->pool : r->pool, script_err);
      }
--- 518,533 ----
  	    return REDIRECT;
  	}
  	
  	send_http_header(r);
! 	if (!r->header_only)
! 	    send_fd(script_in, r);
! 
  	/* Soak up stderr */
+ 	soft_timeout("soaking script stderr", r);
  	while (fgets(argsbuffer, HUGE_STRING_LEN-1, script_err) != NULL)
  	  continue;
! 	kill_timeout(r);
! 
  	pfclose (r->main ? r->main->pool : r->pool, script_in);
  	pfclose (r->main ? r->main->pool : r->pool, script_err);
      }
Index: mod_dir.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_dir.c,v
retrieving revision 1.23
diff -c -r1.23 mod_dir.c
*** mod_dir.c	1997/03/07 14:15:39	1.23
--- mod_dir.c	1997/04/01 11:37:22
***************
*** 700,712 ****
  
      r->content_type = "text/html";
      
-     soft_timeout ("send directory", r);
      send_http_header(r);
  
      if (r->header_only) {
  	closedir (d);
  	return 0;
      }
  
      /* Spew HTML preamble */
      
--- 700,712 ----
  
      r->content_type = "text/html";
      
      send_http_header(r);
  
      if (r->header_only) {
  	closedir (d);
  	return 0;
      }
+     hard_timeout("send directory", r);
  
      /* Spew HTML preamble */
      
***************
*** 766,771 ****
--- 766,773 ----
      }
  
      rputs ("</BODY></HTML>\n", r);
+ 
+     kill_timeout(r);
      return 0;
  }
  
Index: mod_imap.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_imap.c,v
retrieving revision 1.19
diff -c -r1.19 mod_imap.c
*** mod_imap.c	1997/03/07 14:15:41	1.19
--- mod_imap.c	1997/04/01 11:37:22
***************
*** 500,509 ****
      return SERVER_ERROR;  /* they actually requested an error! */
    }
    if ( ! strcasecmp(redirect, "nocontent") ) {
!     r->status_line = pstrdup(r->pool, "204 No Content");
!     soft_timeout ("send no content", r);
!     send_http_header(r);
!     return OK;            /* tell the client to keep the page it has */
    }
    if (redirect && *redirect ) { 
      table_set(r->headers_out, "Location", redirect);
--- 500,506 ----
      return SERVER_ERROR;  /* they actually requested an error! */
    }
    if ( ! strcasecmp(redirect, "nocontent") ) {
!     return HTTP_NO_CONTENT; /* tell the client to keep the page it has */
    }
    if (redirect && *redirect ) { 
      table_set(r->headers_out, "Location", redirect);
***************
*** 514,541 ****
  
  void menu_header(request_rec *r, char *menu)
  {
!   if (! strcasecmp(menu, "formatted")) {
!     r->content_type = "text/html";
!     soft_timeout ("send menu", r);
!     send_http_header(r);
!     rvputs(r, "<html>\n<head><title>Menu for ", r->uri,
! 	   "</title></head>\n\n<body>\n", NULL);
      rvputs(r, "<h1>Menu for ", r->uri, "</h1>\n<hr>\n\n", NULL);
    } 
!   if (! strcasecmp(menu, "semiformatted")) {
!     r->content_type = "text/html";
!     soft_timeout ("send menu", r);
!     send_http_header(r);
!     rvputs(r, "<html>\n<head><title>Menu for ", r->uri,
! 	   "</title></head>\n\n<body>\n", NULL);
!   } 
!   if (! strcasecmp(menu, "unformatted")) {
!     r->content_type = "text/html";
!     soft_timeout ("send menu", r);
!     send_http_header(r);
!     rvputs(r, "<html>\n<head><title>Menu for ", r->uri,
! 	   "</title></head>\n\n<body>\n", NULL);
!   }
    return;
  }
  
--- 511,527 ----
  
  void menu_header(request_rec *r, char *menu)
  {
!   r->content_type = "text/html";
!   send_http_header(r);
!   hard_timeout("send menu", r);   /* killed in menu_footer */
! 
!   rvputs(r, "<html><head>\n<title>Menu for ", r->uri,
! 	    "</title>\n</head><body>\n", NULL);
! 
!   if (!strcasecmp(menu, "formatted")) {
      rvputs(r, "<h1>Menu for ", r->uri, "</h1>\n<hr>\n\n", NULL);
    } 
! 
    return;
  }
  
***************
*** 608,613 ****
--- 594,600 ----
  void menu_footer(request_rec *r)
  {
    rputs("\n\n</body>\n</html>\n", r);  /* finish the menu */
+   kill_timeout(r);
  }
  
  int imap_handler(request_rec *r)
Index: mod_include.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_include.c,v
retrieving revision 1.27
diff -c -r1.27 mod_include.c
*** mod_include.c	1997/03/07 14:15:41	1.27
--- mod_include.c	1997/04/01 11:37:23
***************
*** 1752,1762 ****
  	return FORBIDDEN;
      }
      
-     hard_timeout ("send", r);
      send_http_header(r);
  
      if (r->header_only) {
-         kill_timeout (r);
  	pfclose (r->pool, f);
  	return OK;
      }
--- 1752,1760 ----
***************
*** 1775,1781 ****
  	add_cgi_vars(r);
  	add_include_vars (r, DEFAULT_TIME_FORMAT);
      }
!     
      send_parsed_content (f, r);
      
      kill_timeout (r);
--- 1773,1780 ----
  	add_cgi_vars(r);
  	add_include_vars (r, DEFAULT_TIME_FORMAT);
      }
!     hard_timeout("send SSI", r);
! 
      send_parsed_content (f, r);
      
      kill_timeout (r);
Index: mod_info.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_info.c,v
retrieving revision 1.14
diff -c -r1.14 mod_info.c
*** mod_info.c	1997/03/07 14:15:41	1.14
--- mod_info.c	1997/04/01 11:37:23
***************
*** 277,289 ****
  	extern char server_root[MAX_STRING_LEN];
  	extern char server_confname[MAX_STRING_LEN];
  
- 	/* Init timeout */
- 	soft_timeout ("send server info", r);
  	r->content_type = "text/html";		
  	send_http_header(r);
  	if(r->header_only) {
  		return 0;
      }
  	
  	rputs("<html><head><title>Server Information</title></head>\n",r);
  	rputs("<body><h1 align=center>Apache Server Information</h1>\n",r);
--- 277,288 ----
  	extern char server_root[MAX_STRING_LEN];
  	extern char server_confname[MAX_STRING_LEN];
  
  	r->content_type = "text/html";		
  	send_http_header(r);
  	if(r->header_only) {
  		return 0;
      }
+ 	hard_timeout("send server info", r);
  	
  	rputs("<html><head><title>Server Information</title></head>\n",r);
  	rputs("<body><h1 align=center>Apache Server Information</h1>\n",r);
***************
*** 418,423 ****
--- 417,423 ----
  	}	
  	rputs("</dl></body></html>\n",r);
  	/* Done, turn off timeout, close file and return */
+ 	kill_timeout(r);
  	return 0;
  }
  
Index: mod_status.c
===================================================================
RCS file: /export/home/cvs/apache/src/mod_status.c,v
retrieving revision 1.44
diff -c -r1.44 mod_status.c
*** mod_status.c	1997/03/07 14:15:43	1.44
--- mod_status.c	1997/04/01 11:37:23
***************
*** 264,270 ****
          }
      }
  
-     soft_timeout ("send status info", r);
      send_http_header(r);
  
      if (r->header_only) 
--- 264,269 ----
***************
*** 304,309 ****
--- 303,310 ----
  
      up_time=nowtime-restart_time;
  
+     hard_timeout("send status info", r);
+ 
      if (!short_report)
      {
          rputs("<HTML><HEAD>\n<TITLE>Apache Status</TITLE>\n</HEAD><BODY>\n",r);
***************
*** 586,591 ****
--- 587,594 ----
  
      if (!short_report)
          rputs("</BODY></HTML>\n",r);
+ 
+     kill_timeout(r);
      return 0;
  }
  

Mime
View raw message