HttpClient

Trait HttpClient 

Source
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§

Source

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 of Envoy Cluster to send request to.
  • headers - request headers
  • body - request body
  • trailers - request trailers
  • timeout - request timeout
§Return value

opaque identifier of the request sent. Can be used to correlate requests and responses.

Implementations§

Source§

impl dyn HttpClient

Source

pub fn default() -> &'static dyn HttpClient

Returns the default implementation that interacts with Envoy through its ABI.

Implementors§