Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MERGE] feat(proxy-wasm) new 'request.is_subrequest' property #666

Merged
merged 1 commit into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/PROXY_WASM.md
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,7 @@ implementation state in ngx_wasm_module:
`request.size` | :heavy_check_mark: | :x: | Maps to [ngx.content_length](https://nginx.org/en/docs/http/ngx_http_core_module.html#content_length).
`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).
`request.headers.*` | :heavy_check_mark: | :x: | Returns the value of any request header, e.g. `request.headers.date`.
`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.
*Response properties* | |
`response.code` | :heavy_check_mark: | :x: | Maps to [ngx.status](https://nginx.org/en/docs/http/ngx_http_core_module.html#status).
`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).
Expand Down
68 changes: 46 additions & 22 deletions src/common/proxy_wasm/ngx_proxy_wasm_properties.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,22 @@ static const char *ngx_prefix = "ngx.";
static const size_t ngx_prefix_len = 4;


static const char *host_prefix =
NGX_WASM_HOST_PROPERTY_NAMESPACE_STR ".";
static size_t host_prefix_len;


#ifdef NGX_WASM_HTTP
static ngx_str_t str_on = ngx_string("true");
static ngx_str_t str_off = ngx_string("false");
#endif


static ngx_hash_init_t pwm2ngx_init;
static ngx_hash_combined_t pwm2ngx_hash;
static ngx_hash_keys_arrays_t pwm2ngx_keys;


static const char *host_prefix = NGX_WASM_HOST_PROPERTY_NAMESPACE_STR ".";
static size_t host_prefix_len;


typedef struct {
ngx_str_node_t sn;
ngx_str_t value;
Expand Down Expand Up @@ -171,6 +178,37 @@ get_request_time(ngx_proxy_wasm_ctx_t *pwctx, ngx_str_t *path,
}


static ngx_int_t
get_request_header(ngx_proxy_wasm_ctx_t *pwctx, ngx_str_t *path,
ngx_str_t *value)
{
ngx_str_t name;

name.data = (u_char *) (path->data + request_headers_prefix_len);
name.len = path->len - request_headers_prefix_len;

return get_map_value(pwctx, &name, value,
NGX_PROXY_WASM_MAP_HTTP_REQUEST_HEADERS);
}


static ngx_int_t
is_subrequest(ngx_proxy_wasm_ctx_t *pwctx, ngx_str_t *path,
ngx_str_t *value)
{
ngx_str_t *result;
ngx_http_wasm_req_ctx_t *rctx = pwctx->data;
ngx_http_request_t *r = rctx->r;

result = r != r->main ? &str_on : &str_off;

value->data = result->data;
value->len = result->len;

return NGX_OK;
}


static ngx_int_t
get_upstream_address(ngx_proxy_wasm_ctx_t *pwctx, ngx_str_t *path,
ngx_str_t *value)
Expand Down Expand Up @@ -243,20 +281,6 @@ get_upstream_port(ngx_proxy_wasm_ctx_t *pwctx, ngx_str_t *path,
}


static ngx_int_t
get_request_header(ngx_proxy_wasm_ctx_t *pwctx, ngx_str_t *path,
ngx_str_t *value)
{
ngx_str_t name;

name.data = (u_char *) (path->data + request_headers_prefix_len);
name.len = path->len - request_headers_prefix_len;

return get_map_value(pwctx, &name, value,
NGX_PROXY_WASM_MAP_HTTP_REQUEST_HEADERS);
}


static ngx_int_t
get_response_header(ngx_proxy_wasm_ctx_t *pwctx, ngx_str_t *path,
ngx_str_t *value)
Expand Down Expand Up @@ -313,9 +337,6 @@ get_connection_mtls(ngx_proxy_wasm_ctx_t *pwctx, ngx_str_t *path,
static ngx_str_t verify_p = ngx_string("ngx.ssl_client_verify");
static ngx_str_t verify_e = ngx_string("SUCCESS");

static ngx_str_t mtls_on = ngx_string("true");
static ngx_str_t mtls_off = ngx_string("false");

if (!pwctx->mtls.len) {
rc = ngx_proxy_wasm_properties_get_ngx(pwctx, &https_p, &https_v);
if (rc != NGX_OK) {
Expand All @@ -331,7 +352,7 @@ get_connection_mtls(ngx_proxy_wasm_ctx_t *pwctx, ngx_str_t *path,
&& ngx_str_eq(verify_v.data, verify_v.len,
verify_e.data, verify_e.len);

result = on ? &mtls_on : &mtls_off;
result = on ? &str_on : &str_off;

pwctx->mtls.data = ngx_pnalloc(pwctx->pool, result->len);
if (pwctx->mtls.data == NULL) {
Expand Down Expand Up @@ -472,6 +493,9 @@ static pwm2ngx_mapping_t pw2ngx[] = {
{ ngx_string("request.headers.*"),
ngx_null_string,
&get_request_header, NULL },
{ ngx_string("request.is_subrequest"),
ngx_null_string,
&is_subrequest, NULL },

/* Response properties */

Expand Down
42 changes: 35 additions & 7 deletions t/03-proxy_wasm/hfuncs/117-proxy_properties_get.t
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ our $request_properties = join(',', qw(
request.duration
request.size
request.total_size
request.is_subrequest
));

plan_tests(5);
Expand Down Expand Up @@ -63,7 +64,8 @@ request\.protocol: HTTP\/1\.1 at RequestHeaders
request\.query: special_arg\=true\&special_arg2\=false at RequestHeaders
request\.duration: \d+\.\d+ at RequestHeaders
request\.size: 5 at RequestHeaders
request\.total_size: 187 at RequestHeaders/
request\.total_size: 187 at RequestHeaders
request\.is_subrequest: false at RequestHeaders/
--- no_error_log
[error]
[crit]
Expand Down Expand Up @@ -151,7 +153,8 @@ request.method: GET at OnHttpCallResponse
request.time: \d+\.\d+ at OnHttpCallResponse
request.protocol: HTTP\/1\.1 at OnHttpCallResponse
request.query: hello\=world at OnHttpCallResponse
request.total_size: [1-9]+[0-9]+ at OnHttpCallResponse/
request.total_size: [1-9]+[0-9]+ at OnHttpCallResponse
request.is_subrequest: false at OnHttpCallResponse/
--- no_error_log
[error]
[crit]
Expand Down Expand Up @@ -667,7 +670,32 @@ qr/"response.code_details" property not supported



=== TEST 15: proxy_wasm - get_property() - unknown property on: request_headers
=== TEST 15: proxy_wasm - get_property() - request.is_subrequest on: request_headers
--- load_nginx_modules: ngx_http_echo_module
--- wasm_modules: hostcalls
--- config
location /t {
echo_subrequest GET '/sub';
}

location /sub {
proxy_wasm hostcalls 'on=request_headers \
test=/t/log/properties \
name=request.is_subrequest';
echo ok;
}
--- response_body
ok
--- grep_error_log eval: qr/request\.is_subrequest: (true|false) at \w+/
--- grep_error_log_out eval
qr/request\.is_subrequest: true at RequestHeaders/
--- no_error_log
[error]
[crit]



=== TEST 16: proxy_wasm - get_property() - unknown property on: request_headers
--- wasm_modules: hostcalls
--- load_nginx_modules: ngx_http_echo_module
--- config
Expand All @@ -686,7 +714,7 @@ qr/\[info\] .*? property not found: nonexistent_property,/



=== TEST 16: proxy_wasm - get_property() request.* - not available on: tick (isolation: global)
=== TEST 17: proxy_wasm - get_property() request.* - not available on: tick (isolation: global)
--- skip_hup
--- wasm_modules: hostcalls
--- load_nginx_modules: ngx_http_echo_module
Expand All @@ -709,7 +737,7 @@ qr/\[info\] .*? property not found: nonexistent_property,/



=== TEST 17: proxy_wasm - get_property() response.* - not available on: tick (isolation: global)
=== TEST 18: proxy_wasm - get_property() response.* - not available on: tick (isolation: global)
--- skip_hup
--- wasm_modules: hostcalls
--- load_nginx_modules: ngx_http_echo_module
Expand All @@ -732,7 +760,7 @@ qr/\[info\] .*? property not found: nonexistent_property,/



=== TEST 18: proxy_wasm - get_property() upstream.* - not available on: tick (isolation: global)
=== TEST 19: proxy_wasm - get_property() upstream.* - not available on: tick (isolation: global)
--- skip_hup
--- wasm_modules: hostcalls
--- load_nginx_modules: ngx_http_echo_module
Expand All @@ -755,7 +783,7 @@ qr/\[info\] .*? property not found: nonexistent_property,/



=== TEST 19: proxy_wasm - get_property() upstream.* - not available on: configure (isolation: global)
=== TEST 20: proxy_wasm - get_property() upstream.* - not available on: configure (isolation: global)
--- skip_hup
--- wasm_modules: hostcalls
--- load_nginx_modules: ngx_http_echo_module
Expand Down
1 change: 1 addition & 0 deletions t/lib/proxy-wasm-tests/hostcalls/src/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ impl Context for TestHttp {
"request.protocol",
"request.query",
"request.total_size",
"request.is_subrequest",
];

for property in properties {
Expand Down
Loading