From: William A. Rowe Jr Date: Wed, 11 Aug 2004 22:44:38 +0000 (+0000) Subject: Fix the assertion bug for reslist caused by returning the X-Git-Tag: post_ajp_proxy~28 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=674cfed55413fe26d459a5a7325701ea672ad6e7;p=apache Fix the assertion bug for reslist caused by returning the same connection back to the pool twice. Submitted by: mturk git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@104602 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/proxy/proxy_http.c b/modules/proxy/proxy_http.c index dda722dd22..13caec90ad 100644 --- a/modules/proxy/proxy_http.c +++ b/modules/proxy/proxy_http.c @@ -796,7 +796,8 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, } if (len <= 0) { apr_socket_close(backend->sock); - backend->connection = NULL; + backend->sock = NULL; +// backend->connection = NULL; ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "proxy: error reading status line from remote " "server %s", backend->hostname); @@ -819,7 +820,8 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, */ else if ((buffer[5] != '1') || (len >= sizeof(buffer)-1)) { apr_socket_close(backend->sock); - backend->connection = NULL; +// backend->connection = NULL; + backend->sock = NULL; return ap_proxyerror(r, HTTP_BAD_GATEWAY, apr_pstrcat(p, "Corrupt status line returned by remote " "server: ", buffer, NULL)); @@ -1029,7 +1031,7 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, * backend server from hanging around waiting * for a slow client to eat these bytes */ - ap_proxy_http_cleanup(NULL, r, backend); + backend->close = 1; /* signal that we must leave */ finish = TRUE; } @@ -1092,18 +1094,11 @@ apr_status_t ap_proxy_http_cleanup(const char *scheme, request_rec *r, /* if the connection is < HTTP/1.1, or Connection: close, * we close the socket, otherwise we leave it open for KeepAlive support */ - if (backend->close) { + if (backend->close || (r->proto_num < HTTP_VERSION(1,1))) { backend->close_on_recycle = 1; - ap_set_module_config(r->connection, &proxy_http_module, backend); + ap_set_module_config(r->connection->conn_config, &proxy_http_module, NULL); ap_proxy_release_connection(scheme, backend, r->server); } - else if(r->proto_num < HTTP_VERSION(1,1)) { - if (backend->sock) { - apr_socket_close(backend->sock); - backend->sock = NULL; - backend->connection = NULL; - } - } return OK; } @@ -1231,7 +1226,7 @@ int ap_proxy_http_handler(request_rec *r, proxy_worker *worker, /* Step Five: Receive the Response */ status = ap_proxy_http_process_response(p, r, backend, backend->connection, conf, server_portstr); - if ( status != OK ) { + if (status != OK) { /* clean up even if there is an error */ ap_proxy_http_cleanup(scheme, r, backend); return status; diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index 4e74e229ae..aedff9f365 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -1319,14 +1319,24 @@ static apr_status_t proxy_conn_cleanup(void *theconn) static apr_status_t connection_cleanup(void *theconn) { proxy_conn_rec *conn = (proxy_conn_rec *)theconn; + proxy_worker *worker = conn->worker; + /* deterimine if the connection need to be closed */ if (conn->close_on_recycle) { if (conn->sock) apr_socket_close(conn->sock); conn->sock = NULL; } - conn->connection = NULL; - ap_proxy_release_connection(NULL, conn, NULL); +#if APR_HAS_THREADS + if (worker->hmax && worker->cp->res) { + apr_reslist_release(worker->cp->res, (void *)conn); + } + else +#endif + { + worker->cp->conn = conn; + } + /* Allways return the SUCCESS */ return APR_SUCCESS; } @@ -1486,39 +1496,12 @@ PROXY_DECLARE(int) ap_proxy_release_connection(const char *proxy_function, server_rec *s) { apr_status_t rv = APR_SUCCESS; - proxy_worker *worker = conn->worker; - if (!worker) { - /* something bad happened. Obviously bug. - * for now make a core dump. - */ - } - - /* Need to close the connection */ - if (conn->sock && conn->close) { - apr_socket_close(conn->sock); - conn->sock = NULL; - } - conn->close = 0; /* If there is a connection kill it's cleanup */ if (conn->connection) apr_pool_cleanup_kill(conn->connection->pool, conn, connection_cleanup); - -#if APR_HAS_THREADS - if (worker->hmax && worker->cp->res) { - rv = apr_reslist_release(worker->cp->res, (void *)conn); - } - else -#endif - { - worker->cp->conn = conn; - } - if (rv != APR_SUCCESS && proxy_function) { - ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, - "proxy: %s: failed to acquire connection for (%s)", - proxy_function, conn->hostname); - return DECLINED; - } + connection_cleanup(conn); + conn->connection = NULL; return OK; } @@ -1652,7 +1635,8 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function, while (backend_addr && !connected) { if ((rv = apr_socket_create(&newsock, backend_addr->family, - SOCK_STREAM, 0, conn->pool)) != APR_SUCCESS) { + SOCK_STREAM, APR_PROTO_TCP, + conn->pool)) != APR_SUCCESS) { loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR; ap_log_error(APLOG_MARK, loglevel, rv, s, "proxy: %s: error creating fam %d socket for target %s", @@ -1748,6 +1732,12 @@ PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function, conn->sock = NULL; return HTTP_INTERNAL_SERVER_ERROR; } + /* register the connection cleanup to client connection + * so that the connection can be closed or reused + */ + apr_pool_cleanup_register(c->pool, (void *)conn, + connection_cleanup, + apr_pool_cleanup_null); /* For ssl connection to backend */ if (conn->is_ssl) { @@ -1771,12 +1761,5 @@ PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function, /* set up the connection filters */ ap_run_pre_connection(conn->connection, conn->sock); - /* register the connection cleanup to client connection - * so that the connection can be closed or reused - */ - apr_pool_cleanup_register(conn->connection->pool, (void *)conn, - connection_cleanup, - apr_pool_cleanup_null); - return OK; }