Skip to content

Commit b3005e4

Browse files
authored
feat: run on_http_response_headers (#30)
1 parent 6d6d765 commit b3005e4

File tree

6 files changed

+143
-9
lines changed

6 files changed

+143
-9
lines changed

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,26 @@ end
8383
assert(wasm.on_http_request_headers(ctx))
8484
```
8585

86+
### on_http_reponse_headers
87+
88+
`syntax: ok, err = proxy_wasm.on_http_reponse_headers(plugin_ctx)`
89+
90+
Run the HTTP response headers filter in the plugin of the given plugin ctx.
91+
92+
```lua
93+
local plugin, err = proxy_wasm.load("plugin","t/testdata/http_lifecycle/main.go.wasm")
94+
if not plugin then
95+
ngx.log(ngx.ERR, "failed to load wasm ", err)
96+
return
97+
end
98+
local ctx, err = wasm.on_configure(plugin, '{"body":512}')
99+
if not ctx then
100+
ngx.log(ngx.ERR, "failed to create plugin ctx ", err)
101+
return
102+
end
103+
assert(wasm.on_http_response_headers(ctx))
104+
```
105+
86106
## proxy-wasm ABI
87107

88108
Implemented proxy-wasm ABI can be found in [proxy_wasm_abi](./proxy_wasm_abi.md).

lib/resty/proxy-wasm.lua

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ ngx_str_t *ngx_http_wasm_fetch_local_body(void *r);
2828

2929
local _M = {}
3030
local HTTP_REQUEST_HEADERS = 1
31+
--local HTTP_REQUEST_BODY = 2
32+
local HTTP_RESPONSE_HEADERS = 4
33+
--local HTTP_RESPONSE_BODY = 8
3134

3235

3336
function _M.load(name, path)
@@ -100,4 +103,23 @@ function _M.on_http_request_headers(plugin_ctx)
100103
end
101104

102105

106+
function _M.on_http_response_headers(plugin_ctx)
107+
if type(plugin_ctx) ~= "cdata" then
108+
return nil, "bad plugin ctx"
109+
end
110+
111+
local r = get_request()
112+
if not r then
113+
return nil, "bad request"
114+
end
115+
116+
local rc = C.ngx_http_wasm_on_http(plugin_ctx, r, HTTP_RESPONSE_HEADERS)
117+
if rc < 0 then
118+
return nil, "failed to run proxy_on_http_response_headers"
119+
end
120+
121+
return true
122+
end
123+
124+
103125
return _M

proxy_wasm_abi.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,20 @@ Called when HTTP request headers are received from the client. TODO: Headers can
104104

105105
TODO: pass a correct `num_headers` but not 0.
106106

107+
### `proxy_on_response_headers`
108+
109+
* params:
110+
- `i32 (uint32_t) context_id`
111+
- `i32 (size_t) num_headers`
112+
- `i32 (bool) end_of_stream`
113+
* returns:
114+
- `i32 (proxy_action_t) next_action`
115+
116+
Called when HTTP response headers are received from the upstream. TODO: Headers can be retrieved using
117+
`proxy_get_map` and/or `proxy_get_map_value`.
118+
119+
TODO: pass a correct `num_headers` but not 0.
120+
107121

108122
# Functions implemented in the host environment
109123

src/http/ngx_http_wasm_module.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,15 @@ static ngx_str_t proxy_on_done = ngx_string("proxy_on_done");
3030
static ngx_str_t proxy_on_delete = ngx_string("proxy_on_delete");
3131
static ngx_str_t proxy_on_request_headers =
3232
ngx_string("proxy_on_request_headers");
33+
static ngx_str_t proxy_on_response_headers =
34+
ngx_string("proxy_on_response_headers");
3335

3436

3537
typedef enum {
3638
HTTP_REQUEST_HEADERS = 1,
39+
HTTP_REQUEST_BODY = 2,
40+
HTTP_RESPONSE_HEADERS = 4,
41+
HTTP_RESPONSE_BODY = 8,
3742
} ngx_http_wasm_phase_t;
3843

3944

@@ -594,6 +599,7 @@ ngx_http_wasm_on_http(ngx_http_wasm_plugin_ctx_t *hwp_ctx, ngx_http_request_t *r
594599
{
595600
ngx_int_t rc;
596601
ngx_log_t *log;
602+
ngx_str_t *cb_name;
597603
ngx_http_wasm_http_ctx_t *http_ctx;
598604
ngx_http_wasm_main_conf_t *wmcf;
599605

@@ -614,13 +620,20 @@ ngx_http_wasm_on_http(ngx_http_wasm_plugin_ctx_t *hwp_ctx, ngx_http_request_t *r
614620
return NGX_DECLINED;
615621
}
616622

623+
624+
if (type == HTTP_RESPONSE_HEADERS) {
625+
cb_name = &proxy_on_response_headers;
626+
} else {
627+
cb_name = &proxy_on_request_headers;
628+
}
629+
617630
if (hwp_ctx->hw_plugin->abi_version == PROXY_WASM_ABI_VER_010) {
618631
rc = ngx_wasm_vm.call(hwp_ctx->hw_plugin->plugin,
619-
&proxy_on_request_headers,
632+
cb_name,
620633
true, NGX_WASM_PARAM_I32_I32, http_ctx->id, 0);
621634
} else {
622635
rc = ngx_wasm_vm.call(hwp_ctx->hw_plugin->plugin,
623-
&proxy_on_request_headers,
636+
cb_name,
624637
true, NGX_WASM_PARAM_I32_I32_I32, http_ctx->id,
625638
0, 1);
626639
}

t/http_lifecycle.t

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,10 @@ location /t {
105105
}
106106
}
107107
--- grep_error_log eval
108-
qr/run http ctx \d+ with conf \S+/
108+
qr/run http ctx \d+ with conf \S+ on http request headers,/
109109
--- grep_error_log_out
110-
run http ctx 3 with conf {"body":512},
111-
run http ctx 4 with conf {"body":256},
110+
run http ctx 3 with conf {"body":512} on http request headers,
111+
run http ctx 4 with conf {"body":256} on http request headers,
112112

113113

114114

@@ -126,7 +126,53 @@ location /t {
126126
}
127127
}
128128
--- grep_error_log eval
129-
qr/run http ctx \d+ with conf \S+/
129+
qr/run http ctx \d+ with conf \S+ on http request headers,/
130130
--- grep_error_log_out
131-
run http ctx 2 with conf {"body":512},
132-
run http ctx 2 with conf {"body":256},
131+
run http ctx 2 with conf {"body":512} on http request headers,
132+
run http ctx 2 with conf {"body":256} on http request headers,
133+
134+
135+
136+
=== TEST 6: on reponse headers
137+
--- config
138+
location /t {
139+
content_by_lua_block {
140+
local wasm = require("resty.proxy-wasm")
141+
local plugin = assert(wasm.load("plugin", "t/testdata/http_lifecycle/main.go.wasm"))
142+
local ctx = assert(wasm.on_configure(plugin, '{"body":512}'))
143+
ngx.ctx.ctx = ctx
144+
assert(wasm.on_http_request_headers(ctx))
145+
}
146+
header_filter_by_lua_block {
147+
local wasm = require("resty.proxy-wasm")
148+
local ctx = ngx.ctx.ctx
149+
assert(wasm.on_http_response_headers(ctx))
150+
}
151+
}
152+
--- grep_error_log eval
153+
qr/run http ctx \d+ with conf \S+ on [^,]+,/
154+
--- grep_error_log_out
155+
run http ctx 2 with conf {"body":512} on http request headers,
156+
run http ctx 2 with conf {"body":512} on http response headers,
157+
158+
159+
160+
=== TEST 7: crash on reponse headers
161+
--- config
162+
location /t {
163+
content_by_lua_block {
164+
local wasm = require("resty.proxy-wasm")
165+
local plugin = assert(wasm.load("plugin", "t/testdata/http_lifecycle/main.go.wasm"))
166+
ngx.ctx.plugin = plugin
167+
}
168+
header_filter_by_lua_block {
169+
local wasm = require("resty.proxy-wasm")
170+
local plugin = ngx.ctx.plugin
171+
local ctx = assert(wasm.on_configure(plugin, 'panic_on_http_response_headers'))
172+
local ok, err = wasm.on_http_response_headers(ctx)
173+
ngx.log(ngx.ERR, err)
174+
}
175+
}
176+
--- error_log
177+
failed to call function
178+
failed to run proxy_on_http_response_headers

t/testdata/http_lifecycle/main.go

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,25 @@ func (ctx *httpLifecycle) OnHttpRequestHeaders(numHeaders int, endOfStream bool)
4545
return types.ActionContinue
4646
}
4747

48-
proxywasm.LogWarnf("run http ctx %d with conf %s", ctx.contextID, string(data))
48+
proxywasm.LogWarnf("run http ctx %d with conf %s on http request headers",
49+
ctx.contextID, string(data))
50+
return types.ActionContinue
51+
}
52+
53+
func (ctx *httpLifecycle) OnHttpResponseHeaders(numHeaders int, endOfStream bool) types.Action {
54+
data, err := proxywasm.GetPluginConfiguration()
55+
if err != nil {
56+
proxywasm.LogCriticalf("error reading plugin configuration: %v", err)
57+
return types.ActionContinue
58+
}
59+
60+
action := string(data)
61+
62+
if action == "panic_on_http_response_headers" {
63+
panic("OUCH")
64+
}
65+
66+
proxywasm.LogWarnf("run http ctx %d with conf %s on http response headers",
67+
ctx.contextID, string(data))
4968
return types.ActionContinue
5069
}

0 commit comments

Comments
 (0)