You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ji...@apache.org on 2010/02/15 20:54:42 UTC
svn commit: r910322 - in /httpd/httpd/branches/2.2.x: CHANGES STATUS
docs/manual/mod/mod_proxy.xml docs/manual/mod/mod_proxy_connect.xml
docs/manual/mod/mod_proxy_http.xml include/ap_mmn.h
modules/proxy/mod_proxy.h modules/proxy/proxy_util.c
Author: jim
Date: Mon Feb 15 19:54:41 2010
New Revision: 910322
URL: http://svn.apache.org/viewvc?rev=910322&view=rev
Log: (empty)
Modified:
httpd/httpd/branches/2.2.x/CHANGES
httpd/httpd/branches/2.2.x/STATUS
httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy.xml
httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy_connect.xml
httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy_http.xml
httpd/httpd/branches/2.2.x/include/ap_mmn.h
httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.h
httpd/httpd/branches/2.2.x/modules/proxy/proxy_util.c
Modified: httpd/httpd/branches/2.2.x/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/CHANGES?rev=910322&r1=910321&r2=910322&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/CHANGES [utf-8] (original)
+++ httpd/httpd/branches/2.2.x/CHANGES [utf-8] Mon Feb 15 19:54:41 2010
@@ -9,6 +9,10 @@
access control is still vulnerable, unless using OpenSSL >= 0.9.8l.
[Joe Orton, Ruediger Pluem, Hartmut Keil <Hartmut.Keil adnovum.ch>]
+ *) mod_proxy, mod_proxy_http: Support remote https proxies
+ by using HTTP CONNECT.
+ PR 19188. [Philippe Dutrueux <lilas evidian.com>, Rainer Jung]
+
*) worker: Don't report server has reached MaxClients until it has.
Add message when server gets within MinSpareThreads of MaxClients.
PR 46996. [Dan Poirier]
Modified: httpd/httpd/branches/2.2.x/STATUS
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/STATUS?rev=910322&r1=910321&r2=910322&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/STATUS (original)
+++ httpd/httpd/branches/2.2.x/STATUS Mon Feb 15 19:54:41 2010
@@ -87,17 +87,6 @@
PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
[ start all new proposals below, under PATCHES PROPOSED. ]
- * mod_proxy: Allow https to a remote forward proxy by issuing an HTTP
- CONNECT request. This adds a CONNECT client (sending a connect request).
- It is not the same as mod_proxy_connect, which is a CONNECT server
- (responding to connect requests).
- PR: https://issues.apache.org/bugzilla/show_bug.cgi?id=19188
- Trunk patches: http://svn.apache.org/viewvc?rev=909323&view=rev
- http://svn.apache.org/viewvc?rev=910079&view=rev
- http://svn.apache.org/viewvc?rev=910081&view=rev
- http://svn.apache.org/viewvc?rev=910124&view=rev
- 2.2.x patch: http://people.apache.org/~rjung/patches/bz19188-proxyremote-https-v2.patch
- +1: rjung, minfrin, jim
PATCHES PROPOSED TO BACKPORT FROM TRUNK:
Modified: httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy.xml?rev=910322&r1=910321&r2=910322&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy.xml (original)
+++ httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy.xml Mon Feb 15 19:54:41 2010
@@ -475,8 +475,9 @@
</example>
<p><var>scheme</var> is effectively the protocol that should be used to
- communicate with the remote server; only <code>http</code> is supported by
- this module.</p>
+ communicate with the remote server; only <code>http</code> and <code>https</code>
+ are supported by this module. When using <code>https</code>, the requests
+ are forwarded through the remote proxy using the HTTP CONNECT method.</p>
<example><title>Example</title>
ProxyRemote http://goodguys.example.com/ http://mirrorguys.example.com:8000<br />
Modified: httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy_connect.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy_connect.xml?rev=910322&r1=910321&r2=910322&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy_connect.xml (original)
+++ httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy_connect.xml Mon Feb 15 19:54:41 2010
@@ -39,6 +39,11 @@
requests, <module>mod_proxy</module> and
<module>mod_proxy_connect</module> have to be present in the server.</p>
+ <p>CONNECT is also used, when the server needs to send an HTTPS request
+ through a forward proxy. In this case the server acts as a CONNECT client.
+ This functionality is part of <module>mod_proxy</module> and
+ <module>mod_proxy_connect</module> is not needed in this case.</p>
+
<note type="warning"><title>Warning</title>
<p>Do not enable proxying until you have <a
href="mod_proxy.html#access">secured your server</a>. Open proxy
Modified: httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy_http.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy_http.xml?rev=910322&r1=910321&r2=910322&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy_http.xml (original)
+++ httpd/httpd/branches/2.2.x/docs/manual/mod/mod_proxy_http.xml Mon Feb 15 19:54:41 2010
@@ -32,7 +32,7 @@
<summary>
<p>This module <em>requires</em> the service of <module
>mod_proxy</module>. It provides the features used for
- proxying HTTP requests. <module>mod_proxy_http</module>
+ proxying HTTP and HTTPS requests. <module>mod_proxy_http</module>
supports HTTP/0.9, HTTP/1.0 and HTTP/1.1. It does <em>not</em>
provide any caching abilities. If you want to set up a caching
proxy, you might want to use the additional service of the
Modified: httpd/httpd/branches/2.2.x/include/ap_mmn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/include/ap_mmn.h?rev=910322&r1=910321&r2=910322&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/include/ap_mmn.h (original)
+++ httpd/httpd/branches/2.2.x/include/ap_mmn.h Mon Feb 15 19:54:41 2010
@@ -138,6 +138,7 @@
* 20051115.22 (2.2.12) Add ap_escape_html2 API, with additional option
* 20051115.23 (2.2.12) Add ap_open_piped_log_ex API, with cmdtype option,
* and conditional cmdtype member of piped_log struct
+ * 20051115.24 (2.2.15) Add forward member to proxy_conn_rec
*/
#define MODULE_MAGIC_COOKIE 0x41503232UL /* "AP22" */
@@ -145,7 +146,7 @@
#ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 20051115
#endif
-#define MODULE_MAGIC_NUMBER_MINOR 23 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 24 /* 0...n */
/**
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
Modified: httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.h
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.h?rev=910322&r1=910321&r2=910322&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.h (original)
+++ httpd/httpd/branches/2.2.x/modules/proxy/mod_proxy.h Mon Feb 15 19:54:41 2010
@@ -247,6 +247,7 @@
* which the backend currently answers. */
int need_flush;/* Flag to decide whether we need to flush the
* filter chain or not */
+ void *forward; /* opaque forward proxy data */
} proxy_conn_rec;
typedef struct {
Modified: httpd/httpd/branches/2.2.x/modules/proxy/proxy_util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/modules/proxy/proxy_util.c?rev=910322&r1=910321&r2=910322&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/modules/proxy/proxy_util.c (original)
+++ httpd/httpd/branches/2.2.x/modules/proxy/proxy_util.c Mon Feb 15 19:54:41 2010
@@ -29,6 +29,18 @@
#define apr_socket_create apr_socket_create_ex
#endif
+/*
+ * Opaque structure containing target server info when
+ * using a forward proxy.
+ * Up to now only used in combination with HTTP CONNECT.
+ */
+typedef struct {
+ int use_http_connect; /* Use SSL Tunneling via HTTP CONNECT */
+ const char *target_host; /* Target hostname */
+ apr_port_t target_port; /* Target port */
+ const char *proxy_auth; /* Proxy authorization */
+} forward_info;
+
/* Global balancer counter */
int PROXY_DECLARE_DATA proxy_lb_workers = 0;
static int lb_workers_limit = 0;
@@ -2085,6 +2097,34 @@
if (proxyname) {
conn->hostname = apr_pstrdup(conn->pool, proxyname);
conn->port = proxyport;
+ /*
+ * If we have a forward proxy and the protocol is HTTPS,
+ * then we need to prepend a HTTP CONNECT request before
+ * sending our actual HTTPS requests.
+ * Save our real backend data for using it later during HTTP CONNECT.
+ */
+ if (conn->is_ssl) {
+ const char *proxy_auth;
+
+ forward_info *forward = apr_pcalloc(conn->pool, sizeof(forward_info));
+ conn->forward = forward;
+ forward->use_http_connect = 1;
+ forward->target_host = apr_pstrdup(conn->pool, uri->hostname);
+ forward->target_port = uri->port;
+ /* Do we want to pass Proxy-Authorization along?
+ * If we haven't used it, then YES
+ * If we have used it then MAYBE: RFC2616 says we MAY propagate it.
+ * So let's make it configurable by env.
+ * The logic here is the same used in mod_proxy_http.
+ */
+ proxy_auth = apr_table_get(r->headers_in, "Proxy-Authorization");
+ if (proxy_auth != NULL &&
+ proxy_auth[0] != '\0' &&
+ r->user == NULL && /* we haven't yet authenticated */
+ apr_table_get(r->subprocess_env, "Proxy-Chain-Auth")) {
+ forward->proxy_auth = apr_pstrdup(conn->pool, proxy_auth);
+ }
+ }
}
else {
conn->hostname = apr_pstrdup(conn->pool, uri->hostname);
@@ -2224,6 +2264,102 @@
}
#endif /* USE_ALTERNATE_IS_CONNECTED */
+
+/*
+ * Send a HTTP CONNECT request to a forward proxy.
+ * The proxy is given by "backend", the target server
+ * is contained in the "forward" member of "backend".
+ */
+static apr_status_t send_http_connect(proxy_conn_rec *backend,
+ server_rec *s)
+{
+ int status;
+ apr_size_t nbytes;
+ apr_size_t left;
+ int complete = 0;
+ char buffer[HUGE_STRING_LEN];
+ char drain_buffer[HUGE_STRING_LEN];
+ forward_info *forward = (forward_info *)backend->forward;
+ int len = 0;
+
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ "proxy: CONNECT: sending the CONNECT request for %s:%d "
+ "to the remote proxy %pI (%s)",
+ forward->target_host, forward->target_port,
+ backend->addr, backend->hostname);
+ /* Create the CONNECT request */
+ nbytes = apr_snprintf(buffer, sizeof(buffer),
+ "CONNECT %s:%d HTTP/1.0" CRLF,
+ forward->target_host, forward->target_port);
+ /* Add proxy authorization from the initial request if necessary */
+ if (forward->proxy_auth != NULL) {
+ nbytes += apr_snprintf(buffer + nbytes, sizeof(buffer) - nbytes,
+ "Proxy-Authorization: %s" CRLF,
+ forward->proxy_auth);
+ }
+ /* Set a reasonable agent and send everything */
+ nbytes += apr_snprintf(buffer + nbytes, sizeof(buffer) - nbytes,
+ "Proxy-agent: %s" CRLF CRLF,
+ ap_get_server_banner());
+ apr_socket_send(backend->sock, buffer, &nbytes);
+
+ /* Receive the whole CONNECT response */
+ left = sizeof(buffer) - 1;
+ /* Read until we find the end of the headers or run out of buffer */
+ do {
+ nbytes = left;
+ status = apr_socket_recv(backend->sock, buffer + len, &nbytes);
+ len += nbytes;
+ left -= nbytes;
+ buffer[len] = '\0';
+ if (strstr(buffer + len - nbytes, "\r\n\r\n") != NULL) {
+ complete = 1;
+ break;
+ }
+ } while (status == APR_SUCCESS && left > 0);
+ /* Drain what's left */
+ if (!complete) {
+ nbytes = sizeof(drain_buffer) - 1;
+ while (status == APR_SUCCESS && nbytes) {
+ status = apr_socket_recv(backend->sock, drain_buffer, &nbytes);
+ buffer[nbytes] = '\0';
+ nbytes = sizeof(drain_buffer) - 1;
+ if (strstr(drain_buffer, "\r\n\r\n") != NULL) {
+ complete = 1;
+ break;
+ }
+ }
+ }
+
+ /* Check for HTTP_OK response status */
+ if (status == APR_SUCCESS) {
+ int major, minor;
+ /* Only scan for three character status code */
+ char code_str[4];
+
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ "send_http_connect: response from the forward proxy: %s",
+ buffer);
+
+ /* Extract the returned code */
+ if (sscanf(buffer, "HTTP/%u.%u %3s", &major, &minor, code_str) == 3) {
+ status = atoi(code_str);
+ if (status == HTTP_OK) {
+ status = APR_SUCCESS;
+ }
+ else {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ "send_http_connect: the forward proxy returned code is '%s'",
+ code_str);
+ status = APR_INCOMPLETE;
+ }
+ }
+ }
+
+ return(status);
+}
+
+
PROXY_DECLARE(int) ap_proxy_connect_backend(const char *proxy_function,
proxy_conn_rec *conn,
proxy_worker *worker,
@@ -2336,7 +2472,33 @@
apr_socket_timeout_set(newsock, s->timeout);
}
- conn->sock = newsock;
+ conn->sock = newsock;
+
+ if (conn->forward) {
+ forward_info *forward = (forward_info *)conn->forward;
+ /*
+ * For HTTP CONNECT we need to prepend CONNECT request before
+ * sending our actual HTTPS requests.
+ */
+ if (forward->use_http_connect) {
+ rv = send_http_connect(conn, s);
+ /* If an error occurred, loop round and try again */
+ if (rv != APR_SUCCESS) {
+ conn->sock = NULL;
+ apr_socket_close(newsock);
+ loglevel = backend_addr->next ? APLOG_DEBUG : APLOG_ERR;
+ ap_log_error(APLOG_MARK, loglevel, rv, s,
+ "proxy: %s: attempt to connect to %s:%d "
+ "via http CONNECT through %pI (%s) failed",
+ proxy_function,
+ forward->target_host, forward->target_port,
+ backend_addr, worker->hostname);
+ backend_addr = backend_addr->next;
+ continue;
+ }
+ }
+ }
+
connected = 1;
}
/*
@@ -2516,4 +2678,3 @@
}
return rv;
}
-
Re: svn commit: r910322 - in /httpd/httpd/branches/2.2.x: CHANGES STATUS docs/manual/mod/mod_proxy.xml docs/manual/mod/mod_proxy_connect.xml docs/manual/mod/mod_proxy_http.xml include/ap_mmn.h modules/proxy/mod_proxy.h modules/proxy/proxy_util.c
Posted by André Malo <nd...@perlig.de>.
* jim@apache.org wrote:
> Author: jim
> Date: Mon Feb 15 19:54:41 2010
> New Revision: 910322
>
> URL: http://svn.apache.org/viewvc?rev=910322&view=rev
> Log: (empty)
'nough said ;)
nd