WASM filter doesn't progress from `on_http_[request|response]_header` to `on_http_[request|response]_body`
adalrsjr1 opened this issue · comments
I'm trying to create a filter that access the body content of an HTTP request/response, but it fails. The code can't progress from on_http_response_headers
to on_http_response_body
. I'm using a customized code baded onhttp_body
example.
I noticed that I can't go from on_http_request_headers
to on_http_request_body
as well.
My toy application is an Nginx+Istio proxy on Kubernetes. Following are the filter configuration and the code.
Do I missing anything?
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: my-wasm-filter
spec:
workloadSelector:
labels:
app: wasm-filter
configPatches:
- applyTo: HTTP_FILTER
match:
context: ANY # I've tried SIDECAR_INBOUND with no sucess as well
listener:
filterChain:
filter:
name: envoy.filters.network.http_connection_manager
subFilter:
name: envoy.filters.http.router
patch:
operation: INSERT_BEFORE
value:
name: my-wasm-filter
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
config:
root_id: "my-wasm-filter-root-0.1"
vm_config:
code:
local:
filename: /wasm-filter/myenvoyfilter.wasm
runtime: envoy.wasm.runtime.v8
vm_id: my-wasm-filter-0.1
---
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: my-wasm-filter-config
spec:
configPatches:
- applyTo: EXTENSION_CONFIG
patch:
operation: ADD
value:
name: my-wasm-filter
typed_config:
'@type': type.googleapis.com/udpa.type.v1.TypedStruct
type_url: type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
value:
config:
root_id: "my-wasm-filter-root-0.1"
vm_config:
vm_id: "my-wasm-filter-0.1"
code:
local:
filename: file:///wasm-filter/myenvoyfilter.wasm
runtime: envoy.wasm.runtime.v8
fn on_http_response_headers(&mut self, _num_headers: usize, _end_of_stream: bool) -> Action {
match self.get_shared_data(":path") {
(None, _) => {
warn!("cannot retrieve :path from shared data");
},
(Some(path), _) => {
debug!("[{}] on response headers {}", self.context_id, str::from_utf8(&path).unwrap());
}
}
debug!("still on response headers");
// If there is a Content-Length header and we change the length of
// the body later, then clients will break. So remove it.
// We must do this here, because once we exit this function we
// can no longer modify the response headers.
self.set_http_response_header("content-length", None);
Action::Continue
}
fn on_http_response_body(&mut self, _body_size: usize, _end_of_stream: bool) -> Action {
debug!("on response body");
if !_end_of_stream {
// Wait -- we'll be called again when the complete body is buffered
// at the host side.
trace!("waiting end of stream");
return Action::Pause;
}
match self.get_shared_data(":path") {
(None, _) => {
warn!("cannot retrieve :path from shared data");
},
(Some(path), _) => {
debug!("[{}] on response body {}", self.context_id, str::from_utf8(&path).unwrap());
}
}
// Replace the message body if it contains the text "secret".
// Since we returned "Pause" previuously, this will return the whole body.
// if let Some(body_bytes) = self.get_http_response_body(0, body_size) {
// let body_str = String::from_utf8(body_bytes).unwrap();
// if body_str.contains("secret") {
// let new_body = format!("Original message body ({} bytes) redacted.", body_size);
// self.set_http_response_body(0, body_size, &new_body.into_bytes());
// }
// }
Action::Continue
}
Here is the part of the log referent to HTTP response.
2022-08-03T14:15:04.691239Z debug envoy wasm wasm log my-wasm-filter-0.1: [6] on response headers b [5/1795]
2022-08-03T14:15:04.691267Z trace envoy wasm [vm<-host] env.proxy_log return: 0
2022-08-03T14:15:04.691283Z trace envoy wasm [vm->host] env.proxy_log(1, 1114328, 25)
2022-08-03T14:15:04.691367Z debug envoy wasm wasm log my-wasm-filter-0.1: still on response headers
2022-08-03T14:15:04.691374Z trace envoy wasm [vm<-host] env.proxy_log return: 0
2022-08-03T14:15:04.691386Z trace envoy wasm [vm->host] env.proxy_remove_header_map_value(2, 1051436, 14)
2022-08-03T14:15:04.691468Z trace envoy wasm [vm<-host] env.proxy_remove_header_map_value return: 0
2022-08-03T14:15:04.691486Z trace envoy wasm [host<-vm] proxy_on_response_headers return: 0
2022-08-03T14:15:04.693984Z debug envoy wasm expr_evaluate value error: No value with name "downstream_peer" found in Activation
2022-08-03T14:15:04.694185Z trace envoy wasm wasm log stats_inbound stats_inbound: [extensions/stats/plugin.cc:628]::report() Failed to evaluate expression: <downstream_peer.cluster_id>
2022-08-03T14:15:04.694397Z debug envoy wasm wasm log stats_inbound stats_inbound: [extensions/stats/plugin.cc:640]::report() metricKey cache hit , stat=16
2022-08-03T14:15:04.694818Z debug envoy wasm wasm log stats_inbound stats_inbound: [extensions/stats/plugin.cc:640]::report() metricKey cache hit , stat=18
2022-08-03T14:15:04.694902Z debug envoy wasm wasm log stats_inbound stats_inbound: [extensions/stats/plugin.cc:640]::report() metricKey cache hit , stat=22
2022-08-03T14:15:04.694917Z debug envoy wasm wasm log stats_inbound stats_inbound: [extensions/stats/plugin.cc:640]::report() metricKey cache hit , stat=26
2022-08-03T14:15:04.694999Z trace envoy wasm [host->vm] proxy_on_log(6)
2022-08-03T14:15:04.695034Z trace envoy wasm [host<-vm] proxy_on_log return: void
2022-08-03T14:15:04.695096Z trace envoy wasm [host->vm] proxy_on_done(6)
2022-08-03T14:15:04.695125Z trace envoy wasm [host<-vm] proxy_on_done return: 1
2022-08-03T14:15:04.695129Z trace envoy wasm [host->vm] proxy_on_delete(6)
2022-08-03T14:15:04.695181Z trace envoy wasm [host<-vm] proxy_on_delete return: void
[2022-08-03T14:15:04.678Z] "HEAD /b HTTP/1.1" 404 - via_upstream - "-" 0 0 13 2 "-" "curl/7.47.0" "de2f78e1-9f58-9c2f-a7c0-58c167d92999" "wasm-filter" "10.244.0.41:80" inbound|80|| 127.0.0.6:55503 10.244.0.41:80 10.244.0.15:43030 - default
It's a HEAD
request, so there is no response body sent by the upstream, which is why on_http_response_body
is not called.
oh man, it is embarassing my lack of attention on such silly thing 😅
I changed my curl -I
to curl
and it worked as expected.
Closing the issue.