@@ -, +, @@ --- httpd/include/mod_proxy.h | 13 ++++- httpd/modules/proxy/mod_proxy.c | 51 ++++++++++++++++---- httpd/modules/proxy/mod_proxy.h | 13 ++++- .../httpd/modules/proxy/mod_proxy_connect.c | 18 ++++++- httpd/modules/proxy/mod_proxy_http.c | 19 ++++++-- 5 files changed, 98 insertions(+), 16 deletions(-) --- a/httpd/include/mod_proxy.h +++ a/httpd/include/mod_proxy.h @@ -99,6 +99,7 @@ struct proxy_remote { const char *scheme; /* the schemes handled by this proxy, or '*' */ const char *protocol; /* the scheme used to talk to this proxy */ const char *hostname; /* the hostname of this proxy */ + const char *auth; /* base64encode(:) */ ap_regex_t *regexp; /* compiled regex (if any) for the remote */ int use_regex; /* simple boolean. True if we have a regex pattern */ apr_port_t port; /* the port for this proxy */ @@ -486,7 +487,10 @@ struct proxy_balancer_method { APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, scheme_handler, (request_rec *r, proxy_worker *worker, proxy_server_conf *conf, char *url, - const char *proxyhost, apr_port_t proxyport)) +// const char *proxyhost, apr_port_t proxyport)) + const char *proxyhost, apr_port_t proxyport, + const char *proxyauth)) + APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, canon_handler, (request_rec *r, char *url)) @@ -720,6 +724,13 @@ PROXY_DECLARE(int) ap_proxy_post_request(proxy_worker *worker, proxy_server_conf *conf); /** + * Request status function + * @param status status of proxy request + * @return OK or DECLINED + */ + PROXY_DECLARE(int) ap_proxy_request_status(int *status, request_rec *r); + + /** * Determine backend hostname and port * @param p memory pool used for processing * @param r current request --- a/httpd/modules/proxy/mod_proxy.c +++ a/httpd/modules/proxy/mod_proxy.c @@ -1011,7 +1011,9 @@ static int proxy_handler(request_rec *r) access_status = proxy_run_scheme_handler(r, worker, conf, url, ents[i].hostname, - ents[i].port); +// ents[i].port); + ents[i].port, + ents[i].auth); /* Did the scheme handler process the request? */ if (access_status != DECLINED) { @@ -1063,7 +1065,8 @@ static int proxy_handler(request_rec *r) scheme, attempts); AP_PROXY_RUN(r, worker, conf, url, attempts); access_status = proxy_run_scheme_handler(r, worker, conf, - url, NULL, 0); + url, NULL, 0, NULL); +// url, NULL, 0); if (access_status == OK) break; else if (access_status == HTTP_INTERNAL_SERVER_ERROR) { @@ -1285,7 +1288,8 @@ static const char * proxy_server_conf *conf = (proxy_server_conf *) ap_get_module_config(s->module_config, &proxy_module); struct proxy_remote *new; - char *p, *q; +// char *p, *q; + char *p, *q, *a; char *r, *f, *scheme; ap_regex_t *reg = NULL; int port; @@ -1293,6 +1297,7 @@ static const char * r = apr_pstrdup(cmd->pool, r1); scheme = apr_pstrdup(cmd->pool, r1); f = apr_pstrdup(cmd->pool, f1); + // http://host:port p = strchr(r, ':'); if (p == NULL || p[1] != '/' || p[2] != '/' || p[3] == '\0') { if (regex) @@ -1301,9 +1306,26 @@ static const char * return "ProxyRemote: Bad syntax for a remote proxy server"; } else { - scheme[p-r] = 0; +// scheme[p-r] = 0; + scheme[p-r] = '\0'; } - q = strchr(p + 3, ':'); +// q = strchr(p + 3, ':'); + + *p = '\0'; /* terminate r (scheme) */ + p+=3; + /* may extract authentication string */ + q = strchr(p, '@'); + if (q != NULL) { + *q = '\0'; + a = ap_pbase64encode(cmd->pool, p); + p = q; + p+=1; + } + else + a = NULL; + + q = strchr(p, ':'); + if (q != NULL) { if (sscanf(q + 1, "%u", &port) != 1 || port > 65535) { if (regex) @@ -1315,7 +1337,9 @@ static const char * } else port = -1; - *p = '\0'; +// *p = '\0'; + + if (regex) { reg = ap_pregcomp(cmd->pool, f, AP_REG_EXTENDED); if (!reg) @@ -1324,7 +1348,8 @@ static const char * else if (strchr(f, ':') == NULL) ap_str_tolower(f); /* lowercase scheme */ - ap_str_tolower(p + 3); /* lowercase hostname */ +// ap_str_tolower(p + 3); /* lowercase hostname */ + ap_str_tolower(p ); /* lowercase hostname */ if (port == -1) { port = apr_uri_port_of_scheme(scheme); @@ -1333,8 +1358,10 @@ static const char * new = apr_array_push(conf->proxies); new->scheme = f; new->protocol = r; - new->hostname = p + 3; +// new->hostname = p + 3; + new->hostname = p; new->port = port; + new->auth = a; new->regexp = reg; new->use_regex = regex; return NULL; @@ -2539,8 +2566,12 @@ APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, scheme_handler, (request_rec *r, proxy_worker *worker, proxy_server_conf *conf, char *url, const char *proxyhost, - apr_port_t proxyport),(r,worker,conf, - url,proxyhost,proxyport),DECLINED) +// apr_port_t proxyport),(r,worker,conf, +// url,proxyhost,proxyport),DECLINED) + apr_port_t proxyport, + const char *proxyauth + ),(r,worker,conf, + url,proxyhost,proxyport, proxyauth),DECLINED) APR_IMPLEMENT_EXTERNAL_HOOK_RUN_FIRST(proxy, PROXY, int, canon_handler, (request_rec *r, char *url),(r, url),DECLINED) --- a/httpd/modules/proxy/mod_proxy.h +++ a/httpd/modules/proxy/mod_proxy.h @@ -99,6 +99,7 @@ struct proxy_remote { const char *scheme; /* the schemes handled by this proxy, or '*' */ const char *protocol; /* the scheme used to talk to this proxy */ const char *hostname; /* the hostname of this proxy */ + const char *auth; /* base64encode(:) */ ap_regex_t *regexp; /* compiled regex (if any) for the remote */ int use_regex; /* simple boolean. True if we have a regex pattern */ apr_port_t port; /* the port for this proxy */ @@ -486,7 +487,10 @@ struct proxy_balancer_method { APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, scheme_handler, (request_rec *r, proxy_worker *worker, proxy_server_conf *conf, char *url, - const char *proxyhost, apr_port_t proxyport)) +// const char *proxyhost, apr_port_t proxyport)) + const char *proxyhost, apr_port_t proxyport, + const char *proxyauth)) + APR_DECLARE_EXTERNAL_HOOK(proxy, PROXY, int, canon_handler, (request_rec *r, char *url)) @@ -720,6 +724,13 @@ PROXY_DECLARE(int) ap_proxy_post_request(proxy_worker *worker, proxy_server_conf *conf); /** + * Request status function + * @param status status of proxy request + * @return OK or DECLINED + */ + PROXY_DECLARE(int) ap_proxy_request_status(int *status, request_rec *r); + + /** * Determine backend hostname and port * @param p memory pool used for processing * @param r current request --- a/httpd/modules/proxy/mod_proxy_connect.c +++ a/httpd/modules/proxy/mod_proxy_connect.c @@ -194,7 +194,10 @@ static int proxy_connect_transfer(request_rec *r, conn_rec *c_i, conn_rec *c_o, static int proxy_connect_handler(request_rec *r, proxy_worker *worker, proxy_server_conf *conf, char *url, const char *proxyname, - apr_port_t proxyport) +// apr_port_t proxyport) + apr_port_t proxyport, + const char *proxyauth + ) { connect_conf *c_conf = ap_get_module_config(r->server->module_config, &proxy_connect_module); @@ -384,6 +387,19 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker, "sending the CONNECT request to the remote proxy"); ap_fprintf(backconn->output_filters, bb, "CONNECT %s HTTP/1.0" CRLF, r->uri); + + + if (proxyauth) { + ap_fprintf(backconn->output_filters, bb, + "Proxy-Authorization: Basic %s" CRLF, + proxyauth); +// nbytes = apr_snprintf(buffer, sizeof(buffer), +// "Proxy-Authorization: Basic %s" CRLF, +// proxyauth); +// apr_socket_send(sock, buffer, &nbytes); + } + + ap_fprintf(backconn->output_filters, bb, "Proxy-agent: %s" CRLF CRLF, ap_get_server_banner()); ap_fflush(backconn->output_filters, bb); --- a/httpd/modules/proxy/mod_proxy_http.c +++ a/httpd/modules/proxy/mod_proxy_http.c @@ -743,7 +743,9 @@ int ap_proxy_http_request(apr_pool_t *p, request_rec *r, proxy_conn_rec *p_conn, proxy_worker *worker, proxy_server_conf *conf, apr_uri_t *uri, - char *url, char *server_portstr) +// char *url, char *server_portstr) + char *url, char *server_portstr, + const char *proxyauth) { conn_rec *c = r->connection; apr_bucket_alloc_t *bucket_alloc = c->bucket_alloc; @@ -1005,6 +1007,14 @@ int ap_proxy_http_request(apr_pool_t *p, request_rec *r, APR_BRIGADE_INSERT_TAIL(header_brigade, e); } + if (proxyauth) { + buf = apr_pstrcat(p, "Proxy-Authorization: Basic ", + proxyauth, CRLF, NULL); + ap_xlate_proto_to_ascii(buf, strlen(buf)); + e = apr_bucket_pool_create(buf, strlen(buf), p, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(header_brigade, e); + } + /* We have headers, let's figure out our request body... */ input_brigade = apr_brigade_create(p, bucket_alloc); @@ -2129,7 +2139,8 @@ apr_status_t ap_proxy_http_cleanup(const char *scheme, request_rec *r, static int proxy_http_handler(request_rec *r, proxy_worker *worker, proxy_server_conf *conf, char *url, const char *proxyname, - apr_port_t proxyport) +// apr_port_t proxyport) + apr_port_t proxyport, const char *proxyauth) { int status; char server_portstr[32]; @@ -2246,7 +2257,9 @@ static int proxy_http_handler(request_rec *r, proxy_worker *worker, * kinda HTTP ping test, allow for retries */ if ((status = ap_proxy_http_request(p, r, backend, worker, - conf, uri, locurl, server_portstr)) != OK) { +// conf, uri, locurl, server_portstr)) != OK) { + conf, uri, locurl, server_portstr, (is_ssl ? NULL : proxyauth) + )) != OK) { if ((status == HTTP_SERVICE_UNAVAILABLE) && worker->s->ping_timeout_set) { backend->close = 1; ap_log_rerror(APLOG_MARK, APLOG_INFO, status, r, APLOGNO(01115) --