From 9e6393182e75d6b8eb33a94036df2b03982894c7 Mon Sep 17 00:00:00 2001 From: "William A. Rowe Jr" Date: Wed, 11 Aug 2004 22:05:20 +0000 Subject: [PATCH] Added ap_proxy_determine_connection. It will be used both for http and ajp handlers. Started writing apr_reslist connection pool. Submitted by: mturk git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@104582 13f79535-47bb-0310-9956-ffa450edef68 --- modules/proxy/mod_proxy.h | 4 ++ modules/proxy/proxy_util.c | 132 +++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index 4911a3bdfb..0f1b3471ee 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -195,6 +195,7 @@ typedef struct { typedef struct { apr_pool_t *pool; /* Subpool used for creating socket */ apr_socket_t *sock; + int flags; /* 0: newly created 1: initialized -1: in error */ int close; /* Close 'this' connection */ } proxy_conn; @@ -353,6 +354,9 @@ PROXY_DECLARE(struct proxy_balancer *) ap_proxy_get_balancer(apr_pool_t *p, prox PROXY_DECLARE(const char *) ap_proxy_add_balancer(struct proxy_balancer **balancer, apr_pool_t *p, proxy_server_conf *conf, const char *url); PROXY_DECLARE(void) ap_proxy_add_worker_to_balancer(struct proxy_balancer *balancer, proxy_worker *worker); PROXY_DECLARE(int) ap_proxy_pre_request(proxy_worker **worker, struct proxy_balancer **balancer, request_rec *r, proxy_server_conf *conf, char **url); +PROXY_DECLARE(apr_status_t) ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, proxy_server_conf *conf, proxy_module_conf *mconf, + apr_pool_t *ppool, apr_uri_t *uri, char **url, const char *proxyname, apr_port_t proxyport, + char *server_portstr, int server_portstr_size); /* For proxy_util */ extern module PROXY_DECLARE_DATA proxy_module; diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index d35fc1abf2..81124e2f79 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -1303,4 +1303,136 @@ PROXY_DECLARE(int) ap_proxy_connect_to_backend(apr_socket_t **newsock, } return connected ? 0 : 1; } + +static apr_status_t proxy_conn_cleanup(void *theconn) +{ + proxy_conn *conn = (proxy_conn *)theconn; + /* Close the socket */ + if (conn->sock) + apr_socket_close(conn->sock); + conn->sock = NULL; + return APR_SUCCESS; +} + +/* reslist constructor */ +static apr_status_t connection_constructor(void **resource, void *params, + apr_pool_t *pool) +{ + apr_pool_t *ctx; + proxy_conn *conn; + server_rec *s = (server_rec *)params; + /* Create the subpool for each connection + * This keeps the memory consumption constant + * when disconnecting from backend. + */ + apr_pool_create(&ctx, pool); + conn = apr_pcalloc(ctx, sizeof(proxy_conn)); + + conn->pool = ctx; + *resource = conn; + /* register the pool cleanup */ + apr_pool_cleanup_register(ctx, (void *)conn, + proxy_conn_cleanup, apr_pool_cleanup_null); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "proxy: socket is constructed"); + + return APR_SUCCESS; +} + +/* reslist destructor */ +static apr_status_t connection_destructor(void *resource, void *params, + apr_pool_t *pool) +{ + proxy_conn *conn = (proxy_conn *)resource; + server_rec *s = (server_rec *)params; + + apr_pool_destroy(conn->pool); + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "proxy: socket is destructed"); + + return APR_SUCCESS; +} + + +PROXY_DECLARE(apr_status_t) +ap_proxy_determine_connection(apr_pool_t *p, request_rec *r, + proxy_server_conf *conf, + proxy_module_conf *mconf, + apr_pool_t *ppool, + apr_uri_t *uri, + char **url, + const char *proxyname, + apr_port_t proxyport, + char *server_portstr, + int server_portstr_size) +{ + int server_port; + apr_status_t err = APR_SUCCESS; + /* + * Break up the URL to determine the host to connect to + */ + + /* we break the URL into host, port, uri */ + if (APR_SUCCESS != apr_uri_parse(p, *url, uri)) { + return ap_proxyerror(r, HTTP_BAD_REQUEST, + apr_pstrcat(p,"URI cannot be parsed: ", *url, + NULL)); + } + if (!uri->port) { + uri->port = apr_uri_port_of_scheme(uri->scheme); + } + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: HTTP connecting %s to %s:%d", *url, uri->hostname, + uri->port); + + /* allocate these out of the specified connection pool + * The scheme handler decides if this is permanent or + * short living pool. + */ + /* are we connecting directly, or via a proxy? */ + if (proxyname) { + mconf->conn_rec->hostname = apr_pstrdup(ppool, proxyname); + mconf->conn_rec->port = proxyport; + /* see memory note above */ + } else { + mconf->conn_rec->hostname = apr_pstrdup(ppool, uri->hostname); + mconf->conn_rec->port = uri->port; + *url = apr_pstrcat(p, uri->path, uri->query ? "?" : "", + uri->query ? uri->query : "", + uri->fragment ? "#" : "", + uri->fragment ? uri->fragment : "", NULL); + } + if (!mconf->worker->cp->addr) + err = apr_sockaddr_info_get(&(mconf->worker->cp->addr), + mconf->conn_rec->hostname, APR_UNSPEC, + mconf->conn_rec->port, 0, + mconf->worker->cp->pool); + + /* do a DNS lookup for the destination host */ + if (err != APR_SUCCESS) { + return ap_proxyerror(r, HTTP_BAD_GATEWAY, + apr_pstrcat(p, "DNS lookup failure for: ", + mconf->conn_rec->hostname, NULL)); + } + + /* Get the server port for the Via headers */ + { + server_port = ap_get_server_port(r); + if (ap_is_default_port(server_port, r)) { + strcpy(server_portstr,""); + } else { + apr_snprintf(server_portstr, server_portstr_size, ":%d", + server_port); + } + } + + /* check if ProxyBlock directive on this host */ + if (OK != ap_proxy_checkproxyblock(r, conf, mconf->worker->cp->addr)) { + return ap_proxyerror(r, HTTP_FORBIDDEN, + "Connect to remote machine blocked"); + } + return OK; +} -- 2.50.1