Skip to content

Commit

Permalink
feat: implement get_http_call_response_header (#107)
Browse files Browse the repository at this point in the history
Fix #106
  • Loading branch information
spacewander authored May 20, 2022
1 parent ff257a0 commit e6a8009
Show file tree
Hide file tree
Showing 5 changed files with 260 additions and 15 deletions.
69 changes: 54 additions & 15 deletions src/http/ngx_http_wasm_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -658,32 +658,28 @@ proxy_get_buffer_bytes(int32_t type, int32_t start, int32_t size,
switch (type) {
case PROXY_BUFFER_TYPE_PLUGIN_CONFIGURATION:
buffer = ngx_http_wasm_get_conf();
if (buffer != NULL) {
data = buffer->data;
len = buffer->len;
}
break;

case PROXY_BUFFER_TYPE_HTTP_REQUEST_BODY:
case PROXY_BUFFER_TYPE_HTTP_RESPONSE_BODY:
buffer = ngx_http_wasm_get_body();
if (buffer != NULL) {
data = buffer->data;
len = buffer->len;
}
break;

case PROXY_BUFFER_TYPE_HTTP_CALL_RESPONSE_BODY:
must_get_req(r);
ctx = ngx_http_wasm_get_module_ctx(r);
data = ctx->call_resp_body->data;
len = ctx->call_resp_body->len;
buffer = ctx->call_resp_body;
break;

default:
return PROXY_RESULT_UNIMPLEMENTED;
}

if (buffer != NULL) {
data = buffer->data;
len = buffer->len;
}

if (len == 0) {
return PROXY_RESULT_NOT_FOUND;
}
Expand Down Expand Up @@ -1243,7 +1239,7 @@ proxy_get_header_map_pairs(int32_t type, int32_t addr, int32_t size_addr)
return ngx_http_wasm_http_call_resp_get_headers(r, addr, size_addr);

default:
return PROXY_RESULT_BAD_ARGUMENT;
return PROXY_RESULT_UNIMPLEMENTED;
}

return PROXY_RESULT_OK;
Expand Down Expand Up @@ -1370,6 +1366,46 @@ ngx_http_wasm_resp_get_header(ngx_http_request_t *r, char *key, int32_t key_siz
}


static int32_t
ngx_http_wasm_http_call_resp_get_header(ngx_http_request_t *r, char *key, int32_t key_size,
int32_t addr, int32_t size)
{
ngx_log_t *log;
ngx_uint_t i;
ngx_http_wasm_ctx_t *ctx;
proxy_wasm_table_elt_t *hdr;
const u_char *val = NULL;
int32_t val_len = 0;

log = r->connection->log;

ctx = ngx_http_wasm_get_module_ctx(r);
if (ctx->call_resp_n_header == 0) {
return PROXY_RESULT_NOT_FOUND;
}

hdr = ctx->call_resp_headers;

for (i = 0; i < ctx->call_resp_n_header; i++) {
if ((size_t) key_size != hdr[i].key.len) {
continue;
}

if (ngx_strncasecmp((u_char *) key, hdr[i].key.data, hdr[i].key.len) == 0) {
val = hdr[i].value.data;
val_len = hdr[i].value.len;
break;
}
}

if (val == NULL) {
return PROXY_RESULT_NOT_FOUND;
}

return ngx_http_wasm_copy_to_wasm(log, val, val_len, addr, size);
}


int32_t
proxy_get_header_map_value(int32_t type, int32_t key_data, int32_t key_size,
int32_t addr, int32_t size)
Expand All @@ -1387,8 +1423,11 @@ proxy_get_header_map_value(int32_t type, int32_t key_data, int32_t key_size,
case PROXY_MAP_TYPE_HTTP_RESPONSE_HEADERS:
return ngx_http_wasm_resp_get_header(r, key, key_size, addr, size);

case PROXY_MAP_TYPE_HTTP_CALL_RESPONSE_HEADERS:
return ngx_http_wasm_http_call_resp_get_header(r, key, key_size, addr, size);

default:
return PROXY_RESULT_BAD_ARGUMENT;
return PROXY_RESULT_UNIMPLEMENTED;
}

return PROXY_RESULT_OK;
Expand Down Expand Up @@ -1417,7 +1456,7 @@ proxy_remove_header_map_value(int32_t type, int32_t key_data, int32_t key_size)
break;

default:
return PROXY_RESULT_BAD_ARGUMENT;
return PROXY_RESULT_UNIMPLEMENTED;
}

if (rc != NGX_OK) {
Expand Down Expand Up @@ -1452,7 +1491,7 @@ proxy_replace_header_map_value(int32_t type, int32_t key_data, int32_t key_size,
break;

default:
return PROXY_RESULT_BAD_ARGUMENT;
return PROXY_RESULT_UNIMPLEMENTED;
}

if (rc != NGX_OK) {
Expand Down Expand Up @@ -1487,7 +1526,7 @@ proxy_add_header_map_value(int32_t type, int32_t key_data, int32_t key_size,
break;

default:
return PROXY_RESULT_BAD_ARGUMENT;
return PROXY_RESULT_UNIMPLEMENTED;
}


Expand Down
35 changes: 35 additions & 0 deletions t/rust/http-call.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Copyright 2022 Shenzhen ZhiLiu Technology Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
use t::WASM 'no_plan';

run_tests();

__DATA__
=== TEST 1: get header
--- config
location /t {
content_by_lua_block {
local wasm = require("resty.proxy-wasm")
local plugin = assert(wasm.load("fault_injection",
"t/testdata/rust/http-call/target/wasm32-wasi/debug/http_call.wasm"))
local ctx = assert(wasm.on_configure(plugin, '{}'))
assert(wasm.on_http_request_headers(ctx))
}
}
--- response_headers
resp-status: 200
resp-content-type: text/plain
--- error_code: 403
91 changes: 91 additions & 0 deletions t/testdata/rust/http-call/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions t/testdata/rust/http-call/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright 2022 Shenzhen ZhiLiu Technology Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
[package]
name = "http_call"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib"]
path = "./http_call.rs"

[dependencies]
log = "0.4"
proxy-wasm = "0.2"
54 changes: 54 additions & 0 deletions t/testdata/rust/http-call/http_call.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2022 Shenzhen ZhiLiu Technology Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
use proxy_wasm::traits::*;
use proxy_wasm::types::*;
use std::time::Duration;

proxy_wasm::main! {{
proxy_wasm::set_log_level(LogLevel::Trace);
proxy_wasm::set_http_context(|_, _| -> Box<dyn HttpContext> { Box::new(HttpCall) });
}}

struct HttpCall;

impl HttpContext for HttpCall {
fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action {
self.dispatch_http_call(
"127.0.0.1:1980",
vec![
(":method", "GET"),
(":path", "/bytes/1"),
(":authority", "httpbin.org"),
],
None,
vec![],
Duration::from_secs(5),
)
.unwrap();
Action::Pause
}
}

impl Context for HttpCall {
fn on_http_call_response(&mut self, _: u32, _: usize, _: usize, _: usize) {
let s = self.get_http_call_response_header("Content-Type").unwrap();
let st = self.get_http_call_response_header(":status").unwrap();
self.send_http_response(
403,
vec![("Resp-Content-Type", &s), ("Resp-Status", &st)],
Some(b"Access forbidden.\n"),
);
}
}

0 comments on commit e6a8009

Please sign in to comment.