pub trait HttpClient {
// Required method
fn send_request(
&self,
upstream: &str,
headers: &[(&str, &str)],
body: Option<&[u8]>,
trailers: Option<&[(&str, &str)]>,
timeout: Duration,
) -> Result<HttpClientRequestHandle>;
}Expand description
An interface of the Envoy HTTP Client.
§Examples
§Basic usage of HttpClient:
use std::time::Duration;
use envoy::host::HttpClient;
let client = HttpClient::default();
let request_id = client.send_request(
"cluster_name",
&[("header", "value")],
Some(b"request body"),
Some(&[("trailer", "value")]),
Duration::from_secs(5),
)?;§Injecting HttpClient into a HTTP Filter as a dependency:
use envoy::host::HttpClient;
struct MyHttpFilter<'a> {
http_client: &'a dyn HttpClient,
}
impl<'a> MyHttpFilter<'a> {
/// Creates a new instance parameterized with a given [`HttpClient`] implementation.
pub fn new(http_client: &'a dyn HttpClient) -> Self {
MyHttpFilter { http_client }
}
/// Creates a new instance parameterized with the default [`HttpClient`] implementation.
pub fn default() -> Self {
Self::new(HttpClient::default())
}
}§Sending a request and receiving a response inside a HTTP Filter:
use std::time::Duration;
use envoy::error::format_err;
use envoy::extension::{HttpFilter, Result};
use envoy::extension::filter::http::{FilterHeadersStatus, RequestHeadersOps, Ops};
use envoy::host::HttpClient;
use envoy::host::http::client::{HttpClientRequestHandle, HttpClientResponseOps};
struct MyHttpFilter<'a> {
http_client: &'a dyn HttpClient,
active_request: Option<HttpClientRequestHandle>,
}
impl<'a> HttpFilter for MyHttpFilter<'a> {
fn on_request_headers(&mut self, _num_headers: usize, _end_of_stream: bool, ops: &dyn RequestHeadersOps) -> Result<FilterHeadersStatus> {
self.http_client.send_request(
"cluster_name",
&[("header", "value")],
Some(b"request body"),
Some(&[("trailer", "value")]),
Duration::from_secs(5),
)?;
Ok(FilterHeadersStatus::StopIteration) // stop further request processing
}
fn on_http_call_response(
&mut self,
request: HttpClientRequestHandle,
_num_headers: usize,
body_size: usize,
_num_trailers: usize,
filter_ops: &dyn Ops,
http_client_ops: &dyn HttpClientResponseOps,
) -> Result<()> {
if self.active_request != Some(request) {
// don't use `assert!()` to avoid panicing in production code
return Err(format_err!("received unexpected response from HttpClient"));
}
let response_headers = http_client_ops.http_call_response_headers()?;
let response_body = http_client_ops.http_call_response_body(0, body_size)?;
... look into response headers and response body ...
filter_ops.resume_request() // resume further request processing
}
}Required Methods§
Sourcefn send_request(
&self,
upstream: &str,
headers: &[(&str, &str)],
body: Option<&[u8]>,
trailers: Option<&[(&str, &str)]>,
timeout: Duration,
) -> Result<HttpClientRequestHandle>
fn send_request( &self, upstream: &str, headers: &[(&str, &str)], body: Option<&[u8]>, trailers: Option<&[(&str, &str)]>, timeout: Duration, ) -> Result<HttpClientRequestHandle>
Sends an HTTP request asynchronously.
§Arguments
upstream- name ofEnvoyClusterto send request to.headers- request headersbody- request bodytrailers- request trailerstimeout- request timeout
§Return value
opaque identifier of the request sent. Can be used to correlate requests and responses.
Implementations§
Source§impl dyn HttpClient
impl dyn HttpClient
Sourcepub fn default() -> &'static dyn HttpClient
pub fn default() -> &'static dyn HttpClient
Returns the default implementation that interacts with Envoy
through its ABI.