Skip to content

Commit e6a8009

Browse files
authored
feat: implement get_http_call_response_header (#107)
Fix #106
1 parent ff257a0 commit e6a8009

File tree

5 files changed

+260
-15
lines changed

5 files changed

+260
-15
lines changed

src/http/ngx_http_wasm_api.c

+54-15
Original file line numberDiff line numberDiff line change
@@ -658,32 +658,28 @@ proxy_get_buffer_bytes(int32_t type, int32_t start, int32_t size,
658658
switch (type) {
659659
case PROXY_BUFFER_TYPE_PLUGIN_CONFIGURATION:
660660
buffer = ngx_http_wasm_get_conf();
661-
if (buffer != NULL) {
662-
data = buffer->data;
663-
len = buffer->len;
664-
}
665661
break;
666662

667663
case PROXY_BUFFER_TYPE_HTTP_REQUEST_BODY:
668664
case PROXY_BUFFER_TYPE_HTTP_RESPONSE_BODY:
669665
buffer = ngx_http_wasm_get_body();
670-
if (buffer != NULL) {
671-
data = buffer->data;
672-
len = buffer->len;
673-
}
674666
break;
675667

676668
case PROXY_BUFFER_TYPE_HTTP_CALL_RESPONSE_BODY:
677669
must_get_req(r);
678670
ctx = ngx_http_wasm_get_module_ctx(r);
679-
data = ctx->call_resp_body->data;
680-
len = ctx->call_resp_body->len;
671+
buffer = ctx->call_resp_body;
681672
break;
682673

683674
default:
684675
return PROXY_RESULT_UNIMPLEMENTED;
685676
}
686677

678+
if (buffer != NULL) {
679+
data = buffer->data;
680+
len = buffer->len;
681+
}
682+
687683
if (len == 0) {
688684
return PROXY_RESULT_NOT_FOUND;
689685
}
@@ -1243,7 +1239,7 @@ proxy_get_header_map_pairs(int32_t type, int32_t addr, int32_t size_addr)
12431239
return ngx_http_wasm_http_call_resp_get_headers(r, addr, size_addr);
12441240

12451241
default:
1246-
return PROXY_RESULT_BAD_ARGUMENT;
1242+
return PROXY_RESULT_UNIMPLEMENTED;
12471243
}
12481244

12491245
return PROXY_RESULT_OK;
@@ -1370,6 +1366,46 @@ ngx_http_wasm_resp_get_header(ngx_http_request_t *r, char *key, int32_t key_siz
13701366
}
13711367

13721368

1369+
static int32_t
1370+
ngx_http_wasm_http_call_resp_get_header(ngx_http_request_t *r, char *key, int32_t key_size,
1371+
int32_t addr, int32_t size)
1372+
{
1373+
ngx_log_t *log;
1374+
ngx_uint_t i;
1375+
ngx_http_wasm_ctx_t *ctx;
1376+
proxy_wasm_table_elt_t *hdr;
1377+
const u_char *val = NULL;
1378+
int32_t val_len = 0;
1379+
1380+
log = r->connection->log;
1381+
1382+
ctx = ngx_http_wasm_get_module_ctx(r);
1383+
if (ctx->call_resp_n_header == 0) {
1384+
return PROXY_RESULT_NOT_FOUND;
1385+
}
1386+
1387+
hdr = ctx->call_resp_headers;
1388+
1389+
for (i = 0; i < ctx->call_resp_n_header; i++) {
1390+
if ((size_t) key_size != hdr[i].key.len) {
1391+
continue;
1392+
}
1393+
1394+
if (ngx_strncasecmp((u_char *) key, hdr[i].key.data, hdr[i].key.len) == 0) {
1395+
val = hdr[i].value.data;
1396+
val_len = hdr[i].value.len;
1397+
break;
1398+
}
1399+
}
1400+
1401+
if (val == NULL) {
1402+
return PROXY_RESULT_NOT_FOUND;
1403+
}
1404+
1405+
return ngx_http_wasm_copy_to_wasm(log, val, val_len, addr, size);
1406+
}
1407+
1408+
13731409
int32_t
13741410
proxy_get_header_map_value(int32_t type, int32_t key_data, int32_t key_size,
13751411
int32_t addr, int32_t size)
@@ -1387,8 +1423,11 @@ proxy_get_header_map_value(int32_t type, int32_t key_data, int32_t key_size,
13871423
case PROXY_MAP_TYPE_HTTP_RESPONSE_HEADERS:
13881424
return ngx_http_wasm_resp_get_header(r, key, key_size, addr, size);
13891425

1426+
case PROXY_MAP_TYPE_HTTP_CALL_RESPONSE_HEADERS:
1427+
return ngx_http_wasm_http_call_resp_get_header(r, key, key_size, addr, size);
1428+
13901429
default:
1391-
return PROXY_RESULT_BAD_ARGUMENT;
1430+
return PROXY_RESULT_UNIMPLEMENTED;
13921431
}
13931432

13941433
return PROXY_RESULT_OK;
@@ -1417,7 +1456,7 @@ proxy_remove_header_map_value(int32_t type, int32_t key_data, int32_t key_size)
14171456
break;
14181457

14191458
default:
1420-
return PROXY_RESULT_BAD_ARGUMENT;
1459+
return PROXY_RESULT_UNIMPLEMENTED;
14211460
}
14221461

14231462
if (rc != NGX_OK) {
@@ -1452,7 +1491,7 @@ proxy_replace_header_map_value(int32_t type, int32_t key_data, int32_t key_size,
14521491
break;
14531492

14541493
default:
1455-
return PROXY_RESULT_BAD_ARGUMENT;
1494+
return PROXY_RESULT_UNIMPLEMENTED;
14561495
}
14571496

14581497
if (rc != NGX_OK) {
@@ -1487,7 +1526,7 @@ proxy_add_header_map_value(int32_t type, int32_t key_data, int32_t key_size,
14871526
break;
14881527

14891528
default:
1490-
return PROXY_RESULT_BAD_ARGUMENT;
1529+
return PROXY_RESULT_UNIMPLEMENTED;
14911530
}
14921531

14931532

t/rust/http-call.t

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Copyright 2022 Shenzhen ZhiLiu Technology Co., Ltd.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
use t::WASM 'no_plan';
16+
17+
run_tests();
18+
19+
__DATA__
20+
21+
=== TEST 1: get header
22+
--- config
23+
location /t {
24+
content_by_lua_block {
25+
local wasm = require("resty.proxy-wasm")
26+
local plugin = assert(wasm.load("fault_injection",
27+
"t/testdata/rust/http-call/target/wasm32-wasi/debug/http_call.wasm"))
28+
local ctx = assert(wasm.on_configure(plugin, '{}'))
29+
assert(wasm.on_http_request_headers(ctx))
30+
}
31+
}
32+
--- response_headers
33+
resp-status: 200
34+
resp-content-type: text/plain
35+
--- error_code: 403

t/testdata/rust/http-call/Cargo.lock

+91
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

t/testdata/rust/http-call/Cargo.toml

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Copyright 2022 Shenzhen ZhiLiu Technology Co., Ltd.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
[package]
16+
name = "http_call"
17+
version = "0.1.0"
18+
edition = "2021"
19+
20+
[lib]
21+
crate-type = ["cdylib"]
22+
path = "./http_call.rs"
23+
24+
[dependencies]
25+
log = "0.4"
26+
proxy-wasm = "0.2"
+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright 2022 Shenzhen ZhiLiu Technology Co., Ltd.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
use proxy_wasm::traits::*;
16+
use proxy_wasm::types::*;
17+
use std::time::Duration;
18+
19+
proxy_wasm::main! {{
20+
proxy_wasm::set_log_level(LogLevel::Trace);
21+
proxy_wasm::set_http_context(|_, _| -> Box<dyn HttpContext> { Box::new(HttpCall) });
22+
}}
23+
24+
struct HttpCall;
25+
26+
impl HttpContext for HttpCall {
27+
fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action {
28+
self.dispatch_http_call(
29+
"127.0.0.1:1980",
30+
vec![
31+
(":method", "GET"),
32+
(":path", "/bytes/1"),
33+
(":authority", "httpbin.org"),
34+
],
35+
None,
36+
vec![],
37+
Duration::from_secs(5),
38+
)
39+
.unwrap();
40+
Action::Pause
41+
}
42+
}
43+
44+
impl Context for HttpCall {
45+
fn on_http_call_response(&mut self, _: u32, _: usize, _: usize, _: usize) {
46+
let s = self.get_http_call_response_header("Content-Type").unwrap();
47+
let st = self.get_http_call_response_header(":status").unwrap();
48+
self.send_http_response(
49+
403,
50+
vec![("Resp-Content-Type", &s), ("Resp-Status", &st)],
51+
Some(b"Access forbidden.\n"),
52+
);
53+
}
54+
}

0 commit comments

Comments
 (0)