Skip to content

Commit cb4dcd5

Browse files
authored
Merge pull request #174 from chobits/for_pull_request
Feature: modify CONNECT response via proxy_connect_response directive
2 parents 3cc43d0 + 2847f79 commit cb4dcd5

File tree

3 files changed

+113
-1
lines changed

3 files changed

+113
-1
lines changed

README.md

+42-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Table of Contents
2828
* [proxy_connect_send_timeout](#proxy_connect_send_timeout)
2929
* [proxy_connect_address](#proxy_connect_address)
3030
* [proxy_connect_bind](#proxy_connect_bind)
31+
* [proxy_connect_response](#proxy_connect_response)
3132
* [Variables](#variables)
3233
* [$connect_host](#connect_host)
3334
* [$connect_port](#connect_port)
@@ -37,7 +38,7 @@ Table of Contents
3738
* [$proxy_connect_send_timeout](#proxy_connect_send_timeout-1)
3839
* [$proxy_connect_resolve_time](#proxy_connect_resolve_time)
3940
* [$proxy_connect_connect_time](#proxy_connect_connect_time)
40-
* [$proxy_connect_response](#proxy_connect_response)
41+
* [$proxy_connect_response](#proxy_connect_response-1)
4142
* [Compatibility](#compatibility)
4243
* [Nginx Compatibility](#nginx-compatibility)
4344
* [OpenResty Compatibility](#openresty-compatibility)
@@ -367,6 +368,44 @@ In order for this parameter to work, it is usually necessary to run nginx worker
367368

368369
NOTE: If using `set $<nginx variable>` and `proxy_connect_bind $<nginx variable>` together, you should use `proxy_connect_rewrite.patch` instead, see [Install](#install) for more details.
369370

371+
proxy_connect_response
372+
----------------------
373+
374+
Syntax: **proxy_connect_response `CONNECT response`**
375+
Default: `HTTP/1.1 200 Connection Established\r\nProxy-agent: nginx\r\n\r\n`
376+
Context: `server`
377+
378+
Set the response of CONNECT request.
379+
380+
Note that it is only used for CONNECT request, it cannot modify the data flow over CONNECT tunnel.
381+
382+
For example:
383+
384+
```
385+
proxy_connect_response "HTTP/1.1 200 Connection Established\r\nProxy-agent: nginx\r\nX-Proxy-Connected-Addr: $connect_addr\r\n\r\n";
386+
387+
```
388+
389+
The `curl` command test case with above config is as following:
390+
391+
```
392+
$ curl https://github.com -sv -x localhost:3128
393+
* Connected to localhost (127.0.0.1) port 3128 (#0)
394+
* allocate connect buffer!
395+
* Establish HTTP proxy tunnel to github.com:443
396+
> CONNECT github.com:443 HTTP/1.1
397+
> Host: github.com:443
398+
> User-Agent: curl/7.64.1
399+
> Proxy-Connection: Keep-Alive
400+
>
401+
< HTTP/1.1 200 Connection Established --.
402+
< Proxy-agent: nginx | custom CONNECT response
403+
< X-Proxy-Connected-Addr: 13.229.188.59:443 --'
404+
...
405+
406+
```
407+
408+
370409
Variables
371410
=========
372411

@@ -465,6 +504,8 @@ rewrite_by_lua '
465504
';
466505
```
467506

507+
Also note that `set` or `rewrite_by_lua*` directive is run during the REWRITE phase, which is ahead of dns resolving phase. It cannot get right value of some variables, for example, `$connect_addr` value is `nil`. In such case, you should use [`proxy_connect_response` directive](#proxy_connect_response) instead.
508+
468509

469510
Compatibility
470511
=============

ngx_http_proxy_connect_module.c

+25
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ typedef struct {
3737

3838
ngx_http_complex_value_t *address;
3939
ngx_http_proxy_connect_address_t *local;
40+
41+
ngx_http_complex_value_t *response;
4042
} ngx_http_proxy_connect_loc_conf_t;
4143

4244

@@ -201,6 +203,12 @@ static ngx_command_t ngx_http_proxy_connect_commands[] = {
201203
offsetof(ngx_http_proxy_connect_loc_conf_t, local),
202204
NULL },
203205

206+
{ ngx_string("proxy_connect_response"),
207+
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
208+
ngx_http_set_complex_value_slot,
209+
NGX_HTTP_LOC_CONF_OFFSET,
210+
offsetof(ngx_http_proxy_connect_loc_conf_t, response),
211+
NULL },
204212

205213
ngx_null_command
206214
};
@@ -530,6 +538,23 @@ ngx_http_proxy_connect_send_connection_established(ngx_http_request_t *r)
530538

531539
b = &ctx->buf;
532540

541+
/* modify CONNECT response via proxy_connect_response directive */
542+
{
543+
ngx_str_t resp;
544+
ngx_http_proxy_connect_loc_conf_t *plcf;
545+
546+
plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_connect_module);
547+
548+
if (plcf->response
549+
&& ngx_http_complex_value(r, plcf->response, &resp) == NGX_OK)
550+
{
551+
if (resp.len > 0) {
552+
b->pos = resp.data;
553+
b->last = b->pos + resp.len;
554+
}
555+
}
556+
}
557+
533558
ctx->send_established = 1;
534559

535560
for (;;) {

t/http_proxy_connect.t

+46
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,52 @@ if ($test_enable_rewrite_phase) {
346346

347347
$t->stop();
348348

349+
###############################################################################
350+
351+
$t->write_file_expand('nginx.conf', <<'EOF');
352+
353+
%%TEST_GLOBALS%%
354+
355+
daemon off;
356+
357+
events {
358+
}
359+
360+
http {
361+
%%TEST_GLOBALS_HTTP%%
362+
363+
access_log off;
364+
365+
resolver 127.0.0.1:18085 ipv6=off; # NOTE: cannot connect ipv6 address ::1 in mac os x.
366+
367+
server {
368+
listen 127.0.0.1:8080;
369+
proxy_connect;
370+
proxy_connect_allow all;
371+
372+
proxy_connect_response "HTTP/1.1 200 Connection Established\r\nProxy-agent: nginx\r\nX-Proxy-Connected-Addr: $connect_addr\r\n\r\n";
373+
}
374+
375+
server {
376+
listen 8081;
377+
location / {
378+
return 200 "backend";
379+
}
380+
}
381+
}
382+
383+
EOF
384+
385+
# test proxy_connect_response directive
386+
387+
$t->run();
388+
389+
if ($test_enable_rewrite_phase) {
390+
like(http_connect_request('set-response-header.com', '8081', '/'), qr/X-Proxy-Connected-Addr: 127.0.0.1:8081\r/, 'added header "Foo: bar" to CONNECT response');
391+
}
392+
393+
$t->stop();
394+
349395

350396

351397
# --- stop DNS server ---

0 commit comments

Comments
 (0)