fielding    97/04/05 23:43:51

  Modified:    src       CHANGES http_main.c http_protocol.c http_core.c
                        mod_asis.c  mod_cgi.c mod_dir.c mod_imap.c
                        mod_include.c mod_info.c  mod_status.c
               src/modules/proxy  proxy_cache.c proxy_ftp.c proxy_http.c
                        proxy_util.c
  Log:
  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 was 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.
  
  Reviewed by: Chuck Murcko, Jim Jagielski
  
  Revision  Changes    Path
  1.221     +6 -1      apache/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apache/src/CHANGES,v
  retrieving revision 1.220
  retrieving revision 1.221
  diff -C3 -r1.220 -r1.221
  *** CHANGES   1997/04/05 06:09:51     1.220
  --- CHANGES   1997/04/06 07:43:38     1.221
  ***************
  *** 47,53 ****
    
      *) Added missing timeouts for sending header fields, error responses,
         and the last chunk of chunked encoding, each of which could have
  !      resulted in a process being stuck in write forever. [Roy Fielding]
    
      *) mod_auth_anon required an @ or a . in the email address, not both.
         [Dirk vanGulik]
  --- 47,58 ----
    
      *) Added missing timeouts for sending header fields, error responses,
         and the last chunk of chunked encoding, each of which could have
  !      resulted in a process being stuck in write forever.  Using soft_timeout
  !      requires that the sender check for an aborted connection rather than
  !      continuing after an EINTR.  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.  [Roy Fielding]
    
      *) mod_auth_anon required an @ or a . in the email address, not both.
         [Dirk vanGulik]
  
  
  
  1.134     +8 -17     apache/src/http_main.c
  
  Index: http_main.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_main.c,v
  retrieving revision 1.133
  retrieving revision 1.134
  diff -C3 -r1.133 -r1.134
  *** http_main.c       1997/03/22 23:51:02     1.133
  --- http_main.c       1997/04/06 07:43:39     1.134
  ***************
  *** 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 ----
  
  
  
  1.111     +10 -8     apache/src/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_protocol.c,v
  retrieving revision 1.110
  retrieving revision 1.111
  diff -C3 -r1.110 -r1.111
  *** http_protocol.c   1997/03/20 23:30:50     1.110
  --- http_protocol.c   1997/04/06 07:43:39     1.111
  ***************
  *** 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 body", 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))) {
            /*
  
  
  
  1.76      +0 -2      apache/src/http_core.c
  
  Index: http_core.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/http_core.c,v
  retrieving revision 1.75
  retrieving revision 1.76
  diff -C3 -r1.75 -r1.76
  *** http_core.c       1997/04/01 05:00:19     1.75
  --- http_core.c       1997/04/06 07:43:40     1.76
  ***************
  *** 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 ----
  
  
  
  1.13      +0 -1      apache/src/mod_asis.c
  
  Index: mod_asis.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/mod_asis.c,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -C3 -r1.12 -r1.13
  *** mod_asis.c        1997/03/07 14:15:37     1.12
  --- mod_asis.c        1997/04/06 07:43:40     1.13
  ***************
  *** 97,103 ****
        return OK;
        }
        
  -     soft_timeout ("send", r);
        send_http_header (r);
        if (!r->header_only) send_fd (f, r);
    
  --- 97,102 ----
  
  
  
  1.37      +9 -5      apache/src/mod_cgi.c
  
  Index: mod_cgi.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/mod_cgi.c,v
  retrieving revision 1.36
  retrieving revision 1.37
  diff -C3 -r1.36 -r1.37
  *** mod_cgi.c 1997/04/01 06:17:52     1.36
  --- mod_cgi.c 1997/04/06 07:43:40     1.37
  ***************
  *** 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,534 ----
            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) &&
  !            !r->connection->aborted)
  !         continue;
  !     kill_timeout(r);
  ! 
        pfclose (r->main ? r->main->pool : r->pool, script_in);
        pfclose (r->main ? r->main->pool : r->pool, script_err);
        }
  
  
  
  1.24      +3 -1      apache/src/mod_dir.c
  
  Index: mod_dir.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/mod_dir.c,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -C3 -r1.23 -r1.24
  *** mod_dir.c 1997/03/07 14:15:39     1.23
  --- mod_dir.c 1997/04/06 07:43:41     1.24
  ***************
  *** 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;
    }
    
  
  
  
  1.20      +11 -24    apache/src/mod_imap.c
  
  Index: mod_imap.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/mod_imap.c,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -C3 -r1.19 -r1.20
  *** mod_imap.c        1997/03/07 14:15:41     1.19
  --- mod_imap.c        1997/04/06 07:43:41     1.20
  ***************
  *** 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)
  
  
  
  1.28      +2 -3      apache/src/mod_include.c
  
  Index: mod_include.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/mod_include.c,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -C3 -r1.27 -r1.28
  *** mod_include.c     1997/03/07 14:15:41     1.27
  --- mod_include.c     1997/04/06 07:43:41     1.28
  ***************
  *** 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);
  
  
  
  1.15      +2 -2      apache/src/mod_info.c
  
  Index: mod_info.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/mod_info.c,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -C3 -r1.14 -r1.15
  *** mod_info.c        1997/03/07 14:15:41     1.14
  --- mod_info.c        1997/04/06 07:43:42     1.15
  ***************
  *** 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;
    }
    
  
  
  
  1.45      +4 -1      apache/src/mod_status.c
  
  Index: mod_status.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/mod_status.c,v
  retrieving revision 1.44
  retrieving revision 1.45
  diff -C3 -r1.44 -r1.45
  *** mod_status.c      1997/03/07 14:15:43     1.44
  --- mod_status.c      1997/04/06 07:43:42     1.45
  ***************
  *** 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;
    }
    
  
  
  
  1.12      +8 -4      apache/src/modules/proxy/proxy_cache.c
  
  Index: proxy_cache.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_cache.c,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -C3 -r1.11 -r1.12
  *** proxy_cache.c     1997/04/05 06:08:23     1.11
  --- proxy_cache.c     1997/04/06 07:43:48     1.12
  ***************
  *** 526,534 ****
        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);
  --- 526,536 ----
        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);
  ***************
  *** 754,763 ****
            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);
  --- 756,767 ----
            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);
  
  
  
  1.13      +97 -26    apache/src/modules/proxy/proxy_ftp.c
  
  Index: proxy_ftp.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_ftp.c,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -C3 -r1.12 -r1.13
  *** proxy_ftp.c       1997/03/20 18:40:15     1.12
  --- proxy_ftp.c       1997/04/06 07:43:48     1.13
  ***************
  *** 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;
            }
  
  
  
  1.16      +3 -0      apache/src/modules/proxy/proxy_http.c
  
  Index: proxy_http.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_http.c,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -C3 -r1.15 -r1.16
  *** proxy_http.c      1997/03/20 18:40:15     1.15
  --- proxy_http.c      1997/04/06 07:43:49     1.16
  ***************
  *** 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 */
  
  
  
  1.9       +14 -5     apache/src/modules/proxy/proxy_util.c
  
  Index: proxy_util.c
  ===================================================================
  RCS file: /export/home/cvs/apache/src/modules/proxy/proxy_util.c,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -C3 -r1.8 -r1.9
  *** proxy_util.c      1997/03/20 18:40:16     1.8
  --- proxy_util.c      1997/04/06 07:43:49     1.9
  ***************
  *** 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);
  
  
  

Reply via email to