Wasm C++ filter¶
This sandbox demonstrates a basic Envoy Wasm filter written in C++ which injects
content into the body of an HTTP
response, and adds and updates some headers.
It also takes you through the steps required to build your own C++ Wasm filter, and run it with Envoy.
Step 1: Start all of our containers¶
First lets start the containers - an Envoy proxy which uses a Wasm Filter, and a backend which echos back our request.
Change to the examples/wasm-cc
folder in the Envoy repo, and start the composition:
$ pwd
envoy/examples/wasm-cc
$ docker-compose build --pull
$ docker-compose up -d
$ docker-compose ps
Name Command State Ports
-----------------------------------------------------------------------------------------------
wasm_proxy_1 /docker-entrypoint.sh /usr ... Up 10000/tcp, 0.0.0.0:8000->8000/tcp
wasm_web_service_1 node ./index.js Up
Step 2: Check web response¶
The Wasm filter should inject “Hello, world” at the end of the response body when you make a request to the proxy.
$ curl -s http://localhost:8000 | grep "Hello, world"
}Hello, world
The filter also sets the content-type
header to text/plain
, and adds a custom x-wasm-custom
header.
$ curl -v http://localhost:8000 | grep "content-type: "
content-type: text/plain; charset=utf-8
$ curl -v http://localhost:8000 | grep "x-wasm-custom: "
x-wasm-custom: FOO
Step 3: Compile the updated filter¶
There are two source code files provided for the Wasm filter.
envoy_filter_http_wasm_example.cc
provides the source code for
the included prebuilt binary.
envoy_filter_http_wasm_updated_example.cc
makes a few
changes to the original.
The following diff shows the changes that have been made:
--- /tmp/tmpe5xv7v2q/generated/rst/start/sandboxes/_include/wasm-cc/envoy_filter_http_wasm_example.cc
+++ /tmp/tmpe5xv7v2q/generated/rst/start/sandboxes/_include/wasm-cc/envoy_filter_http_wasm_updated_example.cc
@@ -65,8 +65,8 @@
for (auto& p : pairs) {
LOG_INFO(std::string(p.first) + std::string(" -> ") + std::string(p.second));
}
- addResponseHeader("X-Wasm-custom", "FOO");
- replaceResponseHeader("content-type", "text/plain; charset=utf-8");
+ addResponseHeader("X-Wasm-custom", "BAR");
+ replaceResponseHeader("content-type", "text/html; charset=utf-8");
removeResponseHeader("content-length");
return FilterHeadersStatus::Continue;
}
@@ -78,9 +78,9 @@
return FilterDataStatus::Continue;
}
-FilterDataStatus ExampleContext::onResponseBody(size_t body_buffer_length,
+FilterDataStatus ExampleContext::onResponseBody(size_t /* body_buffer_length */,
bool /* end_of_stream */) {
- setBuffer(WasmBufferType::HttpResponseBody, 0, body_buffer_length, "Hello, world\n");
+ setBuffer(WasmBufferType::HttpResponseBody, 0, 17, "Hello, Wasm world");
return FilterDataStatus::Continue;
}
Warning
These instructions for compiling an updated Wasm binary use the envoyproxy/envoy-build-ubuntu image. You will need 4-5GB of disk space to accommodate this image.
Stop the proxy server and compile the Wasm binary with the updated code:
$ docker-compose stop proxy
$ docker-compose -f docker-compose-wasm.yaml up --remove-orphans wasm_compile_update
The compiled binary should now be in the lib
folder.
$ ls -l lib
total 120
-r-xr-xr-x 1 root root 59641 Oct 20 00:00 envoy_filter_http_wasm_example.wasm
-r-xr-xr-x 1 root root 59653 Oct 20 10:16 envoy_filter_http_wasm_updated_example.wasm
Step 4: Edit the Dockerfile and restart the proxy¶
Edit the Dockerfile-proxy
recipe provided in the example to use the updated binary you created in step 3.
Find the COPY
line that adds the Wasm binary to the image:
1FROM envoyproxy/envoy-dev:latest
2COPY ./envoy.yaml /etc/envoy.yaml
3COPY ./lib/envoy_filter_http_wasm_example.wasm /lib/envoy_filter_http_wasm_example.wasm
4RUN chmod go+r /etc/envoy.yaml /lib/envoy_filter_http_wasm_example.wasm
5CMD ["/usr/local/bin/envoy", "-c", "/etc/envoy.yaml", "--service-cluster", "proxy"]
Replace this line with the following:
COPY ./lib/envoy_filter_http_wasm_updated_example.wasm /lib/envoy_filter_http_wasm_example.wasm
Now, rebuild and start the proxy container.
$ docker-compose up --build -d proxy
Step 5: Check the proxy has been updated¶
The Wasm filter should instead inject “Hello, Wasm world” at the end of the response body.
$ curl -s http://localhost:8000 | grep "Hello, Wasm world"
}Hello, Wasm world
The content-type
and x-wasm-custom
headers should also have changed
$ curl -v http://localhost:8000 | grep "content-type: "
content-type: text/html; charset=utf-8
$ curl -v http://localhost:8000 | grep "x-wasm-custom: "
x-wasm-custom: BAR
See also
- Envoy Wasm filter
Further information about the Envoy Wasm filter.
- Envoy Wasm API(V3)
The Envoy Wasm API - version 3.
- Proxy Wasm C++ SDK
WebAssembly for proxies (C++ SDK)