Skip to main content

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.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§