Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

README.md

Overwrite Header Plugin

This plugin demonstrates conditional header replacement with different behaviors for request and response headers. For request headers, it only replaces existing headers (conditional overwrite). For response headers, it always sets the header value, creating it if it doesn't exist (unconditional upsert). Use this plugin when you need to standardize header values, enforce header policies, or learn the differences between header manipulation APIs. It operates during the request headers and response headers processing phases.

How It Works

Request Headers (Conditional Replacement)

  1. The proxy receives an HTTP request and invokes on_http_request_headers.

  2. The plugin checks if the RequestHeader header exists by reading its value.

  3. If the header exists: The plugin replaces its value with "changed".

  4. If the header doesn't exist: The plugin does nothing (header is not added).

This pattern is useful when you want to normalize existing headers without adding new ones.

Response Headers (Unconditional Upsert)

  1. The proxy receives an HTTP response from the upstream server and invokes on_http_response_headers.

  2. The plugin unconditionally calls replaceResponseHeader() / ReplaceHttpResponseHeader() / set_http_response_header() with ResponseHeader: changed.

  3. If the header exists: Its value is replaced with "changed".

  4. If the header doesn't exist: The header is created with value "changed".

This pattern is useful when you want to ensure a header is always present with a specific value.

Implementation Notes

  • Conditional logic: Demonstrates checking for header existence before mutation using getRequestHeader()->size() (C++) or equivalent patterns in other languages.
  • API distinction: Contrasts the difference between appending values (addHeader) versus upserting values (replaceHeader).
  • Phase-specific behavior: Runs in both request and response phases, doing a conditional overwrite for requests and an unconditional upsert for responses.

Configuration

No configuration required. Header names (RequestHeader, ResponseHeader) and values ("changed") are hardcoded in the plugin source.

Customization:

// C++
const auto header_key = "X-Custom-Header";
replaceRequestHeader(header_key, "new-value");
// Rust
const REQUEST_HEADER_KEY: &str = "X-Custom-Header";
const REQUEST_HEADER_VALUE: &str = "new-value";

Build

Build the plugin for any supported language from the plugins/ directory:

# Rust
bazelisk build //samples/overwrite_header:plugin_rust.wasm

# C++
bazelisk build //samples/overwrite_header:plugin_cpp.wasm

# Go
bazelisk build //samples/overwrite_header:plugin_go.wasm

Test

Run the unit tests defined in tests.textpb:

# Using Docker (recommended)
docker run -it -v $(pwd):/mnt \
    us-docker.pkg.dev/service-extensions-samples/plugins/wasm-tester:main \
    --proto /mnt/samples/overwrite_header/tests.textpb \
    --plugin /mnt/bazel-bin/samples/overwrite_header/plugin_rust.wasm

# Using Bazel (all languages)
bazelisk test --test_output=all //samples/overwrite_header:tests

Expected Behavior

Derived from tests.textpb:

Scenario Description
DoNotAddRequestHeader Skips modifying the request header since the target header is completely missing.
DoAddResponseHeader Unconditionally adds the response header even though it was originally absent.
OverwriteRequestHeader Conditionally overwrites the value of the existing request header.
OverwriteResponseHeader Unconditionally overwrites the value of the existing response header.

Available Languages

Use Cases

Request headers (conditional):

  • Normalize authentication tokens only if present
  • Sanitize user-provided headers without adding defaults
  • Enforce format requirements on existing headers

Response headers (unconditional):

  • Ensure security headers are always present (e.g., X-Frame-Options, X-Content-Type-Options)
  • Override upstream header values with policy-enforced values
  • Add or update cache-control headers

Example: Security headers:

FilterHeadersStatus onResponseHeaders(...) override {
    // Always enforce security headers
    replaceResponseHeader("X-Frame-Options", "DENY");
    replaceResponseHeader("X-Content-Type-Options", "nosniff");
    replaceResponseHeader("Strict-Transport-Security", "max-age=31536000");
    return FilterHeadersStatus::Continue;
}