pub trait ProxyHttp {
type CTX;
Show 31 methods
// Required methods
fn new_ctx(&self) -> Self::CTX;
async fn upstream_peer(
&self,
session: &mut Session,
ctx: &mut Self::CTX,
) -> Result<Box<HttpPeer>>;
// Provided methods
fn init_downstream_modules(&self, modules: &mut HttpModules) { ... }
async fn request_filter(
&self,
_session: &mut Session,
_ctx: &mut Self::CTX,
) -> Result<bool>
where Self::CTX: Send + Sync { ... }
async fn early_request_filter(
&self,
_session: &mut Session,
_ctx: &mut Self::CTX,
) -> Result<()>
where Self::CTX: Send + Sync { ... }
async fn request_body_filter(
&self,
_session: &mut Session,
_body: &mut Option<Bytes>,
_end_of_stream: bool,
_ctx: &mut Self::CTX,
) -> Result<()>
where Self::CTX: Send + Sync { ... }
fn request_cache_filter(
&self,
_session: &mut Session,
_ctx: &mut Self::CTX,
) -> Result<()> { ... }
fn cache_key_callback(
&self,
session: &Session,
_ctx: &mut Self::CTX,
) -> Result<CacheKey> { ... }
fn cache_miss(&self, session: &mut Session, _ctx: &mut Self::CTX) { ... }
async fn cache_hit_filter(
&self,
_session: &Session,
_meta: &CacheMeta,
_ctx: &mut Self::CTX,
) -> Result<bool>
where Self::CTX: Send + Sync { ... }
async fn proxy_upstream_filter(
&self,
_session: &mut Session,
_ctx: &mut Self::CTX,
) -> Result<bool>
where Self::CTX: Send + Sync { ... }
fn response_cache_filter(
&self,
_session: &Session,
_resp: &ResponseHeader,
_ctx: &mut Self::CTX,
) -> Result<RespCacheable> { ... }
fn cache_vary_filter(
&self,
_meta: &CacheMeta,
_ctx: &mut Self::CTX,
_req: &RequestHeader,
) -> Option<HashBinary> { ... }
fn cache_not_modified_filter(
&self,
session: &Session,
resp: &ResponseHeader,
_ctx: &mut Self::CTX,
) -> Result<bool> { ... }
async fn upstream_request_filter(
&self,
_session: &mut Session,
_upstream_request: &mut RequestHeader,
_ctx: &mut Self::CTX,
) -> Result<()>
where Self::CTX: Send + Sync { ... }
fn upstream_response_filter(
&self,
_session: &mut Session,
_upstream_response: &mut ResponseHeader,
_ctx: &mut Self::CTX,
) { ... }
async fn response_filter(
&self,
_session: &mut Session,
_upstream_response: &mut ResponseHeader,
_ctx: &mut Self::CTX,
) -> Result<()>
where Self::CTX: Send + Sync { ... }
fn upstream_response_body_filter(
&self,
_session: &mut Session,
_body: &mut Option<Bytes>,
_end_of_stream: bool,
_ctx: &mut Self::CTX,
) { ... }
fn upstream_response_trailer_filter(
&self,
_session: &mut Session,
_upstream_trailers: &mut HeaderMap,
_ctx: &mut Self::CTX,
) -> Result<()> { ... }
fn response_body_filter(
&self,
_session: &mut Session,
_body: &mut Option<Bytes>,
_end_of_stream: bool,
_ctx: &mut Self::CTX,
) -> Result<Option<Duration>>
where Self::CTX: Send + Sync { ... }
async fn response_trailer_filter(
&self,
_session: &mut Session,
_upstream_trailers: &mut HeaderMap,
_ctx: &mut Self::CTX,
) -> Result<Option<Bytes>>
where Self::CTX: Send + Sync { ... }
async fn logging(
&self,
_session: &mut Session,
_e: Option<&Error>,
_ctx: &mut Self::CTX,
)
where Self::CTX: Send + Sync { ... }
fn suppress_error_log(
&self,
_session: &Session,
_ctx: &Self::CTX,
_error: &Error,
) -> bool { ... }
fn error_while_proxy(
&self,
peer: &HttpPeer,
session: &mut Session,
e: Box<Error>,
_ctx: &mut Self::CTX,
client_reused: bool,
) -> Box<Error> { ... }
fn fail_to_connect(
&self,
_session: &mut Session,
_peer: &HttpPeer,
_ctx: &mut Self::CTX,
e: Box<Error>,
) -> Box<Error> { ... }
async fn fail_to_proxy(
&self,
session: &mut Session,
e: &Error,
_ctx: &mut Self::CTX,
) -> u16
where Self::CTX: Send + Sync { ... }
fn should_serve_stale(
&self,
_session: &mut Session,
_ctx: &mut Self::CTX,
error: Option<&Error>,
) -> bool { ... }
async fn connected_to_upstream(
&self,
_session: &mut Session,
_reused: bool,
_peer: &HttpPeer,
_fd: RawFd,
_digest: Option<&Digest>,
_ctx: &mut Self::CTX,
) -> Result<()>
where Self::CTX: Send + Sync { ... }
fn request_summary(&self, session: &Session, _ctx: &Self::CTX) -> String { ... }
fn is_purge(&self, _session: &Session, _ctx: &Self::CTX) -> bool { ... }
fn purge_response_filter(
&self,
_session: &Session,
_ctx: &mut Self::CTX,
_purge_status: PurgeStatus,
_purge_response: &mut Cow<'static, ResponseHeader>,
) -> Result<()> { ... }
}
Expand description
The interface to control the HTTP proxy
The methods in ProxyHttp are filters/callbacks which will be performed on all requests at their particular stage (if applicable).
If any of the filters returns Result::Err, the request will fail, and the error will be logged.
Required Associated Types§
Required Methods§
Provided Methods§
Sourcefn init_downstream_modules(&self, modules: &mut HttpModules)
fn init_downstream_modules(&self, modules: &mut HttpModules)
Set up downstream modules.
In this phase, users can add or configure HttpModules before the server starts up.
In the default implementation of this method, ResponseCompressionBuilder is added and disabled.
Sourceasync fn request_filter(
&self,
_session: &mut Session,
_ctx: &mut Self::CTX,
) -> Result<bool>
async fn request_filter( &self, _session: &mut Session, _ctx: &mut Self::CTX, ) -> Result<bool>
Handle the incoming request.
In this phase, users can parse, validate, rate limit, perform access control and/or return a response for this request.
If the user already sent a response to this request, an Ok(true)
should be returned so that
the proxy would exit. The proxy continues to the next phases when Ok(false)
is returned.
By default this filter does nothing and returns Ok(false)
.
Sourceasync fn early_request_filter(
&self,
_session: &mut Session,
_ctx: &mut Self::CTX,
) -> Result<()>
async fn early_request_filter( &self, _session: &mut Session, _ctx: &mut Self::CTX, ) -> Result<()>
Handle the incoming request before any downstream module is executed.
This function is similar to Self::request_filter() but executes before any other logic, including downstream module logic. The main purpose of this function is to provide finer grained control of the behavior of the modules.
Note that because this function is executed before any module that might provide access control or rate limiting, logic should stay in request_filter() if it can in order to be protected by said modules.
Sourceasync fn request_body_filter(
&self,
_session: &mut Session,
_body: &mut Option<Bytes>,
_end_of_stream: bool,
_ctx: &mut Self::CTX,
) -> Result<()>
async fn request_body_filter( &self, _session: &mut Session, _body: &mut Option<Bytes>, _end_of_stream: bool, _ctx: &mut Self::CTX, ) -> Result<()>
Handle the incoming request body.
This function will be called every time a piece of request body is received. The body
is
not the entire request body.
The async nature of this function allows to throttle the upload speed and/or executing heavy computation logic such as WAF rules on offloaded threads without blocking the threads who process the requests themselves.
Sourcefn request_cache_filter(
&self,
_session: &mut Session,
_ctx: &mut Self::CTX,
) -> Result<()>
fn request_cache_filter( &self, _session: &mut Session, _ctx: &mut Self::CTX, ) -> Result<()>
This filter decides if the request is cacheable and what cache backend to use
The caller can interact with Session.cache
to enable caching.
By default this filter does nothing which effectively disables caching.
Sourcefn cache_key_callback(
&self,
session: &Session,
_ctx: &mut Self::CTX,
) -> Result<CacheKey>
fn cache_key_callback( &self, session: &Session, _ctx: &mut Self::CTX, ) -> Result<CacheKey>
This callback generates the cache key
This callback is called only when cache is enabled for this request
By default this callback returns a default cache key generated from the request.
Sourcefn cache_miss(&self, session: &mut Session, _ctx: &mut Self::CTX)
fn cache_miss(&self, session: &mut Session, _ctx: &mut Self::CTX)
This callback is invoked when a cacheable response is ready to be admitted to cache
Sourceasync fn cache_hit_filter(
&self,
_session: &Session,
_meta: &CacheMeta,
_ctx: &mut Self::CTX,
) -> Result<bool>
async fn cache_hit_filter( &self, _session: &Session, _meta: &CacheMeta, _ctx: &mut Self::CTX, ) -> Result<bool>
This filter is called after a successful cache lookup and before the cache asset is ready to be used.
This filter allow the user to log or force expire the asset.
Sourceasync fn proxy_upstream_filter(
&self,
_session: &mut Session,
_ctx: &mut Self::CTX,
) -> Result<bool>
async fn proxy_upstream_filter( &self, _session: &mut Session, _ctx: &mut Self::CTX, ) -> Result<bool>
Decide if a request should continue to upstream after not being served from cache.
returns: Ok(true) if the request should continue, Ok(false) if a response was written by the callback and the session should be finished, or an error
This filter can be used for deferring checks like rate limiting or access control to when they actually needed after cache miss.
Sourcefn response_cache_filter(
&self,
_session: &Session,
_resp: &ResponseHeader,
_ctx: &mut Self::CTX,
) -> Result<RespCacheable>
fn response_cache_filter( &self, _session: &Session, _resp: &ResponseHeader, _ctx: &mut Self::CTX, ) -> Result<RespCacheable>
Decide if the response is cacheable
Sourcefn cache_vary_filter(
&self,
_meta: &CacheMeta,
_ctx: &mut Self::CTX,
_req: &RequestHeader,
) -> Option<HashBinary>
fn cache_vary_filter( &self, _meta: &CacheMeta, _ctx: &mut Self::CTX, _req: &RequestHeader, ) -> Option<HashBinary>
Decide how to generate cache vary key from both request and response
None means no variance is needed.
Sourcefn cache_not_modified_filter(
&self,
session: &Session,
resp: &ResponseHeader,
_ctx: &mut Self::CTX,
) -> Result<bool>
fn cache_not_modified_filter( &self, session: &Session, resp: &ResponseHeader, _ctx: &mut Self::CTX, ) -> Result<bool>
Decide if the incoming request’s condition fails against the cached response.
Returning Ok(true)
means that the response does not match against the condition, and
that the proxy can return 304 Not Modified
downstream.
An example is a conditional GET request with If-None-Match: "foobar"
. If the cached
response contains the ETag: "foobar"
, then the condition fails, and 304 Not Modified
should be returned. Else, the condition passes which means the full 200 OK
response must
be sent.
Sourceasync fn upstream_request_filter(
&self,
_session: &mut Session,
_upstream_request: &mut RequestHeader,
_ctx: &mut Self::CTX,
) -> Result<()>
async fn upstream_request_filter( &self, _session: &mut Session, _upstream_request: &mut RequestHeader, _ctx: &mut Self::CTX, ) -> Result<()>
Modify the request before it is sent to the upstream
Unlike Self::request_filter(), this filter allows to change the request headers to send to the upstream.
Sourcefn upstream_response_filter(
&self,
_session: &mut Session,
_upstream_response: &mut ResponseHeader,
_ctx: &mut Self::CTX,
)
fn upstream_response_filter( &self, _session: &mut Session, _upstream_response: &mut ResponseHeader, _ctx: &mut Self::CTX, )
Modify the response header from the upstream
The modification is before caching, so any change here will be stored in the cache if enabled.
Responses served from cache won’t trigger this filter. If the cache needed revalidation, only the 304 from upstream will trigger the filter (though it will be merged into the cached header, not served directly to downstream).
Sourceasync fn response_filter(
&self,
_session: &mut Session,
_upstream_response: &mut ResponseHeader,
_ctx: &mut Self::CTX,
) -> Result<()>
async fn response_filter( &self, _session: &mut Session, _upstream_response: &mut ResponseHeader, _ctx: &mut Self::CTX, ) -> Result<()>
Modify the response header before it is send to the downstream
The modification is after caching. This filter is called for all responses including responses served from cache.
Sourcefn upstream_response_body_filter(
&self,
_session: &mut Session,
_body: &mut Option<Bytes>,
_end_of_stream: bool,
_ctx: &mut Self::CTX,
)
fn upstream_response_body_filter( &self, _session: &mut Session, _body: &mut Option<Bytes>, _end_of_stream: bool, _ctx: &mut Self::CTX, )
Similar to Self::upstream_response_filter() but for response body
This function will be called every time a piece of response body is received. The body
is
not the entire response body.
Sourcefn upstream_response_trailer_filter(
&self,
_session: &mut Session,
_upstream_trailers: &mut HeaderMap,
_ctx: &mut Self::CTX,
) -> Result<()>
fn upstream_response_trailer_filter( &self, _session: &mut Session, _upstream_trailers: &mut HeaderMap, _ctx: &mut Self::CTX, ) -> Result<()>
Similar to Self::upstream_response_filter() but for response trailers
Sourcefn response_body_filter(
&self,
_session: &mut Session,
_body: &mut Option<Bytes>,
_end_of_stream: bool,
_ctx: &mut Self::CTX,
) -> Result<Option<Duration>>
fn response_body_filter( &self, _session: &mut Session, _body: &mut Option<Bytes>, _end_of_stream: bool, _ctx: &mut Self::CTX, ) -> Result<Option<Duration>>
Similar to Self::response_filter() but for response body chunks
Sourceasync fn response_trailer_filter(
&self,
_session: &mut Session,
_upstream_trailers: &mut HeaderMap,
_ctx: &mut Self::CTX,
) -> Result<Option<Bytes>>
async fn response_trailer_filter( &self, _session: &mut Session, _upstream_trailers: &mut HeaderMap, _ctx: &mut Self::CTX, ) -> Result<Option<Bytes>>
Similar to Self::response_filter() but for response trailers. Note, returning an Ok(Some(Bytes)) will result in the downstream response trailers being written to the response body.
TODO: make this interface more intuitive
Sourceasync fn logging(
&self,
_session: &mut Session,
_e: Option<&Error>,
_ctx: &mut Self::CTX,
)
async fn logging( &self, _session: &mut Session, _e: Option<&Error>, _ctx: &mut Self::CTX, )
This filter is called when the entire response is sent to the downstream successfully or there is a fatal error that terminate the request.
An error log is already emitted if there is any error. This phase is used for collecting metrics and sending access logs.
Sourcefn suppress_error_log(
&self,
_session: &Session,
_ctx: &Self::CTX,
_error: &Error,
) -> bool
fn suppress_error_log( &self, _session: &Session, _ctx: &Self::CTX, _error: &Error, ) -> bool
A value of true means that the log message will be suppressed. The default value is false.
Sourcefn error_while_proxy(
&self,
peer: &HttpPeer,
session: &mut Session,
e: Box<Error>,
_ctx: &mut Self::CTX,
client_reused: bool,
) -> Box<Error>
fn error_while_proxy( &self, peer: &HttpPeer, session: &mut Session, e: Box<Error>, _ctx: &mut Self::CTX, client_reused: bool, ) -> Box<Error>
This filter is called when there is an error after a connection is established (or reused) to the upstream.
Sourcefn fail_to_connect(
&self,
_session: &mut Session,
_peer: &HttpPeer,
_ctx: &mut Self::CTX,
e: Box<Error>,
) -> Box<Error>
fn fail_to_connect( &self, _session: &mut Session, _peer: &HttpPeer, _ctx: &mut Self::CTX, e: Box<Error>, ) -> Box<Error>
This filter is called when there is an error in the process of establishing a connection to the upstream.
In this filter the user can decide whether the error is retry-able by marking the error e
.
If the error can be retried, Self::upstream_peer() will be called again so that the user can decide whether to send the request to the same upstream or another upstream that is possibly available.
Sourceasync fn fail_to_proxy(
&self,
session: &mut Session,
e: &Error,
_ctx: &mut Self::CTX,
) -> u16
async fn fail_to_proxy( &self, session: &mut Session, e: &Error, _ctx: &mut Self::CTX, ) -> u16
This filter is called when the request encounters a fatal error.
Users may write an error response to the downstream if the downstream is still writable.
The response status code of the error response maybe returned for logging purpose.
Sourcefn should_serve_stale(
&self,
_session: &mut Session,
_ctx: &mut Self::CTX,
error: Option<&Error>,
) -> bool
fn should_serve_stale( &self, _session: &mut Session, _ctx: &mut Self::CTX, error: Option<&Error>, ) -> bool
Decide whether should serve stale when encountering an error or during revalidation
An implementation should follow https://datatracker.ietf.org/doc/html/rfc9111#section-4.2.4 https://www.rfc-editor.org/rfc/rfc5861#section-4
This filter is only called if cache is enabled.
Sourceasync fn connected_to_upstream(
&self,
_session: &mut Session,
_reused: bool,
_peer: &HttpPeer,
_fd: RawFd,
_digest: Option<&Digest>,
_ctx: &mut Self::CTX,
) -> Result<()>
async fn connected_to_upstream( &self, _session: &mut Session, _reused: bool, _peer: &HttpPeer, _fd: RawFd, _digest: Option<&Digest>, _ctx: &mut Self::CTX, ) -> Result<()>
This filter is called when the request just established or reused a connection to the upstream
This filter allows user to log timing and connection related info.
Sourcefn request_summary(&self, session: &Session, _ctx: &Self::CTX) -> String
fn request_summary(&self, session: &Session, _ctx: &Self::CTX) -> String
This callback is invoked every time request related error log needs to be generated
Users can define what is important to be written about this request via the returned string.
Sourcefn is_purge(&self, _session: &Session, _ctx: &Self::CTX) -> bool
fn is_purge(&self, _session: &Session, _ctx: &Self::CTX) -> bool
Whether the request should be used to invalidate(delete) the HTTP cache
true
: this request will be used to invalidate the cache.false
: this request is a treated as a normal request
Sourcefn purge_response_filter(
&self,
_session: &Session,
_ctx: &mut Self::CTX,
_purge_status: PurgeStatus,
_purge_response: &mut Cow<'static, ResponseHeader>,
) -> Result<()>
fn purge_response_filter( &self, _session: &Session, _ctx: &mut Self::CTX, _purge_status: PurgeStatus, _purge_response: &mut Cow<'static, ResponseHeader>, ) -> Result<()>
This filter is called after the proxy cache generates the downstream response to the purge request (to invalidate or delete from the HTTP cache), based on the purge status, which indicates whether the request succeeded or failed.
The filter allows the user to modify or replace the generated downstream response.
If the filter returns Err
, the proxy will instead send a 500 response.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.