memorysafety / river

This repository is the home of the River reverse proxy application, based on the pingora library from Cloudflare.
https://www.memorysafety.org/initiative/reverse-proxy/
Apache License 2.0
1.72k stars 101 forks source link

Initial filter implementation #27

Closed jamesmunns closed 5 months ago

jamesmunns commented 5 months ago

Closes #24.

This introduces basic "Request Path Control" features - the ability to modify or block in-flight requests.

Additionally, this switches to the more complete http proxy facilities provided by pingora.

jamesmunns commented 5 months ago

When making a request:

curl --header "X-MyHeader-secret: 123" -vvvv --insecure https://fedora.local:4443

With this Control Path config:

# "Path Control" affects requests and responses as they are proxied
[basic-proxy.path-control]
# upstream request filters specifically allow for the cancellation or modification
# of requests, as they are being made.
#
# Filters are applied in the order they are specified. Multiple instances of
# each filter may be provided.
upstream-request-filters = [
    # Remove any headers with keys matching `pattern`
    { kind = "remove-header-key-regex", pattern = ".*(secret|SECRET).*" },
    # Add or replace (e.g. "Upsert") a fixed header with the given key and value
    { kind = "upsert-header", key = "x-proxy-friend", value = "river" },
]

We can see the requests being made, and the filter operations occurring:

2024-04-18T14:24:18.598712Z DEBUG pingora_proxy: Successfully get a new request    
2024-04-18T14:24:18.598784Z TRACE pingora_proxy: Request header: Parts { method: GET, uri: /, version: HTTP/1.1, headers: {"host": "fedora.local:4443", "user-agent": "curl/8.4.0", "accept": "*/*", "x-myheader-secret": "123"} }    
2024-04-18T14:24:18.599457Z DEBUG pingora_core::connectors: No reusable connection found for addr: 91.107.223.4:443, scheme: HTTPS,sni: onevariable.com,    
2024-04-18T14:24:18.621248Z DEBUG pingora_core::connectors::l4: connected to new server: 91.107.223.4:443    

!!!

2024-04-18T14:24:18.649995Z DEBUG river::proxy::request_modifiers: Removing header: "x-myheader-secret"
2024-04-18T14:24:18.650187Z DEBUG river::proxy::request_modifiers: Inserted header: x-proxy-friend: river
2024-04-18T14:24:18.650224Z DEBUG pingora_proxy::proxy_h1: Sending header to upstream RequestHeader { base: Parts { method: GET, uri: /, version: HTTP/1.1, headers: {"host": "fedora.local:4443", "user-agent": "curl/8.4.0", "accept": "*/*", "x-proxy-friend": "river"} }, header_name_map: Some({"host": CaseHeaderName(b"Host"), "user-agent": CaseHeaderName(b"User-Agent"), "accept": CaseHeaderName(b"Accept"), "x-proxy-friend": CaseHeaderName(b"x-proxy-friend")}), raw_path_fallback: [] }    

!!!

2024-04-18T14:24:18.650319Z TRACE pingora_core::protocols::http::v1::client: Writing request header: b"GET / HTTP/1.1\r\nHost: fedora.local:4443\r\nUser-Agent: curl/8.4.0\r\nAccept: */*\r\nx-proxy-friend: river\r\n\r\n"    
2024-04-18T14:24:18.650737Z DEBUG pingora_proxy::proxy_h1: finish sending body to upstream

(area highlighted by me with !!! showing the actions taken)

jamesmunns commented 5 months ago

Also added the same filters to the Response path as well.