File proxy_connect_rewrite_102101.patch of Package nginx
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index c7463dc..41a0a7a 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -957,6 +957,14 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
r->content_handler = NULL;
r->uri_changed = 0;
+#if (NGX_HTTP_PROXY_CONNECT)
+ if (r->method == NGX_HTTP_CONNECT) {
+ ngx_http_update_location_config(r);
+ r->phase_handler++;
+ return NGX_AGAIN;
+ }
+#endif
+
rc = ngx_http_core_find_location(r);
if (rc == NGX_ERROR) {
diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c
index 6460da2..7b209fa 100644
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -107,6 +107,14 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
enum {
sw_start = 0,
sw_method,
+#if (NGX_HTTP_PROXY_CONNECT)
+ sw_spaces_before_connect_host,
+ sw_connect_host_start,
+ sw_connect_host,
+ sw_connect_host_end,
+ sw_connect_host_ip_literal,
+ sw_connect_port,
+#endif
sw_spaces_before_uri,
sw_schema,
sw_schema_slash,
@@ -270,6 +278,13 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
}
state = sw_spaces_before_uri;
+
+#if (NGX_HTTP_PROXY_CONNECT)
+ if (r->method == NGX_HTTP_CONNECT) {
+ state = sw_spaces_before_connect_host;
+ }
+#endif
+
break;
}
@@ -279,6 +294,111 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
break;
+#if (NGX_HTTP_PROXY_CONNECT)
+ case sw_spaces_before_connect_host:
+
+ if (ch == ' ') {
+ break;
+ }
+
+ /* fall through */
+
+ case sw_connect_host_start:
+
+ r->connect_host_start = p;
+
+ if (ch == '[') {
+ state = sw_connect_host_ip_literal;
+ break;
+ }
+
+ state = sw_connect_host;
+
+ /* fall through */
+
+ case sw_connect_host:
+
+ c = (u_char) (ch | 0x20);
+ if (c >= 'a' && c <= 'z') {
+ break;
+ }
+
+ if ((ch >= '0' && ch <= '9') || ch == '.' || ch == '-') {
+ break;
+ }
+
+ /* fall through */
+
+ case sw_connect_host_end:
+
+ r->connect_host_end = p;
+
+ switch (ch) {
+ case ':':
+ state = sw_connect_port;
+ break;
+ default:
+ return NGX_HTTP_PARSE_INVALID_REQUEST;
+ }
+ break;
+
+ case sw_connect_host_ip_literal:
+
+ if (ch >= '0' && ch <= '9') {
+ break;
+ }
+
+ c = (u_char) (ch | 0x20);
+ if (c >= 'a' && c <= 'z') {
+ break;
+ }
+
+ switch (ch) {
+ case ':':
+ break;
+ case ']':
+ state = sw_connect_host_end;
+ break;
+ case '-':
+ case '.':
+ case '_':
+ case '~':
+ /* unreserved */
+ break;
+ case '!':
+ case '$':
+ case '&':
+ case '\'':
+ case '(':
+ case ')':
+ case '*':
+ case '+':
+ case ',':
+ case ';':
+ case '=':
+ /* sub-delims */
+ break;
+ default:
+ return NGX_HTTP_PARSE_INVALID_REQUEST;
+ }
+ break;
+
+ case sw_connect_port:
+ if (ch >= '0' && ch <= '9') {
+ break;
+ }
+
+ switch (ch) {
+ case ' ':
+ r->connect_port_end = p;
+ state = sw_http_09;
+ break;
+ default:
+ return NGX_HTTP_PARSE_INVALID_REQUEST;
+ }
+ break;
+#endif
+
/* space* before URI */
case sw_spaces_before_uri:
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 013b715..f4fa0a4 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1102,6 +1102,55 @@ ngx_http_process_request_line(ngx_event_t *rev)
r->http_protocol.len = r->request_end - r->http_protocol.data;
}
+#if (NGX_HTTP_PROXY_CONNECT)
+
+ if (r->connect_host_start && r->connect_host_end) {
+
+ host.len = r->connect_host_end - r->connect_host_start;
+ host.data = r->connect_host_start;
+ rc = ngx_http_validate_host(&host, r->pool, 0);
+
+ if (rc == NGX_DECLINED) {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "client sent invalid host in request line");
+ ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+ return;
+ }
+
+ if (rc == NGX_ERROR) {
+ ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ r->connect_host = host;
+
+ if (!r->connect_port_end) {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "client sent no port in request line");
+ ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+ return;
+ }
+
+ r->connect_port.data = r->connect_host_end + 1;
+ r->connect_port.len = r->connect_port_end
+ - r->connect_host_end - 1;
+
+ ngx_int_t port;
+
+ port = ngx_atoi(r->connect_port.data, r->connect_port.len);
+ if (port == NGX_ERROR || port < 1 || port > 65535) {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "client sent invalid port in request line");
+ ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+ return;
+ }
+
+ r->connect_port_n = port;
+
+ /* skip processing request uri */
+ } else
+#endif
+
if (ngx_http_process_request_uri(r) != NGX_OK) {
break;
}
@@ -1697,6 +1746,19 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
r->schema_end = new + (r->schema_end - old);
}
+#if (NGX_HTTP_PROXY_CONNECT)
+ if (r->connect_host_start) {
+ r->connect_host_start = new + (r->connect_host_start - old);
+ if (r->connect_host_end) {
+ r->connect_host_end = new + (r->connect_host_end - old);
+ }
+
+ if (r->connect_port_end) {
+ r->connect_port_end = new + (r->connect_port_end - old);
+ }
+ }
+#endif
+
if (r->host_start) {
r->host_start = new + (r->host_start - old);
if (r->host_end) {
@@ -2011,13 +2073,6 @@ ngx_http_process_request_header(ngx_http_request_t *r)
}
}
- if (r->method == NGX_HTTP_CONNECT) {
- ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
- "client sent CONNECT method");
- ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
- return NGX_ERROR;
- }
-
if (r->method == NGX_HTTP_TRACE) {
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent TRACE method");
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index b1269d2..a68bd03 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -414,6 +414,15 @@ struct ngx_http_request_s {
ngx_str_t exten;
ngx_str_t unparsed_uri;
+#if (NGX_HTTP_PROXY_CONNECT)
+ ngx_str_t connect_host;
+ ngx_str_t connect_port;
+ in_port_t connect_port_n;
+ u_char *connect_host_start;
+ u_char *connect_host_end;
+ u_char *connect_port_end;
+#endif
+
ngx_str_t method_name;
ngx_str_t http_protocol;
ngx_str_t schema;
diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c
index 942dacd..6c59d6a 100644
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -163,6 +163,14 @@ static ngx_int_t ngx_http_variable_time_local(ngx_http_request_t *r,
static ngx_http_variable_t ngx_http_core_variables[] = {
+#if (NGX_HTTP_PROXY_CONNECT)
+ { ngx_string("connect_host"), NULL, ngx_http_variable_request,
+ offsetof(ngx_http_request_t, connect_host), 0, 0 },
+
+ { ngx_string("connect_port"), NULL, ngx_http_variable_request,
+ offsetof(ngx_http_request_t, connect_port), 0, 0 },
+#endif
+
{ ngx_string("http_host"), NULL, ngx_http_variable_header,
offsetof(ngx_http_request_t, headers_in.host), 0, 0 },