Skip to content

Commit 6138510

Browse files
feat(proxy-wasm) new 'request.is_subrequest' property
Introduce a new request property `request.is_subrequest` to indicate whether the current request is a subrequest of an existing request (e.g. in slicing scenarios). Note: although the property uses the `request.*` prefix, this is not an Envoy-supported attribute. See #658. Co-Authored-By: Thibault Charbonnier <[email protected]>
1 parent 1ec8c84 commit 6138510

File tree

4 files changed

+83
-29
lines changed

4 files changed

+83
-29
lines changed

docs/PROXY_WASM.md

+1
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,7 @@ implementation state in ngx_wasm_module:
712712
`request.size` | :heavy_check_mark: | :x: | Maps to [ngx.content_length](https://nginx.org/en/docs/http/ngx_http_core_module.html#content_length).
713713
`request.total_size` | :heavy_check_mark: | :x: | Maps to [ngx.request_length](https://nginx.org/en/docs/http/ngx_http_core_module.html#request_length).
714714
`request.headers.*` | :heavy_check_mark: | :x: | Returns the value of any request header, e.g. `request.headers.date`.
715+
`request.is_subrequest` | :heavy_check_mark: | :x: | An ngx_wasm_module extension indicating whether the current request is a subrequest as a `"true"/"false"` string.
715716
*Response properties* | |
716717
`response.code` | :heavy_check_mark: | :x: | Maps to [ngx.status](https://nginx.org/en/docs/http/ngx_http_core_module.html#status).
717718
`response.size` | :heavy_check_mark: | :x: | Maps to [ngx.body_bytes_sent](https://nginx.org/en/docs/http/ngx_http_core_module.html#body_bytes_sent).

src/common/proxy_wasm/ngx_proxy_wasm_properties.c

+46-22
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,22 @@ static const char *ngx_prefix = "ngx.";
4141
static const size_t ngx_prefix_len = 4;
4242

4343

44+
static const char *host_prefix =
45+
NGX_WASM_HOST_PROPERTY_NAMESPACE_STR ".";
46+
static size_t host_prefix_len;
47+
48+
49+
#ifdef NGX_WASM_HTTP
50+
static ngx_str_t str_on = ngx_string("true");
51+
static ngx_str_t str_off = ngx_string("false");
52+
#endif
53+
54+
4455
static ngx_hash_init_t pwm2ngx_init;
4556
static ngx_hash_combined_t pwm2ngx_hash;
4657
static ngx_hash_keys_arrays_t pwm2ngx_keys;
4758

4859

49-
static const char *host_prefix = NGX_WASM_HOST_PROPERTY_NAMESPACE_STR ".";
50-
static size_t host_prefix_len;
51-
52-
5360
typedef struct {
5461
ngx_str_node_t sn;
5562
ngx_str_t value;
@@ -171,6 +178,37 @@ get_request_time(ngx_proxy_wasm_ctx_t *pwctx, ngx_str_t *path,
171178
}
172179

173180

181+
static ngx_int_t
182+
get_request_header(ngx_proxy_wasm_ctx_t *pwctx, ngx_str_t *path,
183+
ngx_str_t *value)
184+
{
185+
ngx_str_t name;
186+
187+
name.data = (u_char *) (path->data + request_headers_prefix_len);
188+
name.len = path->len - request_headers_prefix_len;
189+
190+
return get_map_value(pwctx, &name, value,
191+
NGX_PROXY_WASM_MAP_HTTP_REQUEST_HEADERS);
192+
}
193+
194+
195+
static ngx_int_t
196+
is_subrequest(ngx_proxy_wasm_ctx_t *pwctx, ngx_str_t *path,
197+
ngx_str_t *value)
198+
{
199+
ngx_str_t *result;
200+
ngx_http_wasm_req_ctx_t *rctx = pwctx->data;
201+
ngx_http_request_t *r = rctx->r;
202+
203+
result = r != r->main ? &str_on : &str_off;
204+
205+
value->data = result->data;
206+
value->len = result->len;
207+
208+
return NGX_OK;
209+
}
210+
211+
174212
static ngx_int_t
175213
get_upstream_address(ngx_proxy_wasm_ctx_t *pwctx, ngx_str_t *path,
176214
ngx_str_t *value)
@@ -243,20 +281,6 @@ get_upstream_port(ngx_proxy_wasm_ctx_t *pwctx, ngx_str_t *path,
243281
}
244282

245283

246-
static ngx_int_t
247-
get_request_header(ngx_proxy_wasm_ctx_t *pwctx, ngx_str_t *path,
248-
ngx_str_t *value)
249-
{
250-
ngx_str_t name;
251-
252-
name.data = (u_char *) (path->data + request_headers_prefix_len);
253-
name.len = path->len - request_headers_prefix_len;
254-
255-
return get_map_value(pwctx, &name, value,
256-
NGX_PROXY_WASM_MAP_HTTP_REQUEST_HEADERS);
257-
}
258-
259-
260284
static ngx_int_t
261285
get_response_header(ngx_proxy_wasm_ctx_t *pwctx, ngx_str_t *path,
262286
ngx_str_t *value)
@@ -313,9 +337,6 @@ get_connection_mtls(ngx_proxy_wasm_ctx_t *pwctx, ngx_str_t *path,
313337
static ngx_str_t verify_p = ngx_string("ngx.ssl_client_verify");
314338
static ngx_str_t verify_e = ngx_string("SUCCESS");
315339

316-
static ngx_str_t mtls_on = ngx_string("true");
317-
static ngx_str_t mtls_off = ngx_string("false");
318-
319340
if (!pwctx->mtls.len) {
320341
rc = ngx_proxy_wasm_properties_get_ngx(pwctx, &https_p, &https_v);
321342
if (rc != NGX_OK) {
@@ -331,7 +352,7 @@ get_connection_mtls(ngx_proxy_wasm_ctx_t *pwctx, ngx_str_t *path,
331352
&& ngx_str_eq(verify_v.data, verify_v.len,
332353
verify_e.data, verify_e.len);
333354

334-
result = on ? &mtls_on : &mtls_off;
355+
result = on ? &str_on : &str_off;
335356

336357
pwctx->mtls.data = ngx_pnalloc(pwctx->pool, result->len);
337358
if (pwctx->mtls.data == NULL) {
@@ -472,6 +493,9 @@ static pwm2ngx_mapping_t pw2ngx[] = {
472493
{ ngx_string("request.headers.*"),
473494
ngx_null_string,
474495
&get_request_header, NULL },
496+
{ ngx_string("request.is_subrequest"),
497+
ngx_null_string,
498+
&is_subrequest, NULL },
475499

476500
/* Response properties */
477501

t/03-proxy_wasm/hfuncs/117-proxy_properties_get.t

+35-7
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ our $request_properties = join(',', qw(
1919
request.duration
2020
request.size
2121
request.total_size
22+
request.is_subrequest
2223
));
2324

2425
plan_tests(5);
@@ -63,7 +64,8 @@ request\.protocol: HTTP\/1\.1 at RequestHeaders
6364
request\.query: special_arg\=true\&special_arg2\=false at RequestHeaders
6465
request\.duration: \d+\.\d+ at RequestHeaders
6566
request\.size: 5 at RequestHeaders
66-
request\.total_size: 187 at RequestHeaders/
67+
request\.total_size: 187 at RequestHeaders
68+
request\.is_subrequest: false at RequestHeaders/
6769
--- no_error_log
6870
[error]
6971
[crit]
@@ -151,7 +153,8 @@ request.method: GET at OnHttpCallResponse
151153
request.time: \d+\.\d+ at OnHttpCallResponse
152154
request.protocol: HTTP\/1\.1 at OnHttpCallResponse
153155
request.query: hello\=world at OnHttpCallResponse
154-
request.total_size: [1-9]+[0-9]+ at OnHttpCallResponse/
156+
request.total_size: [1-9]+[0-9]+ at OnHttpCallResponse
157+
request.is_subrequest: false at OnHttpCallResponse/
155158
--- no_error_log
156159
[error]
157160
[crit]
@@ -667,7 +670,32 @@ qr/"response.code_details" property not supported
667670
668671
669672
670-
=== TEST 15: proxy_wasm - get_property() - unknown property on: request_headers
673+
=== TEST 15: proxy_wasm - get_property() - request.is_subrequest on: request_headers
674+
--- load_nginx_modules: ngx_http_echo_module
675+
--- wasm_modules: hostcalls
676+
--- config
677+
location /t {
678+
echo_subrequest GET '/sub';
679+
}
680+
681+
location /sub {
682+
proxy_wasm hostcalls 'on=request_headers \
683+
test=/t/log/properties \
684+
name=request.is_subrequest';
685+
echo ok;
686+
}
687+
--- response_body
688+
ok
689+
--- grep_error_log eval: qr/request\.is_subrequest: (true|false) at \w+/
690+
--- grep_error_log_out eval
691+
qr/request\.is_subrequest: true at RequestHeaders/
692+
--- no_error_log
693+
[error]
694+
[crit]
695+
696+
697+
698+
=== TEST 16: proxy_wasm - get_property() - unknown property on: request_headers
671699
--- wasm_modules: hostcalls
672700
--- load_nginx_modules: ngx_http_echo_module
673701
--- config
@@ -686,7 +714,7 @@ qr/\[info\] .*? property not found: nonexistent_property,/
686714
687715
688716
689-
=== TEST 16: proxy_wasm - get_property() request.* - not available on: tick (isolation: global)
717+
=== TEST 17: proxy_wasm - get_property() request.* - not available on: tick (isolation: global)
690718
--- skip_hup
691719
--- wasm_modules: hostcalls
692720
--- load_nginx_modules: ngx_http_echo_module
@@ -709,7 +737,7 @@ qr/\[info\] .*? property not found: nonexistent_property,/
709737
710738
711739
712-
=== TEST 17: proxy_wasm - get_property() response.* - not available on: tick (isolation: global)
740+
=== TEST 18: proxy_wasm - get_property() response.* - not available on: tick (isolation: global)
713741
--- skip_hup
714742
--- wasm_modules: hostcalls
715743
--- load_nginx_modules: ngx_http_echo_module
@@ -732,7 +760,7 @@ qr/\[info\] .*? property not found: nonexistent_property,/
732760
733761
734762
735-
=== TEST 18: proxy_wasm - get_property() upstream.* - not available on: tick (isolation: global)
763+
=== TEST 19: proxy_wasm - get_property() upstream.* - not available on: tick (isolation: global)
736764
--- skip_hup
737765
--- wasm_modules: hostcalls
738766
--- load_nginx_modules: ngx_http_echo_module
@@ -755,7 +783,7 @@ qr/\[info\] .*? property not found: nonexistent_property,/
755783
756784
757785
758-
=== TEST 19: proxy_wasm - get_property() upstream.* - not available on: configure (isolation: global)
786+
=== TEST 20: proxy_wasm - get_property() upstream.* - not available on: configure (isolation: global)
759787
--- skip_hup
760788
--- wasm_modules: hostcalls
761789
--- load_nginx_modules: ngx_http_echo_module

t/lib/proxy-wasm-tests/hostcalls/src/filter.rs

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ impl Context for TestHttp {
4444
"request.protocol",
4545
"request.query",
4646
"request.total_size",
47+
"request.is_subrequest",
4748
];
4849

4950
for property in properties {

0 commit comments

Comments
 (0)