mirror of
https://github.com/apache/httpd.git
synced 2025-08-08 15:02:10 +03:00
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
This commit is contained in:
@@ -796,7 +796,8 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r,
|
|||||||
}
|
}
|
||||||
if (len <= 0) {
|
if (len <= 0) {
|
||||||
apr_socket_close(backend->sock);
|
apr_socket_close(backend->sock);
|
||||||
backend->connection = NULL;
|
backend->sock = NULL;
|
||||||
|
// backend->connection = NULL;
|
||||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||||
"proxy: error reading status line from remote "
|
"proxy: error reading status line from remote "
|
||||||
"server %s", backend->hostname);
|
"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)) {
|
else if ((buffer[5] != '1') || (len >= sizeof(buffer)-1)) {
|
||||||
apr_socket_close(backend->sock);
|
apr_socket_close(backend->sock);
|
||||||
backend->connection = NULL;
|
// backend->connection = NULL;
|
||||||
|
backend->sock = NULL;
|
||||||
return ap_proxyerror(r, HTTP_BAD_GATEWAY,
|
return ap_proxyerror(r, HTTP_BAD_GATEWAY,
|
||||||
apr_pstrcat(p, "Corrupt status line returned by remote "
|
apr_pstrcat(p, "Corrupt status line returned by remote "
|
||||||
"server: ", buffer, NULL));
|
"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
|
* backend server from hanging around waiting
|
||||||
* for a slow client to eat these bytes
|
* for a slow client to eat these bytes
|
||||||
*/
|
*/
|
||||||
ap_proxy_http_cleanup(NULL, r, backend);
|
backend->close = 1;
|
||||||
/* signal that we must leave */
|
/* signal that we must leave */
|
||||||
finish = TRUE;
|
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,
|
/* if the connection is < HTTP/1.1, or Connection: close,
|
||||||
* we close the socket, otherwise we leave it open for KeepAlive support
|
* 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;
|
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);
|
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;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1231,7 +1226,7 @@ int ap_proxy_http_handler(request_rec *r, proxy_worker *worker,
|
|||||||
/* Step Five: Receive the Response */
|
/* Step Five: Receive the Response */
|
||||||
status = ap_proxy_http_process_response(p, r, backend, backend->connection, conf,
|
status = ap_proxy_http_process_response(p, r, backend, backend->connection, conf,
|
||||||
server_portstr);
|
server_portstr);
|
||||||
if ( status != OK ) {
|
if (status != OK) {
|
||||||
/* clean up even if there is an error */
|
/* clean up even if there is an error */
|
||||||
ap_proxy_http_cleanup(scheme, r, backend);
|
ap_proxy_http_cleanup(scheme, r, backend);
|
||||||
return status;
|
return status;
|
||||||
|
@@ -1319,14 +1319,24 @@ static apr_status_t proxy_conn_cleanup(void *theconn)
|
|||||||
static apr_status_t connection_cleanup(void *theconn)
|
static apr_status_t connection_cleanup(void *theconn)
|
||||||
{
|
{
|
||||||
proxy_conn_rec *conn = (proxy_conn_rec *)theconn;
|
proxy_conn_rec *conn = (proxy_conn_rec *)theconn;
|
||||||
|
proxy_worker *worker = conn->worker;
|
||||||
|
|
||||||
/* deterimine if the connection need to be closed */
|
/* deterimine if the connection need to be closed */
|
||||||
if (conn->close_on_recycle) {
|
if (conn->close_on_recycle) {
|
||||||
if (conn->sock)
|
if (conn->sock)
|
||||||
apr_socket_close(conn->sock);
|
apr_socket_close(conn->sock);
|
||||||
conn->sock = NULL;
|
conn->sock = NULL;
|
||||||
}
|
}
|
||||||
conn->connection = NULL;
|
#if APR_HAS_THREADS
|
||||||
ap_proxy_release_connection(NULL, conn, NULL);
|
if (worker->hmax && worker->cp->res) {
|
||||||
|
apr_reslist_release(worker->cp->res, (void *)conn);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
worker->cp->conn = conn;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allways return the SUCCESS */
|
/* Allways return the SUCCESS */
|
||||||
return APR_SUCCESS;
|
return APR_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -1486,39 +1496,12 @@ PROXY_DECLARE(int) ap_proxy_release_connection(const char *proxy_function,
|
|||||||
server_rec *s)
|
server_rec *s)
|
||||||
{
|
{
|
||||||
apr_status_t rv = APR_SUCCESS;
|
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 there is a connection kill it's cleanup */
|
||||||
if (conn->connection)
|
if (conn->connection)
|
||||||
apr_pool_cleanup_kill(conn->connection->pool, conn, connection_cleanup);
|
apr_pool_cleanup_kill(conn->connection->pool, conn, connection_cleanup);
|
||||||
|
connection_cleanup(conn);
|
||||||
#if APR_HAS_THREADS
|
conn->connection = NULL;
|
||||||
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;
|
|
||||||
}
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1652,7 +1635,8 @@ PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
|
|||||||
|
|
||||||
while (backend_addr && !connected) {
|
while (backend_addr && !connected) {
|
||||||
if ((rv = apr_socket_create(&newsock, backend_addr->family,
|
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;
|
loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR;
|
||||||
ap_log_error(APLOG_MARK, loglevel, rv, s,
|
ap_log_error(APLOG_MARK, loglevel, rv, s,
|
||||||
"proxy: %s: error creating fam %d socket for target %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;
|
conn->sock = NULL;
|
||||||
return HTTP_INTERNAL_SERVER_ERROR;
|
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 */
|
/* For ssl connection to backend */
|
||||||
if (conn->is_ssl) {
|
if (conn->is_ssl) {
|
||||||
@@ -1771,12 +1761,5 @@ PROXY_DECLARE(int) ap_proxy_connection_create(const char *proxy_function,
|
|||||||
/* set up the connection filters */
|
/* set up the connection filters */
|
||||||
ap_run_pre_connection(conn->connection, conn->sock);
|
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;
|
return OK;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user