]> granicus.if.org Git - apache/commitdiff
Fixed some thread-safety issues with the HTTP proxy in mod_proxy.
authorGraham Leggett <minfrin@apache.org>
Wed, 11 Apr 2001 23:07:21 +0000 (23:07 +0000)
committerGraham Leggett <minfrin@apache.org>
Wed, 11 Apr 2001 23:07:21 +0000 (23:07 +0000)
PR:
Obtained from:
Reviewed by:

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@88814 13f79535-47bb-0310-9956-ffa450edef68

modules/proxy/mod_proxy.h
modules/proxy/proxy_http.c

index c0305b1c8a5d7e809736149134421bcc38b8b438..7a8f6eab3101de40949024cc9251723e6f01298a 100644 (file)
@@ -192,6 +192,12 @@ struct per_thread_data {
     char *charpbuf[2];
 };
 
+typedef struct {
+    conn_rec *connection;
+    char *hostname;
+    apr_port_t port;
+} proxy_conn_rec;
+
 typedef struct {
         float cache_completion; /* completion percentage */
         int content_length; /* length of the content */
index 1095ea621a48adad37b8db436d22a7c080c18307..c69acb69d6b8c1a99b398a2ff0ffd1e72feae937 100644 (file)
@@ -206,6 +206,15 @@ int ap_proxy_http_handler(request_rec *r, char *url,
     apr_bucket *e;
     apr_bucket_brigade *bb = apr_brigade_create(p);
 
+    proxy_conn_rec *backend =
+    (proxy_conn_rec *) ap_get_module_config(c->conn_config, &proxy_module);
+    if (!backend) {
+       backend = ap_pcalloc(c->pool, sizeof(proxy_conn_rec));
+       backend->connection = NULL;
+       backend->hostname = NULL;
+       backend->port = 0;
+       ap_set_module_config(c->conn_config, &proxy_module, backend);
+    }
 
     /*
      * Step One: Determine Who To Connect To
@@ -285,11 +294,11 @@ int ap_proxy_http_handler(request_rec *r, char *url,
      * open, or whether it should be closed and a new socket created.
      */
     /* see memory note above */
-    if (conf->connection) {
-       if ((conf->id == c->id) &&
-           (conf->connectport == connectport) &&
-           (conf->connectname) &&
-            (!apr_strnatcasecmp(conf->connectname,connectname))) {
+    if (backend->connection) {
+       if ((backend->connection->id == c->id) &&
+           (backend->port == connectport) &&
+           (backend->hostname) &&
+            (!apr_strnatcasecmp(backend->hostname,connectname))) {
            ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
                         "proxy: keepalive address match (keep original socket)");
         }
@@ -297,20 +306,20 @@ int ap_proxy_http_handler(request_rec *r, char *url,
             ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
                         "proxy: keepalive address mismatch / connection has"
                         " changed (close old socket (%s/%s, %d/%d))", 
-                        connectname, conf->connectname, 
-                        connectport, conf->connectport);
-            apr_socket_close(conf->connection->client_socket);
-            conf->connection = NULL;
+                        connectname, backend->hostname, 
+                        connectport, backend->port);
+            apr_socket_close(backend->connection->client_socket);
+            backend->connection = NULL;
        }
     }
 
     /* get a socket - either a keepalive one, or a new one */
     new = 1;
-    if ((conf->id == c->id) && (conf->connection)) {
+    if ((backend->connection) && (backend->connection->id == c->id)) {
 
        /* use previous keepalive socket */
-       sock = conf->connection->client_socket;
-       origin = conf->connection;
+       origin = backend->connection;
+       sock = origin->client_socket;
        new = 0;
 
        /* reset the connection filters */
@@ -322,7 +331,7 @@ int ap_proxy_http_handler(request_rec *r, char *url,
     if (new) {
 
        /* create a new socket */
-       conf->connection = NULL;
+       backend->connection = NULL;
 
        /* see memory note above */
        if ((apr_socket_create(&sock, APR_INET, SOCK_STREAM, c->pool)) != APR_SUCCESS) {
@@ -389,7 +398,7 @@ int ap_proxy_http_handler(request_rec *r, char *url,
        ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
                     "proxy: socket is connected");
 
-       /* the socket is now open, create a new downstream connection */
+       /* the socket is now open, create a new backend server connection */
        origin = ap_new_connection(c->pool, r->server, sock, r->connection->id);
        if (!origin) {
            /* the peer reset the connection already; ap_new_connection() 
@@ -399,10 +408,9 @@ int ap_proxy_http_handler(request_rec *r, char *url,
            apr_socket_close(sock);
            return HTTP_INTERNAL_SERVER_ERROR;
        }
-       conf->id = r->connection->id;
-       conf->connectname = connectname;
-       conf->connectport = connectport;
-       conf->connection = origin;
+       backend->connection = origin;
+       backend->hostname = apr_pstrdup(c->pool, connectname);
+       backend->port = connectport;
 
        ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
                     "proxy: connection complete");
@@ -581,7 +589,7 @@ int ap_proxy_http_handler(request_rec *r, char *url,
 
     if (APR_SUCCESS != (rv = ap_proxy_string_read(origin, bb, buffer, sizeof(buffer)))) {
        apr_socket_close(sock);
-       conf->connection = NULL;
+       backend->connection = NULL;
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
             "proxy: error reading status line from remote server %s",
             connectname);
@@ -602,7 +610,7 @@ int ap_proxy_http_handler(request_rec *r, char *url,
         /* If not an HTTP/1 message or if the status line was > 8192 bytes */
        else if ((buffer[5] != '1') || (len >= sizeof(buffer)-1)) {
            apr_socket_close(sock);
-           conf->connection = NULL;
+           backend->connection = NULL;
            return ap_proxyerror(r, HTTP_BAD_GATEWAY,
                                 apr_pstrcat(p, "Corrupt status line returned by remote server: ", buffer, NULL));
        }
@@ -752,7 +760,7 @@ int ap_proxy_http_handler(request_rec *r, char *url,
      */
     if (close || (r->proto_num < HTTP_VERSION(1,1))) {
         apr_socket_close(sock);
-       conf->connection = NULL;
+       backend->connection = NULL;
     }
 
     return OK;