You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by mi...@apache.org on 2001/04/05 20:25:05 UTC

cvs commit: httpd-proxy/module-2.0 mod_proxy.c mod_proxy.h proxy_http.c

minfrin     01/04/05 11:25:05

  Modified:    .        CHANGES
               module-2.0 mod_proxy.c mod_proxy.h proxy_http.c
  Log:
  Reworked the storage of the client socket between keepalive connections
  to fix some nasty problems with the socket lasting longer than the
  memory pool it was allocated from.
  
  Revision  Changes    Path
  1.14      +5 -0      httpd-proxy/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/httpd-proxy/CHANGES,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- CHANGES	2001/04/04 18:47:41	1.13
  +++ CHANGES	2001/04/05 18:25:03	1.14
  @@ -1,6 +1,11 @@
   
   mod_proxy changes for 2.0.15 current
   
  +  *) Reworked the storage of the client socket between keepalive connections
  +     to fix some nasty problems with the socket lasting longer than the
  +     memory pool it was allocated from.
  +     [Graham Leggett <mi...@sharp.fm>]
  +
     *) Fixed bug where a hostname without a "." in it (such as "localhost")
        would not trigger an IP address check with ProxyBlock.
        [Graham Leggett <mi...@sharp.fm>]
  
  
  
  1.32      +6 -3      httpd-proxy/module-2.0/mod_proxy.c
  
  Index: mod_proxy.c
  ===================================================================
  RCS file: /home/cvs/httpd-proxy/module-2.0/mod_proxy.c,v
  retrieving revision 1.31
  retrieving revision 1.32
  diff -u -r1.31 -r1.32
  --- mod_proxy.c	2001/04/04 18:47:42	1.31
  +++ mod_proxy.c	2001/04/05 18:25:04	1.32
  @@ -414,8 +414,12 @@
       if (strcasecmp(scheme, "ftp") == 0)
   	return ap_proxy_ftp_handler(r, NULL, url);
   #endif
  -    else
  +    else {
  +        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, 0, r->server,
  +		     "Neither CONNECT, HTTP or FTP for %s",
  +		     r->uri);
   	return HTTP_FORBIDDEN;
  +    }
   }
   
   /* -------------------------------------------------------------- */
  @@ -431,7 +435,7 @@
       ps->noproxies = ap_make_array(p, 10, sizeof(struct noproxy_entry));
       ps->dirconn = ap_make_array(p, 10, sizeof(struct dirconn_entry));
       ps->allowed_connect_ports = ap_make_array(p, 10, sizeof(int));
  -/*    pc->origin = ap_make_array(p, 10, sizeof(struct origin_entry));*/
  +    ps->client_socket = NULL;
       ps->domain = NULL;
       ps->viaopt = via_off; /* initially backward compatible with 1.3.1 */
       ps->viaopt_set = 0; /* 0 means default */
  @@ -455,7 +459,6 @@
       ps->noproxies = ap_append_arrays(p, base->noproxies, overrides->noproxies);
       ps->dirconn = ap_append_arrays(p, base->dirconn, overrides->dirconn);
       ps->allowed_connect_ports = ap_append_arrays(p, base->allowed_connect_ports, overrides->allowed_connect_ports);
  -/*    ps->origin = base->origin;*/
   
       ps->domain = (overrides->domain == NULL) ? base->domain : overrides->domain;
       ps->viaopt = (overrides->viaopt_set == 0) ? base->viaopt : overrides->viaopt;
  
  
  
  1.32      +4 -7      httpd-proxy/module-2.0/mod_proxy.h
  
  Index: mod_proxy.h
  ===================================================================
  RCS file: /home/cvs/httpd-proxy/module-2.0/mod_proxy.h,v
  retrieving revision 1.31
  retrieving revision 1.32
  diff -u -r1.31 -r1.32
  --- mod_proxy.h	2001/04/04 18:47:42	1.31
  +++ mod_proxy.h	2001/04/05 18:25:04	1.32
  @@ -167,11 +167,6 @@
       struct apr_sockaddr_t *addr;
   };
   
  -struct origin_entry {
  -    conn_rec *origin;
  -    struct origin_entry *next;
  -};
  -
   typedef struct {
       apr_array_header_t *proxies;
       apr_array_header_t *aliases;
  @@ -179,8 +174,10 @@
       apr_array_header_t *noproxies;
       apr_array_header_t *dirconn;
       apr_array_header_t *allowed_connect_ports;
  -/*    apr_array_header_t *origin_array;*/
  -    conn_rec *origin;
  +    long id;
  +    const char *connectname;
  +    apr_port_t connectport;
  +    apr_socket_t *client_socket;
       const char *domain;		/* domain name to use in absence of a domain name in the request */
       int req;			/* true if proxy requests are enabled */
       char req_set;
  
  
  
  1.40      +46 -46    httpd-proxy/module-2.0/proxy_http.c
  
  Index: proxy_http.c
  ===================================================================
  RCS file: /home/cvs/httpd-proxy/module-2.0/proxy_http.c,v
  retrieving revision 1.39
  retrieving revision 1.40
  diff -u -r1.39 -r1.40
  --- proxy_http.c	2001/04/04 18:47:42	1.39
  +++ proxy_http.c	2001/04/05 18:25:04	1.40
  @@ -180,7 +180,7 @@
   		       const char *proxyname, int proxyport)
   {
       request_rec *rp;
  -    apr_pool_t *p = r->connection->pool;
  +    apr_pool_t *p = r->pool;
       const char *connectname;
       int connectport = 0;
       apr_sockaddr_t *uri_addr;
  @@ -271,38 +271,31 @@
                                connectname, NULL));
       }
   
  -    /* if a KeepAlive socket is already open, check whether it must stay
  +    /* if a keepalive socket is already open, check whether it must stay
        * open, or whether it should be closed and a new socket created.
        */
  -    if (conf->origin) {
  -	struct apr_sockaddr_t *remote_addr;
  -	apr_port_t port;
  -	if ((remote_addr = conf->origin->remote_addr) &&
  -	    (APR_SUCCESS == apr_sockaddr_port_get(&port, remote_addr)) &&
  -            (port == connectport) &&
  -            (!apr_strnatcasecmp(conf->origin->remote_addr->hostname,connectname))) {
  +    if (conf->client_socket) {
  +	if ((conf->id == r->connection->id) &&
  +	    (conf->connectport == connectport) &&
  +	    (conf->connectname) &&
  +            (!apr_strnatcasecmp(conf->connectname,connectname))) {
   	    ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
   			 "proxy: keepalive address match (keep original socket)");
           }
   	else {
               ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
  -			 "proxy: keepalive address mismatch (close old socket (%s/%s, %d/%d))", connectname, conf->origin->remote_addr->hostname, connectport, port);
  -            apr_socket_close(conf->origin->client_socket);
  -            conf->origin = NULL;
  +			 "proxy: keepalive address mismatch (close old socket (%s/%s, %d/%d))", connectname, conf->connectname, connectport, conf->connectport);
  +            apr_socket_close(conf->client_socket);
  +            conf->client_socket = NULL;
   	}
       }
   
       /* get a socket - either a keepalive one, or a new one */
       new = 1;
  -    if (conf->origin) {
  +    if (conf->client_socket) {
   
   	/* use previous keepalive socket */
  -	origin = conf->origin;
  -	sock = origin->client_socket;
  -	origin->aborted = 0;
  -	origin->keepalive = 1;
  -	origin->keepalives++;
  -	origin->remain = 0;
  +	sock = conf->client_socket;
   	new = 0;
   
   	/* XXX FIXME: If the socket has since closed, change new to 1 so
  @@ -311,7 +304,9 @@
       if (new) {
   
   	/* create a new socket */
  -	if ((apr_socket_create(&sock, APR_INET, SOCK_STREAM, p)) != APR_SUCCESS) {
  +	/* allocate this out of the process pool - if this socket gets lost then the proxy
  +	 * hangs when the socket is closed...! */
  +	if ((apr_socket_create(&sock, APR_INET, SOCK_STREAM, r->server->process->pconf)) != APR_SUCCESS) {
               ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
   			 "proxy: error creating socket");
   	    return HTTP_INTERNAL_SERVER_ERROR;
  @@ -325,6 +320,9 @@
   	}
   #endif
   
  +	ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
  +		     "proxy: socket has been created");
  +
   	/*
   	 * At this point we have a list of one or more IP addresses of
   	 * the machine to connect to. If configured, reorder this
  @@ -352,22 +350,6 @@
   		continue;
               }
   
  -	    /* the socket is now open, create a new connection */
  -    	    origin = ap_new_connection(p, r->server, sock, 0);
  -	    conf->origin = origin;
  -    	    if (!origin) {
  -		/* the peer reset the connection already; ap_new_connection() 
  -		 * closed the socket */
  -		ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
  -			     "proxy: an error occurred creating a new connection to %pI (%s)", connect_addr, connectname);
  -		connect_addr = connect_addr->next;
  -		continue;
  -	    }
  -
  -	    /* we use keepalives unless later specified */
  -	    origin->keepalive = 1;
  -	    origin->keepalives = 1;
  -
   	    /* if we get here, all is well */
   	    failed = 0;
   	    break;
  @@ -384,7 +366,31 @@
   	}
       }
   
  +    ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
  +		 "proxy: socket is connected");
   
  +    /* the socket is now open, create a new connection */
  +    origin = ap_new_connection(p, r->server, sock, r->connection->id);
  +    if (!origin) {
  +	/* the peer reset the connection already; ap_new_connection() 
  +	 * closed the socket */
  +	ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
  +		     "proxy: an error occurred creating a new connection to %pI (%s)", connect_addr, connectname);
  +	apr_socket_close(sock);
  +	return HTTP_INTERNAL_SERVER_ERROR;
  +    }
  +    conf->id = r->connection->id;
  +    /* allocate this out of the connection pool - the check on r->connection->id makes
  +     * sure that this string does not live past the connection lifetime */
  +    conf->connectname = apr_pstrdup(r->connection->pool, connectname);
  +    conf->connectport = connectport;
  +    conf->client_socket = sock;
  +
  +    ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
  +		 "proxy: connection complete");
  +
  +
  +
       /*
        * Step Three: Send the Request
        *
  @@ -392,11 +398,8 @@
        */
   
       /* set up the connection filters */
  -    origin->input_filters = NULL;
       ap_add_input_filter("HTTP_IN", NULL, NULL, origin);
       ap_add_input_filter("CORE_IN", NULL, NULL, origin);
  -
  -    origin->output_filters = NULL;
       ap_add_output_filter("CORE", NULL, NULL, origin);
   
   
  @@ -577,16 +580,16 @@
   	apr_bucket_read(e, (const char **)&response, &len, APR_BLOCK_READ);
       }
       if (len == -1) {
  -	conf->origin = NULL;
   	apr_socket_close(sock);
  +	conf->client_socket = NULL;
   	ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
   	     "proxy: error reading from remote server %s (length %d) using ap_get_brigade()",
   	     connectname, len);
   	return ap_proxyerror(r, HTTP_BAD_GATEWAY,
   			     "Error reading from remote server");
       } else if (len == 0) {
  -	conf->origin = NULL;
   	apr_socket_close(sock);
  +	conf->client_socket = NULL;
   	return ap_proxyerror(r, HTTP_BAD_GATEWAY,
   			     "No response data from server");
       }
  @@ -604,7 +607,7 @@
           /* If not an HTTP/1 message or if the status line was > 8192 bytes */
   	if (response[5] != '1' || response[len - 1] != '\n') {
   	    apr_socket_close(sock);
  -	    conf->origin = NULL;
  +	    conf->client_socket = NULL;
   	    return ap_proxyerror(r, HTTP_BAD_GATEWAY,
   				 apr_pstrcat(p, "Corrupt status line returned by remote server: ", response, NULL));
   	}
  @@ -754,10 +757,7 @@
        */
       if (close) {
           apr_socket_close(sock);
  -        conf->origin = NULL;
  -    }
  -    else {
  -	origin->keptalive = 1;
  +	conf->client_socket = NULL;
       }
   
       return OK;