Skip to content

Commit 32ecdfe

Browse files
authored
feat: get response body in http call callback (#75)
1 parent 498d46d commit 32ecdfe

File tree

5 files changed

+133
-2
lines changed

5 files changed

+133
-2
lines changed

src/http/ngx_http_wasm_api.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,14 +410,17 @@ proxy_log(int32_t log_level, int32_t addr, int32_t size)
410410

411411

412412
int32_t
413-
proxy_get_buffer_bytes(int32_t type, int32_t start, int32_t length,
413+
proxy_get_buffer_bytes(int32_t type, int32_t start, int32_t size,
414414
int32_t addr, int32_t size_addr)
415415
{
416416
ngx_log_t *log;
417417
const u_char *data;
418418
int32_t len;
419419
const ngx_str_t *conf;
420420

421+
ngx_http_request_t *r;
422+
ngx_http_wasm_ctx_t *ctx;
423+
421424
log = ngx_http_wasm_get_log();
422425

423426
switch (type) {
@@ -427,10 +430,35 @@ proxy_get_buffer_bytes(int32_t type, int32_t start, int32_t length,
427430
len = conf->len;
428431
break;
429432

433+
case PROXY_BUFFER_TYPE_HTTP_CALL_RESPONSE_BODY:
434+
must_get_req(r);
435+
ctx = ngx_http_wasm_get_module_ctx(r);
436+
data = ctx->call_resp_body->data;
437+
len = ctx->call_resp_body->len;
438+
break;
439+
430440
default:
431441
return PROXY_RESULT_UNIMPLEMENTED;
432442
}
433443

444+
if (len == 0) {
445+
return PROXY_RESULT_NOT_FOUND;
446+
}
447+
448+
if (type != PROXY_BUFFER_TYPE_PLUGIN_CONFIGURATION) {
449+
/* configuration is fetched as a whole */
450+
if (start < 0 || size <= 0 || start >= len) {
451+
return PROXY_RESULT_BAD_ARGUMENT;
452+
}
453+
454+
if (start + size > len) {
455+
size = len - start;
456+
}
457+
458+
data = data + start;
459+
len = size;
460+
}
461+
434462
return ngx_http_wasm_copy_to_wasm(log, data, len, addr, size_addr);
435463
}
436464

src/http/ngx_http_wasm_module.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,7 @@ ngx_http_wasm_on_http_call_resp(ngx_http_wasm_plugin_ctx_t *hwp_ctx, ngx_http_re
728728
&proxy_on_http_call_response,
729729
false, NGX_WASM_PARAM_I32_I32_I32_I32_I32,
730730
hwp_ctx->id, ctx->callout_id,
731-
n_header, 0, 0);
731+
n_header, body == NULL ? 0 : body->len, 0);
732732

733733
ngx_http_wasm_set_state(NULL);
734734

t/WASM.pm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ add_block_preprocessor(sub {
7777
local body = ngx.req.get_body_data()
7878
ngx.log(ngx.WARN, "hit with body ", body)
7979
end
80+
81+
if ngx.var.arg_body then
82+
ngx.print(ngx.var.arg_body)
83+
end
8084
}
8185
}
8286
}

t/http_call_callback.t

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,90 @@ location /t {
7878
}
7979
--- error_log
8080
callback err: error status returned by host: not found
81+
82+
83+
84+
=== TEST 4: get body, no body
85+
--- config
86+
location /t {
87+
content_by_lua_block {
88+
local json = require("cjson")
89+
local wasm = require("resty.proxy-wasm")
90+
local plugin = assert(wasm.load("plugin", "t/testdata/http_call/main.go.wasm"))
91+
local conf = {host = "127.0.0.1:1980", action = "body"}
92+
local ctx = assert(wasm.on_configure(plugin, json.encode(conf)))
93+
assert(wasm.on_http_request_headers(ctx))
94+
}
95+
}
96+
--- error_log
97+
get bodySize 0
98+
error status returned by host: not found
99+
100+
101+
102+
=== TEST 5: get body
103+
--- config
104+
location /t {
105+
content_by_lua_block {
106+
local json = require("cjson")
107+
local wasm = require("resty.proxy-wasm")
108+
local plugin = assert(wasm.load("plugin", "t/testdata/http_call/main.go.wasm"))
109+
local conf = {host = "127.0.0.1:1980", action = "body", path = "/?body=helloworld"}
110+
for _, e in ipairs({
111+
{0, 2},
112+
{1, 1},
113+
{1, 2},
114+
{0, 10},
115+
{1, 9},
116+
{8, 2},
117+
{9, 1},
118+
{1, 10},
119+
}) do
120+
conf.start = e[1]
121+
conf.size = e[2]
122+
local ctx = assert(wasm.on_configure(plugin, json.encode(conf)))
123+
assert(wasm.on_http_request_headers(ctx))
124+
end
125+
}
126+
}
127+
--- grep_error_log eval
128+
qr/get body \[\w+\]/
129+
--- grep_error_log_out
130+
get body [he]
131+
get body [e]
132+
get body [el]
133+
get body [helloworld]
134+
get body [elloworld]
135+
get body [ld]
136+
get body [d]
137+
get body [elloworld]
138+
139+
140+
141+
=== TEST 6: get body, bad cases
142+
--- config
143+
location /t {
144+
content_by_lua_block {
145+
local json = require("cjson")
146+
local wasm = require("resty.proxy-wasm")
147+
local plugin = assert(wasm.load("plugin", "t/testdata/http_call/main.go.wasm"))
148+
local conf = {host = "127.0.0.1:1980", action = "body", path = "/?body=helloworld"}
149+
for _, e in ipairs({
150+
{-1, 2},
151+
{1, 0},
152+
{1, -1},
153+
{10, 2},
154+
}) do
155+
conf.start = e[1]
156+
conf.size = e[2]
157+
local ctx = assert(wasm.on_configure(plugin, json.encode(conf)))
158+
assert(wasm.on_http_request_headers(ctx))
159+
end
160+
}
161+
}
162+
--- error_log
163+
[error]
164+
--- grep_error_log eval
165+
qr/error status returned by host: bad argument/
166+
--- grep_error_log_out eval
167+
"error status returned by host: bad argument\n" x 4

t/testdata/http_call/main.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,18 @@ func (ctx *httpContext) dispatchHttpCall(elem *fastjson.Value) {
8282
proxywasm.LogWarnf("get header %s: %s", h[0], h[1])
8383
}
8484
}
85+
case "body":
86+
ctx.callback = func(numHeaders int, bodySize int, numTrailers int) {
87+
proxywasm.LogWarnf("get bodySize %d", bodySize)
88+
start := elem.GetInt("start")
89+
size := elem.GetInt("size")
90+
body, err := proxywasm.GetHttpCallResponseBody(start, size)
91+
if err != nil {
92+
proxywasm.LogErrorf("callback err: %v", err)
93+
return
94+
}
95+
proxywasm.LogWarnf("get body [%s]", string(body))
96+
}
8597
}
8698

8799
hs := [][2]string{}

0 commit comments

Comments
 (0)