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] timeout fixes for the proxy
Date Sat, 05 Apr 1997 04:25:23 GMT
These are similar to my changes to the main server routines.
The goal is to move the timeouts closer to the risky bits, and
remove them immediately after the risky bits rather than letting
them propagate to other parts of the server that are not expecting
a timeout.

.....Roy

Index: proxy_cache.c
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_cache.c,v
retrieving revision 1.10
diff -c -r1.10 proxy_cache.c
*** proxy_cache.c	1997/03/20 18:40:15	1.10
--- proxy_cache.c	1997/04/05 04:20:33
***************
*** 517,525 ****
  	Explain0("Local copy modified, send it");
  	r->status_line = strchr(c->resp_line, ' ') + 1;
  	r->status = c->status;
! 	soft_timeout ("send", r);
! 	if (!r->assbackwards)
  	    proxy_send_headers(r->connection->client, c->resp_line,  c->hdrs);
  	bsetopt(r->connection->client, BO_BYTECT, &zero);
  	r->sent_bodyct = 1;
  	if (!r->header_only) proxy_send_fb (cachefp, r, NULL, NULL);
--- 517,527 ----
  	Explain0("Local copy modified, send it");
  	r->status_line = strchr(c->resp_line, ' ') + 1;
  	r->status = c->status;
! 	if (!r->assbackwards) {
! 	    soft_timeout("proxy send headers", r);
  	    proxy_send_headers(r->connection->client, c->resp_line,  c->hdrs);
+ 	    kill_timeout(r);
+ 	}
  	bsetopt(r->connection->client, BO_BYTECT, &zero);
  	r->sent_bodyct = 1;
  	if (!r->header_only) proxy_send_fb (cachefp, r, NULL, NULL);
***************
*** 745,754 ****
  	    Explain0("Remote document updated, sending");
  	    r->status_line = strchr(c->resp_line, ' ') + 1;
  	    r->status = c->status;
! 	    soft_timeout ("send", r);
! 	    if (!r->assbackwards)
  		proxy_send_headers(r->connection->client, c->resp_line,
  		    c->hdrs);
  	    bsetopt(r->connection->client, BO_BYTECT, &zero);
  	    r->sent_bodyct = 1;
  	    if (!r->header_only) proxy_send_fb (c->fp, r, NULL, NULL);
--- 747,758 ----
  	    Explain0("Remote document updated, sending");
  	    r->status_line = strchr(c->resp_line, ' ') + 1;
  	    r->status = c->status;
! 	    if (!r->assbackwards) {
! 		soft_timeout("proxy send headers", r);
  		proxy_send_headers(r->connection->client, c->resp_line,
  		    c->hdrs);
+ 		kill_timeout(r);
+ 	    }
  	    bsetopt(r->connection->client, BO_BYTECT, &zero);
  	    r->sent_bodyct = 1;
  	    if (!r->header_only) proxy_send_fb (c->fp, r, NULL, NULL);
Index: proxy_ftp.c
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_ftp.c,v
retrieving revision 1.12
diff -c -r1.12 proxy_ftp.c
*** proxy_ftp.c	1997/03/20 18:40:15	1.12
--- proxy_ftp.c	1997/04/05 04:20:33
***************
*** 470,477 ****
      hard_timeout ("proxy ftp", r);
      i = ftp_getrc(f);
      Explain1("FTP: returned status %d", i);
!     if (i == -1) return proxyerror(r, "Error reading from remote server");
!     if (i != 220) return BAD_GATEWAY;
  
      Explain0("FTP: connected.");
  
--- 470,483 ----
      hard_timeout ("proxy ftp", r);
      i = ftp_getrc(f);
      Explain1("FTP: returned status %d", i);
!     if (i == -1) {
! 	kill_timeout(r);
! 	return proxyerror(r, "Error reading from remote server");
!     }
!     if (i != 220) {
! 	kill_timeout(r);
! 	return BAD_GATEWAY;
!     }
  
      Explain0("FTP: connected.");
  
***************
*** 485,493 ****
  /* states: 1 - error, 2 - success; 3 - send password, 4,5 fail */
      i = ftp_getrc(f);
      Explain1("FTP: returned status %d",i);
!     if (i == -1) return proxyerror(r, "Error sending to remote server");
!     if (i == 530) return proxyerror(r, "Not logged in");
!     else if (i != 230 && i != 331) return BAD_GATEWAY;
  	
      if (i == 331) /* send password */
      {
--- 491,508 ----
  /* states: 1 - error, 2 - success; 3 - send password, 4,5 fail */
      i = ftp_getrc(f);
      Explain1("FTP: returned status %d",i);
!     if (i == -1) {
! 	kill_timeout(r);
! 	return proxyerror(r, "Error sending to remote server");
!     }
!     if (i == 530) {
! 	kill_timeout(r);
! 	return proxyerror(r, "Not logged in");
!     }
!     if (i != 230 && i != 331) {
! 	kill_timeout(r);
! 	return BAD_GATEWAY;
!     }
  	
      if (i == 331) /* send password */
      {
***************
*** 500,509 ****
  /* possible results 202, 230, 332, 421, 500, 501, 503, 530 */
  	i = ftp_getrc(f);
          Explain1("FTP: returned status %d",i);
! 	if (i == -1) return proxyerror(r, "Error sending to remote server");
! 	if (i == 332) return proxyerror(r, "Need account for login");
! 	else if (i == 530) return proxyerror(r, "Not logged in");
! 	else if (i != 230 && i != 202) return BAD_GATEWAY;
      }  
  
  /* set the directory */
--- 515,536 ----
  /* possible results 202, 230, 332, 421, 500, 501, 503, 530 */
  	i = ftp_getrc(f);
          Explain1("FTP: returned status %d",i);
! 	if (i == -1) {
! 	    kill_timeout(r);
! 	    return proxyerror(r, "Error sending to remote server");
! 	}
! 	if (i == 332) {
! 	    kill_timeout(r);
! 	    return proxyerror(r, "Need account for login");
! 	}
! 	if (i == 530) {
! 	    kill_timeout(r);
! 	    return proxyerror(r, "Not logged in");
! 	}
! 	if (i != 230 && i != 202) {
! 	    kill_timeout(r);
! 	    return BAD_GATEWAY;
! 	}
      }  
  
  /* set the directory */
***************
*** 526,534 ****
  /* 1,3 error, 2 success, 4,5 failure */
  	i = ftp_getrc(f);
          Explain1("FTP: returned status %d",i);
! 	if (i == -1) return proxyerror(r, "Error sending to remote server");
! 	else if (i == 550) return NOT_FOUND;
! 	else if (i != 250) return BAD_GATEWAY;
  
  	path = p + 1;
      }
--- 553,570 ----
  /* 1,3 error, 2 success, 4,5 failure */
  	i = ftp_getrc(f);
          Explain1("FTP: returned status %d",i);
! 	if (i == -1) {
! 	    kill_timeout(r);
! 	    return proxyerror(r, "Error sending to remote server");
! 	}
! 	if (i == 550) {
! 	    kill_timeout(r);
! 	    return NOT_FOUND;
! 	}
! 	if (i != 250) {
! 	    kill_timeout(r);
! 	    return BAD_GATEWAY;
! 	}
  
  	path = p + 1;
      }
***************
*** 554,563 ****
  /* responses: 200, 421, 500, 501, 504, 530 */
  	i = ftp_getrc(f);
          Explain1("FTP: returned status %d",i);
! 	if (i == -1) return proxyerror(r, "Error sending to remote server");
! 	else if (i != 200 && i != 504) return BAD_GATEWAY;
  /* Allow not implemented */
! 	else if (i == 504) parms[0] = '\0';
      }
  
  /* try to set up PASV data connection first */
--- 590,606 ----
  /* responses: 200, 421, 500, 501, 504, 530 */
  	i = ftp_getrc(f);
          Explain1("FTP: returned status %d",i);
! 	if (i == -1) {
! 	    kill_timeout(r);
! 	    return proxyerror(r, "Error sending to remote server");
! 	}
! 	if (i != 200 && i != 504) {
! 	    kill_timeout(r);
! 	    return BAD_GATEWAY;
! 	}
  /* Allow not implemented */
! 	if (i == 504)
! 	    parms[0] = '\0';
      }
  
  /* try to set up PASV data connection first */
***************
*** 567,572 ****
--- 610,616 ----
  	proxy_log_uerror("socket", NULL, "proxy: error creating PASV socket",
  	    r->server);
  	pclosef(pool, sock);
+ 	kill_timeout(r);
          return SERVER_ERROR;
      }
      note_cleanups_for_fd(pool, dsock);
***************
*** 583,588 ****
--- 627,633 ----
  	    r->server);
  	pclosef(pool, dsock);
  	pclosef(pool, sock);
+ 	kill_timeout(r);
  	return SERVER_ERROR;
      } else
      {
***************
*** 613,622 ****
              data_addr.sin_port = htons(pport);
  	    i = proxy_doconnect(dsock, &data_addr, r);
  
! 	    if (i == -1)
  		return proxyerror(r, "Could not connect to remote machine");
! 	    else
! 	    {
  	        data = bcreate(pool, B_RDWR); 
  	        bpushfd(data, dsock, dsock);
  	        pasvmode = 1;
--- 658,668 ----
              data_addr.sin_port = htons(pport);
  	    i = proxy_doconnect(dsock, &data_addr, r);
  
! 	    if (i == -1) {
! 		kill_timeout(r);
  		return proxyerror(r, "Could not connect to remote machine");
! 	    }
! 	    else {
  	        data = bcreate(pool, B_RDWR); 
  	        bpushfd(data, dsock, dsock);
  	        pasvmode = 1;
***************
*** 633,638 ****
--- 679,685 ----
  	    proxy_log_uerror("getsockname", NULL,
  	        "proxy: error getting socket address", r->server);
  	    pclosef(pool, sock);
+ 	    kill_timeout(r);
  	    return SERVER_ERROR;
          }
  
***************
*** 642,647 ****
--- 689,695 ----
  	    proxy_log_uerror("socket", NULL, "proxy: error creating socket",
  	        r->server);
  	    pclosef(pool, sock);
+ 	    kill_timeout(r);
  	    return SERVER_ERROR;
          }
          note_cleanups_for_fd(pool, dsock);
***************
*** 653,658 ****
--- 701,707 ----
  	        "proxy: error setting reuseaddr option", r->server);
  	    pclosef(pool, dsock);
  	    pclosef(pool, sock);
+ 	    kill_timeout(r);
  	    return SERVER_ERROR;
          }
  
***************
*** 700,708 ****
                  Explain1("FTP: CWD %s",path);
                  i = ftp_getrc(f);
                  Explain1("FTP: returned status %d", i);
!                 if (i == -1) return proxyerror(r, "Error sending to remote server");
!                 else if (i == 550) return NOT_FOUND;
!                 else if (i != 250) return BAD_GATEWAY;
                  path=""; len=0;
              }
          }
--- 749,766 ----
                  Explain1("FTP: CWD %s",path);
                  i = ftp_getrc(f);
                  Explain1("FTP: returned status %d", i);
!                 if (i == -1) {
! 		    kill_timeout(r);
! 		    return proxyerror(r, "Error sending to remote server");
!                 }
!                 if (i == 550) {
! 		    kill_timeout(r);
! 		    return NOT_FOUND;
!                 }
!                 if (i != 250) {
! 		    kill_timeout(r);
! 		    return BAD_GATEWAY;
!                 }
                  path=""; len=0;
              }
          }
***************
*** 726,732 ****
     NLST: 125, 150, 226, 250, 421, 425, 426, 450, 451, 500, 501, 502, 530 */
      rc = ftp_getrc(f);
      Explain1("FTP: returned status %d",rc);
!     if (rc == -1) return proxyerror(r, "Error sending to remote server");
      if (rc == 550)
      {
         Explain0("FTP: RETR failed, trying LIST instead");
--- 784,793 ----
     NLST: 125, 150, 226, 250, 421, 425, 426, 450, 451, 500, 501, 502, 530 */
      rc = ftp_getrc(f);
      Explain1("FTP: returned status %d",rc);
!     if (rc == -1) {
! 	kill_timeout(r);
! 	return proxyerror(r, "Error sending to remote server");
!     }
      if (rc == 550)
      {
         Explain0("FTP: RETR failed, trying LIST instead");
***************
*** 738,746 ****
         Explain1("FTP: CWD %s", path);
         rc = ftp_getrc(f);
         Explain1("FTP: returned status %d", rc);
!        if (rc == -1) return proxyerror(r, "Error sending to remote server");
!        if (rc == 550) return NOT_FOUND;
!        if (rc != 250) return BAD_GATEWAY;
  
         bputs("LIST -lag\015\012", f);
         bflush(f);
--- 799,816 ----
         Explain1("FTP: CWD %s", path);
         rc = ftp_getrc(f);
         Explain1("FTP: returned status %d", rc);
!        if (rc == -1) {
!           kill_timeout(r);
!           return proxyerror(r, "Error sending to remote server");
!        }
!        if (rc == 550) {
!           kill_timeout(r);
!           return NOT_FOUND;
!        }
!        if (rc != 250) {
!           kill_timeout(r);
!           return BAD_GATEWAY;
!        }
  
         bputs("LIST -lag\015\012", f);
         bflush(f);
***************
*** 749,756 ****
         Explain1("FTP: returned status %d", rc);
         if (rc == -1) return proxyerror(r, "Error sending to remote server");
      }   
-     if (rc != 125 && rc != 150 && rc != 226 && rc != 250) return
BAD_GATEWAY;
      kill_timeout(r);
  
      r->status = 200;
      r->status_line = "200 OK";
--- 819,826 ----
         Explain1("FTP: returned status %d", rc);
         if (rc == -1) return proxyerror(r, "Error sending to remote server");
      }   
      kill_timeout(r);
+     if (rc != 125 && rc != 150 && rc != 226 && rc != 250) return
BAD_GATEWAY;
  
      r->status = 200;
      r->status_line = "200 OK";
***************
*** 802,807 ****
--- 872,878 ----
  	        "proxy: failed to accept data connection", r->server);
  	    pclosef(pool, dsock);
  	    pclosef(pool, sock);
+ 	    kill_timeout(r);
  	    proxy_cache_error(c);
  	    return BAD_GATEWAY;
          }
Index: proxy_http.c
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_http.c,v
retrieving revision 1.15
diff -c -r1.15 proxy_http.c
*** proxy_http.c	1997/03/20 18:40:15	1.15
--- proxy_http.c	1997/04/05 04:20:33
***************
*** 272,277 ****
--- 272,278 ----
      if (len == -1 || len == 0)
      {
  	pclosef(pool, sock);
+ 	kill_timeout(r);
  	return proxyerror(r, "Error reading from remote server");
      }
  
***************
*** 282,287 ****
--- 283,289 ----
  	if (buffer[5] != '1' || buffer[len-1] != '\n')
  	{
  	    pclosef(pool, sock);
+ 	    kill_timeout(r);
  	    return BAD_GATEWAY;
  	}
  	buffer[--len] = '\0';
***************
*** 385,390 ****
--- 387,393 ----
  	if (cache != NULL)
  	    if (bwrite(f, buffer, len) != len) cache = proxy_cache_error(c);
      }
+     kill_timeout(r);
  
  /* send body */
  /* if header only, then cache will be NULL */
Index: proxy_util.c
===================================================================
RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_util.c,v
retrieving revision 1.8
diff -c -r1.8 proxy_util.c
*** proxy_util.c	1997/03/20 18:40:16	1.8
--- proxy_util.c	1997/04/05 04:20:33
***************
*** 303,309 ****
  }
  
  /*
!  * Reads headers from a connection and returns an array of headers.
   * Returns NULL on file error
   */
  array_header *
--- 303,309 ----
  }
  
  /*
!  * Reads headers from a buffer and returns an array of headers.
   * Returns NULL on file error
   */
  array_header *
***************
*** 392,397 ****
--- 392,399 ----
      conn_rec *con = r->connection;
      
      total_bytes_sent = 0;
+     soft_timeout("proxy send body", r);
+ 
      while (!con->aborted) {
  	n = bread(f, buf, IOBUFSIZE);
  	if (n == -1) /* input error */
***************
*** 406,412 ****
  	if (f2 != NULL)
  	    if (bwrite(f2, buf, n) != n) f2 = proxy_cache_error(c);
  	
!         while(n && !r->connection->aborted) {
              w = bwrite(con->client, &buf[o], n);
              if (w <= 0) {
                  if (f2 != NULL) {
--- 408,414 ----
  	if (f2 != NULL)
  	    if (bwrite(f2, buf, n) != n) f2 = proxy_cache_error(c);
  	
!         while(n && !con->aborted) {
              w = bwrite(con->client, &buf[o], n);
              if (w <= 0) {
                  if (f2 != NULL) {
***************
*** 416,428 ****
                  }
                  break;
              }
! 	    reset_timeout(r); /* reset timeout after successfule write */
              n-=w;
              o+=w;
          }
      }
!     bflush(con->client);
      
      return total_bytes_sent;
  }
  
--- 418,432 ----
                  }
                  break;
              }
! 	    reset_timeout(r); /* reset timeout after successful write */
              n-=w;
              o+=w;
          }
      }
!     if (!con->aborted)
!         bflush(con->client);
      
+     kill_timeout(r);
      return total_bytes_sent;
  }
  
***************
*** 486,491 ****
--- 490,496 ----
  
  /*
   * Sends response line and headers
+  * A timeout should be set before calling this routine.
   */
  void
  proxy_send_headers(BUFF *fp, const char *respline, array_header *hdrs_arr)
***************
*** 669,679 ****
--- 674,688 ----
      r->content_type = "text/html";
  
      send_http_header(r);
+     soft_timeout("proxy error", r);
+ 
      rvputs(r, "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\015\012\
  <html><head><title>Proxy Error</title><head>\015\012<body><h1>Proxy
Error\
  </h1>\015\012The proxy server could not handle this request.\
  \015\012<p>\015\012Reason: <b>", message, "</b>\015\012</body><html>\015\012",
  	   NULL);
+ 
+     kill_timeout(r);
      return OK;
  }
  
***************
*** 711,717 ****
  {
      int i;
  
!     hard_timeout ("proxy connect", r);
      do	i = connect(sock, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
      while (i == -1 && errno == EINTR);
      if (i == -1) proxy_log_uerror("connect", NULL, NULL, r->server);
--- 720,726 ----
  {
      int i;
  
!     hard_timeout("proxy connect", r);
      do	i = connect(sock, (struct sockaddr *)addr, sizeof(struct sockaddr_in));
      while (i == -1 && errno == EINTR);
      if (i == -1) proxy_log_uerror("connect", NULL, NULL, r->server);

Mime
View raw message