Hi all,
The attached patch makes mod_proxy thread safe, and at the same time
fixes some nasty behavior caused by the non-thread-safeness of the
existing mod_proxy code.
Like last time, the proxy needs to attach the downstream conn_rec to the
upstream conn_rec so that keepalives can be supported. In the mean time
though, it has become clear that this link is necessary for mod_proxy to
work.
It's been suggested that the permanent solution is to allow a mechanism
where modules can save per-connection data other than strings (c->notes)
alongside the conn_rec, but in the meantime we need a temporary solution
so that mod_proxy can work.
The first patch is for httpd.h, the second for mod_proxy.
Regards,
Graham
--
-----------------------------------------
[EMAIL PROTECTED] "There's a moon
over Bourbon Street
tonight..."
diff -u3 -r --exclude=CVS ../../pristine/httpd-2.0/include/httpd.h
httpd-2.0/include/httpd.h
--- ../../pristine/httpd-2.0/include/httpd.h Tue Apr 3 20:09:24 2001
+++ httpd-2.0/include/httpd.h Tue Apr 10 23:49:11 2001
@@ -834,6 +834,8 @@
server_rec *base_server;
/** used by http_vhost.c */
void *vhost_lookup_data;
+ /** used by mod_proxy.c */
+ conn_rec *downstream;
/* Information about the connection itself */
diff -u3 -r --exclude=CVS httpd-proxy2/module-2.0/proxy_http.c
httpd-2.0/modules/proxy/proxy_http.c
--- httpd-proxy2/module-2.0/proxy_http.c Tue Apr 10 23:27:28 2001
+++ httpd-2.0/modules/proxy/proxy_http.c Wed Apr 11 01:10:32 2001
@@ -285,11 +285,12 @@
* 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 (c->downstream) {
+ apr_port_t port = 0;
+ if ((c->downstream->id == c->id) &&
+ (APR_SUCCESS == apr_sockaddr_port_get(&port, c->downstream->remote_addr))
+&&
+ (port == connectport) &&
+ (!apr_strnatcasecmp(c->downstream->remote_host,connectname))) {
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
"proxy: keepalive address match (keep original socket)");
}
@@ -297,20 +298,20 @@
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, c->downstream->remote_host,
+ connectport, port);
+ apr_socket_close(c->downstream->client_socket);
+ c->downstream = NULL;
}
}
/* get a socket - either a keepalive one, or a new one */
new = 1;
- if ((conf->id == c->id) && (conf->connection)) {
+ if ((c->downstream) && (c->downstream->id == c->id)) {
/* use previous keepalive socket */
- sock = conf->connection->client_socket;
- origin = conf->connection;
+ origin = c->downstream;
+ sock = origin->client_socket;
new = 0;
/* reset the connection filters */
@@ -322,7 +323,7 @@
if (new) {
/* create a new socket */
- conf->connection = NULL;
+ c->downstream = NULL;
/* see memory note above */
if ((apr_socket_create(&sock, APR_INET, SOCK_STREAM, c->pool)) != APR_SUCCESS)
{
@@ -399,10 +400,8 @@
apr_socket_close(sock);
return HTTP_INTERNAL_SERVER_ERROR;
}
- conf->id = r->connection->id;
- conf->connectname = connectname;
- conf->connectport = connectport;
- conf->connection = origin;
+ c->downstream = origin;
+ c->downstream->remote_host = apr_pstrdup(c->pool, connectname);
ap_log_error(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r->server,
"proxy: connection complete");
@@ -581,7 +580,7 @@
if (APR_SUCCESS != (rv = ap_proxy_string_read(origin, bb, buffer,
sizeof(buffer)))) {
apr_socket_close(sock);
- conf->connection = NULL;
+ c->downstream = NULL;
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
"proxy: error reading status line from remote server %s",
connectname);
@@ -602,7 +601,7 @@
/* 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;
+ c->downstream = NULL;
return ap_proxyerror(r, HTTP_BAD_GATEWAY,
apr_pstrcat(p, "Corrupt status line returned by
remote server: ", buffer, NULL));
}
@@ -752,7 +751,7 @@
*/
if (close || (r->proto_num < HTTP_VERSION(1,1))) {
apr_socket_close(sock);
- conf->connection = NULL;
+ c->downstream = NULL;
}
return OK;