Skip to content

Commit b3883b3

Browse files
authored
feat: support get path and method with h2 request header (#56)
1 parent 72bb4bb commit b3883b3

File tree

3 files changed

+188
-7
lines changed

3 files changed

+188
-7
lines changed

src/http/ngx_http_wasm_api.c

+62-7
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@ typedef struct {
1212
ngx_str_t value;
1313
} ngx_http_wasm_table_elt_t;
1414

15+
typedef struct {
16+
ngx_str_t name;
17+
ngx_uint_t ty;
18+
} ngx_http_wasm_h2_header_t;
19+
20+
21+
enum {
22+
WASM_H2_HEADER_PATH = 1,
23+
WASM_H2_HEADER_METHOD,
24+
};
1525

1626
#define STR_BUF_SIZE 4096
1727

@@ -37,6 +47,10 @@ typedef struct {
3747
return NGX_ERROR; \
3848
}
3949

50+
#define WASM_H2_HEADER_STATIC_TABLE_ENTRIES \
51+
(sizeof(wasm_h2_header_static_table) \
52+
/ sizeof(ngx_http_wasm_h2_header_t))
53+
4054

4155
static int (*set_resp_header) (ngx_http_request_t *r,
4256
const char *key_data, size_t key_len, int is_nil,
@@ -60,6 +74,11 @@ static char *err_no_req_ctx = "no request ctx found";
6074

6175
static char *str_buf[STR_BUF_SIZE] = {0};
6276

77+
static ngx_http_wasm_h2_header_t wasm_h2_header_static_table[] = {
78+
{ngx_string(":path"), WASM_H2_HEADER_PATH},
79+
{ngx_string(":method"), WASM_H2_HEADER_METHOD},
80+
};
81+
6382

6483
wasm_functype_t *
6584
ngx_http_wasm_host_api_func(const ngx_wasm_host_api_t *api)
@@ -729,13 +748,14 @@ static int32_t
729748
ngx_http_wasm_req_get_header(ngx_http_request_t *r, char *key, int32_t key_size,
730749
int32_t addr, int32_t size)
731750
{
732-
ngx_log_t *log;
733-
ngx_uint_t i;
734-
ngx_list_part_t *part;
735-
ngx_table_elt_t *header;
736-
unsigned char *key_buf = NULL;
737-
const u_char *val = NULL;
738-
int32_t val_len = 0;
751+
ngx_log_t *log;
752+
ngx_uint_t i;
753+
ngx_list_part_t *part;
754+
ngx_table_elt_t *header;
755+
ngx_http_wasm_h2_header_t *wh;
756+
unsigned char *key_buf = NULL;
757+
const u_char *val = NULL;
758+
int32_t val_len = 0;
739759

740760
log = r->connection->log;
741761
part = &r->headers_in.headers.part;
@@ -762,6 +782,39 @@ ngx_http_wasm_req_get_header(ngx_http_request_t *r, char *key, int32_t key_size
762782
key_buf = (u_char *) key;
763783
}
764784

785+
if (key_size > 0 && key_buf[0] == ':') {
786+
for (i = 0; i < WASM_H2_HEADER_STATIC_TABLE_ENTRIES; i++) {
787+
wh = &wasm_h2_header_static_table[i];
788+
789+
if ((size_t) key_size != wh->name.len) {
790+
continue;
791+
}
792+
793+
if (ngx_strncasecmp(key_buf, wh->name.data, wh->name.len) == 0) {
794+
795+
switch (wh->ty) {
796+
case WASM_H2_HEADER_PATH:
797+
val = r->unparsed_uri.data;
798+
val_len = r->unparsed_uri.len;
799+
break;
800+
801+
case WASM_H2_HEADER_METHOD:
802+
val = r->method_name.data;
803+
val_len = r->method_name.len;
804+
break;
805+
806+
/* todo: scheme https://github.com/api7/wasm-nginx-module/issues/47 */
807+
default:
808+
break;
809+
}
810+
811+
if (val != NULL) {
812+
goto done;
813+
}
814+
}
815+
}
816+
}
817+
765818
for (i = 0; /* void */ ; i++) {
766819

767820
if (i >= part->nelts) {
@@ -789,6 +842,8 @@ ngx_http_wasm_req_get_header(ngx_http_request_t *r, char *key, int32_t key_size
789842
}
790843
}
791844

845+
done:
846+
792847
if (key_buf != (u_char *) key) {
793848
ngx_free(key_buf);
794849
}

t/http_req_header.t

+110
Original file line numberDiff line numberDiff line change
@@ -257,3 +257,113 @@ FOO: foo
257257
FOO: bar
258258
--- response_body
259259
nil
260+
261+
262+
263+
=== TEST 14: get path (not args)
264+
--- config
265+
location /t {
266+
content_by_lua_block {
267+
local wasm = require("resty.proxy-wasm")
268+
local plugin = assert(wasm.load("plugin", "t/testdata/http_header/main.go.wasm"))
269+
local ctx = assert(wasm.on_configure(plugin, 'req_path_get'))
270+
assert(wasm.on_http_request_headers(ctx))
271+
}
272+
}
273+
--- grep_error_log eval
274+
qr/get request path: \S+/
275+
--- grep_error_log_out
276+
get request path: /t,
277+
278+
279+
280+
=== TEST 15: get path (args)
281+
--- config
282+
location /t {
283+
content_by_lua_block {
284+
local wasm = require("resty.proxy-wasm")
285+
local plugin = assert(wasm.load("plugin", "t/testdata/http_header/main.go.wasm"))
286+
local ctx = assert(wasm.on_configure(plugin, 'req_path_get'))
287+
assert(wasm.on_http_request_headers(ctx))
288+
}
289+
}
290+
--- request
291+
GET /t?q=hello&a=world
292+
--- grep_error_log eval
293+
qr/get request path: \S+/
294+
--- grep_error_log_out
295+
get request path: /t?q=hello&a=world,
296+
297+
298+
299+
=== TEST 16: get method (GET)
300+
--- config
301+
location /t {
302+
content_by_lua_block {
303+
local wasm = require("resty.proxy-wasm")
304+
local plugin = assert(wasm.load("plugin", "t/testdata/http_header/main.go.wasm"))
305+
local ctx = assert(wasm.on_configure(plugin, 'req_method_get'))
306+
assert(wasm.on_http_request_headers(ctx))
307+
}
308+
}
309+
--- grep_error_log eval
310+
qr/get request method: \S+/
311+
--- grep_error_log_out
312+
get request method: GET,
313+
314+
315+
316+
=== TEST 17: get method (POST)
317+
--- config
318+
location /t {
319+
content_by_lua_block {
320+
local wasm = require("resty.proxy-wasm")
321+
local plugin = assert(wasm.load("plugin", "t/testdata/http_header/main.go.wasm"))
322+
local ctx = assert(wasm.on_configure(plugin, 'req_method_get'))
323+
assert(wasm.on_http_request_headers(ctx))
324+
}
325+
}
326+
--- request
327+
POST /t
328+
--- grep_error_log eval
329+
qr/get request method: \S+/
330+
--- grep_error_log_out
331+
get request method: POST,
332+
333+
334+
335+
=== TEST 18: get method (PUT)
336+
--- config
337+
location /t {
338+
content_by_lua_block {
339+
local wasm = require("resty.proxy-wasm")
340+
local plugin = assert(wasm.load("plugin", "t/testdata/http_header/main.go.wasm"))
341+
local ctx = assert(wasm.on_configure(plugin, 'req_method_get'))
342+
assert(wasm.on_http_request_headers(ctx))
343+
}
344+
}
345+
--- request
346+
PUT /t
347+
--- grep_error_log eval
348+
qr/get request method: \S+/
349+
--- grep_error_log_out
350+
get request method: PUT,
351+
352+
353+
354+
=== TEST 19: get method (DELETE)
355+
--- config
356+
location /t {
357+
content_by_lua_block {
358+
local wasm = require("resty.proxy-wasm")
359+
local plugin = assert(wasm.load("plugin", "t/testdata/http_header/main.go.wasm"))
360+
local ctx = assert(wasm.on_configure(plugin, 'req_method_get'))
361+
assert(wasm.on_http_request_headers(ctx))
362+
}
363+
}
364+
--- request
365+
DELETE /t
366+
--- grep_error_log eval
367+
qr/get request method: \S+/
368+
--- grep_error_log_out
369+
get request method: DELETE,

t/testdata/http_header/main.go

+16
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,22 @@ func (ctx *httpContext) OnHttpRequestHeaders(numHeaders int, endOfStream bool) t
7474

7575
case "req_hdr_del":
7676
proxywasm.RemoveHttpRequestHeader("foo")
77+
78+
case "req_path_get":
79+
res, err := proxywasm.GetHttpRequestHeader(":path")
80+
if err != nil {
81+
proxywasm.LogErrorf("error get request path: %v", err)
82+
return types.ActionContinue
83+
}
84+
proxywasm.LogWarnf("get request path: %v", res)
85+
86+
case "req_method_get":
87+
res, err := proxywasm.GetHttpRequestHeader(":method")
88+
if err != nil {
89+
proxywasm.LogErrorf("error get request method: %v", err)
90+
return types.ActionContinue
91+
}
92+
proxywasm.LogWarnf("get request method: %v", res)
7793
}
7894

7995
return types.ActionContinue

0 commit comments

Comments
 (0)