### Provide Method Example (Nightly) Source: https://docs.rs/pingora/0.8.0/pingora/prelude/trait.ErrorTrait.html An example of using the experimental `provide()` method for accessing error context. ```APIDOC ## Example: Provide Method (Nightly) ### Code ```rust #![feature(error_generic_member_access)] use core::fmt; use core::error::{request_ref, Request}; #[derive(Debug)] enum MyLittleTeaPot { Empty, } #[derive(Debug)] struct MyBacktrace { // ... } impl MyBacktrace { fn new() -> MyBacktrace { // ... MyBacktrace {} } } #[derive(Debug)] struct Error { backtrace: MyBacktrace, } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Example Error") } } impl std::error::Error for Error { fn provide<'a>(&'a self, request: &mut Request<'a>) { request .provide_ref::(&self.backtrace); } } fn main() { let backtrace = MyBacktrace::new(); let error = Error { backtrace }; let dyn_error = &error as &dyn std::error::Error; let backtrace_ref = request_ref::(dyn_error).unwrap(); assert!(core::ptr::eq(&error.backtrace, backtrace_ref)); assert!(request_ref::(dyn_error).is_none()); } ``` ``` -------------------------------- ### Provide Method Example (Experimental) Source: https://docs.rs/pingora/0.8.0/pingora/trait.ErrorTrait.html An example demonstrating the experimental `provide()` method for type-based access to error context. ```APIDOC ### §Example ```rust #![feature(error_generic_member_access)] use core::fmt; use core::error::{request_ref, Request}; #[derive(Debug)] enum MyLittleTeaPot { Empty, } #[derive(Debug)] struct MyBacktrace { // ... } impl MyBacktrace { fn new() -> MyBacktrace { // ... } } #[derive(Debug)] struct Error { backtrace: MyBacktrace, } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Example Error") } } impl std::error::Error for Error { fn provide<'a>(&'a self, request: &mut Request<'a>) { request .provide_ref::(&self.backtrace); } } fn main() { let backtrace = MyBacktrace::new(); let error = Error { backtrace }; let dyn_error = &error as &dyn std::error::Error; let backtrace_ref = request_ref::(dyn_error).unwrap(); assert!(core::ptr::eq(&error.backtrace, backtrace_ref)); assert!(request_ref::(dyn_error).is_none()); } ``` ``` -------------------------------- ### Pingora Prelude - Core Types and Utilities Source: https://docs.rs/pingora/0.8.0/pingora/prelude/index.html This section covers the essential types and utilities provided by the pingora prelude, useful for getting started with pingora. ```APIDOC ## Modules ### `fast_timeout` The fast and more complicated version of pingora-timeout. ### `timer` Lightweight timer for systems with high rate of operations with timeout associated with them. ## Structs ### `Elapsed` The error type returned when the timeout is reached. ### `Error` The struct that represents an error. ### `HttpPeer` A peer representing the remote HTTP server to connect to. ### `LoadBalancer` (`lb`) A LoadBalancer instance contains the service discovery, health check and backend selection all together. ### `Opt` Command-line options. ### `RequestHeader` The HTTP request header type. ### `ResponseHeader` The HTTP response header type. ### `Server` The server object. ### `Session` (`proxy`) The established HTTP session. ### `TcpHealthCheck` (`lb`) TCP health check. ### `Timeout` The timeout future returned by the timeout functions. ### `TokioTimeout` The timeout generated by tokio_timeout(). ## Enums ### `ErrorSource` The source of the error. ### `ErrorType` Predefined type of errors. ### `ImmutStr` A data struct that holds either immutable string or reference to static str. Compared to String or `Box`, it avoids memory allocation on static str. ### `RetryType` Whether the request can be retried after encountering this error. ## Traits ### `Context` Helper trait to add more context to a given error. ### `ErrorTrait` `Error` is a trait representing the basic expectations for error values, i.e., values of type `E` in `Result`. ### `OkOrErr` Helper trait to convert an Option to an Error with context. ### `OrErr` Helper trait to chain errors with context. ### `ProxyHttp` (`proxy`) The interface to control the HTTP proxy. ### `ToTimeout` The interface to start a timeout. ## Functions ### `background_service` Helper function to create a background service with a human readable name. ### `http_proxy` (`proxy`) Create an `HttpProxy` without wrapping it in a `Service`. ### `http_proxy_service` (`proxy`) Create a Service from the user implemented ProxyHttp. ### `sleep` Similar to tokio::time::sleep but more efficient. ### `timeout` Similar to tokio::time::timeout but more efficient. ### `tokio_timeout` The tokio::time::timeout with just lazy timer initialization. ## Type Aliases ### `BError` The boxed Error, the desired way to pass Error. ### `Result` Syntax sugar for `std::Result`. ### `RoundRobin` (`lb`) Round robin selection on weighted backends. ``` -------------------------------- ### Use Entry API for In-place Manipulation Source: https://docs.rs/pingora/0.8.0/pingora/http/struct.HMap.html Illustrates using the `entry` API to get an entry for a key, allowing for in-place manipulation. This example counts occurrences of header names, handling case-insensitivity. ```rust let mut map: HeaderMap = HeaderMap::default(); let headers = &[ "content-length", "x-hello", "Content-Length", "x-world", ]; for &header in headers { let counter = map.entry(header).or_insert(0); *counter += 1; } assert_eq!(map["content-length"], 2); assert_eq!(map["x-hello"], 1); ``` -------------------------------- ### Box::new_in with System allocator example Source: https://docs.rs/pingora/0.8.0/pingora/cache/storage/type.MissHandler.html Shows how to allocate a Box with a specific allocator, using the System allocator in this example. This requires the 'allocator_api' feature. ```rust #![feature(allocator_api)] use std::alloc::System; let five = Box::new_in(5, System); ``` -------------------------------- ### start Method Source: https://docs.rs/pingora/0.8.0/pingora/services/background/trait.BackgroundService.html Called when the Pingora server starts services. The background service can return at any time or wait for the `shutdown` signal. ```rust fn start<'life0, 'async_trait>( &'life0 self, _shutdown: Receiver, ) -> Pin + Send + 'async_trait>> where 'life0: 'async_trait, Self: Sync + 'async_trait ``` -------------------------------- ### Service Start Method Source: https://docs.rs/pingora/0.8.0/pingora/services/trait.Service.html Starts the service without readiness notification. This is a simpler alternative to `Self::start_service()` for services that do not need to control readiness signaling. The default implementation is a no-op. ```rust fn start_service<'life0, 'async_trait>( &'life0 mut self, _fds: Option>>, _shutdown: Receiver, _listeners_per_fd: usize, ) -> Pin + Send + 'async_trait>> where 'life0: 'async_trait, Self: 'async_trait { ... } ``` -------------------------------- ### BackgroundService Start with Ready Notifier Source: https://docs.rs/pingora/0.8.0/pingora/lb/prelude/struct.LoadBalancer.html Implementation of the `start_with_ready_notifier` method for the `BackgroundService` trait. This method is called when the Pingora server starts services and should signal readiness. ```rust fn start_with_ready_notifier<'life0, 'async_trait>( &'life0 self, shutdown: Receiver, ready: ServiceReadyNotifier, ) -> Pin + Send + 'async_trait>> where 'life0: 'async_trait, LoadBalancer: 'async_trait, ``` -------------------------------- ### Source Method Example Source: https://docs.rs/pingora/0.8.0/pingora/trait.ErrorTrait.html A detailed example showcasing the usage of the `source()` method to retrieve the underlying error. ```APIDOC ### §Examples ```rust use std::error::Error; use std::fmt; #[derive(Debug)] struct SuperError { source: SuperErrorSideKick, } impl fmt::Display for SuperError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "SuperError is here!") } } impl Error for SuperError { fn source(&self) -> Option<&(dyn Error + 'static)> { Some(&self.source) } } #[derive(Debug)] struct SuperErrorSideKick; impl fmt::Display for SuperErrorSideKick { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "SuperErrorSideKick is here!") } } impl Error for SuperErrorSideKick {} fn get_super_error() -> Result<(), SuperError> { Err(SuperError { source: SuperErrorSideKick }) } fn main() { match get_super_error() { Err(e) => { println!("Error: {e}"); println!("Caused by: {}", e.source().unwrap()); } _ => println!("No error"), } } ``` ``` -------------------------------- ### LoadBalancer Start Function Source: https://docs.rs/pingora/0.8.0/pingora/lb/struct.LoadBalancer.html Details the `start` function for the LoadBalancer service, which is responsible for initializing all services when the Pingora server starts. It can operate in the background or wait for a shutdown signal. ```APIDOC ## fn start<'life0, 'async_trait>( &'life0 self, shutdown: Receiver, ) -> Pin + Send + 'async_trait>> where 'life0: 'async_trait, LoadBalancer: 'async_trait, ### Description This function is called when the pingora server tries to start all the services. The background service can return at anytime or wait for the `shutdown` signal. ### Method (Not applicable - this is a function signature, not an HTTP endpoint) ### Endpoint (Not applicable - this is a function signature, not an HTTP endpoint) ### Parameters #### Path Parameters (None) #### Query Parameters (None) #### Request Body (None) ### Request Example (Not applicable) ### Response #### Success Response (200) (Not applicable - returns a Future) #### Response Example (Not applicable) ``` -------------------------------- ### start_with_ready_notifier Method Source: https://docs.rs/pingora/0.8.0/pingora/services/background/trait.BackgroundService.html Called when the Pingora server starts services. The service should signal readiness using `ready_notifier.notify_ready()` after initialization. It can return anytime or wait for the `shutdown` signal. Defaults to signaling readiness immediately and calling `start`. ```rust fn start_with_ready_notifier<'life0, 'async_trait>( &'life0 self, shutdown: Receiver, ready_notifier: ServiceReadyNotifier, ) -> Pin + Send + 'async_trait>> where 'life0: 'async_trait, Self: Sync + 'async_trait ``` -------------------------------- ### Get Start Time (InspectableSpan) Source: https://docs.rs/pingora/0.8.0/pingora/cache/trace/type.Span.html Retrieves the start time of the span. Part of the `InspectableSpan` trait. ```rust fn start_time(&self) -> SystemTime ``` -------------------------------- ### Server Bootstrapping and Running Source: https://docs.rs/pingora/0.8.0/pingora/prelude/struct.Server.html Methods for preparing and running the Pingora server. ```APIDOC ## Server Bootstrapping and Running ### `bootstrap` #### Description Prepare the server to start. When trying to zero downtime upgrade from an older version of the server which is already running, this function will try to get all its listening sockets in order to take them over. #### Method `pub fn bootstrap(&mut self)` ### `bootstrap_as_a_service` #### Description Create a service that will run to prepare the service to start. The created service will handle the zero-downtime upgrade from an older version of the server to this one. It will try to get all its listening sockets in order to take them over. Other bootstrapping functionality like sentry initialization will also be handled, but as a service that will complete before any other service starts. #### Method `pub fn bootstrap_as_a_service(&mut self) -> ServiceHandle` ### `run_forever` #### Description Start the server using `Self::run` and default `RunArgs`. This function will block forever until the server needs to quit. So this would be the last function to call for this object. Note: this function may fork the process for daemonization, so any additional threads created before this function will be lost to any service logic once this function is called. #### Method `pub fn run_forever(self) -> !` ### `run` #### Description Run the server until execution finished. This function will run until the server has been instructed to shut down through a signal, and will then wait for all services to finish and runtimes to exit. Note: if daemonization is enabled in the config, this function will never return. Instead it will either start the daemon process and exit, or panic if daemonization fails. #### Method `pub fn run(self, run_args: RunArgs)` ``` -------------------------------- ### Get Sub-slice from BufRef Source: https://docs.rs/pingora/0.8.0/pingora/utils/struct.BufRef.html Returns a sub-slice of the provided buffer using the BufRef's start and length. This operation is O(1). ```rust pub fn get<'a>(&self, buf: &'a [u8]) -> &'a [u8] ``` -------------------------------- ### Bootstrap Server for Execution Source: https://docs.rs/pingora/0.8.0/pingora/prelude/struct.Server.html Prepares the server for startup, attempting to take over listening sockets for zero-downtime upgrades. ```rust pub fn bootstrap(&mut self) ``` -------------------------------- ### Create Server with Options and Configuration Source: https://docs.rs/pingora/0.8.0/pingora/prelude/struct.Server.html Creates a new Server instance using provided raw options and server configuration. This is for custom command-line parsing. ```rust pub fn new_with_opt_and_conf( raw_opt: impl Into>, conf: ServerConf, ) -> Server ``` -------------------------------- ### Get Cached Date in HTTP Headers Source: https://docs.rs/pingora/0.8.0/pingora/protocols/http/date/fn.get_cached_date.html Retrieves the current date formatted for HTTP headers. No specific setup is required beyond importing the function. ```rust pub fn get_cached_date() -> HeaderValue ``` -------------------------------- ### Getting Metadata with `and_then` Source: https://docs.rs/pingora/0.8.0/pingora/prelude/type.Result.html This example demonstrates using `and_then` to chain metadata retrieval operations, handling potential errors like 'NotFound'. Note the platform-specific behavior of path resolution. ```rust use std::{io::ErrorKind, path::Path}; // Note: on Windows "/" maps to "C:\\" let root_modified_time = Path::new("/").metadata().and_then(|md| md.modified()); assert!(root_modified_time.is_ok()); let should_fail = Path::new("/bad/path").metadata().and_then(|md| md.modified()); assert!(should_fail.is_err()); assert_eq!(should_fail.unwrap_err().kind(), ErrorKind::NotFound); ``` -------------------------------- ### Add Services and Dependencies with ServiceHandle Source: https://docs.rs/pingora/0.8.0/pingora/services/struct.ServiceHandle.html Demonstrates how to add multiple services to a server and establish dependencies between them using ServiceHandle. This ensures that services like the API start only after their dependencies (database, cache) are ready. ```rust let db_handle = server.add_service(database_service); let cache_handle = server.add_service(cache_service); let api_handle = server.add_service(api_service); api_handle.add_dependency(&db_handle); api_handle.add_dependency(&cache_handle); ``` -------------------------------- ### Receiver::borrow Example Source: https://docs.rs/pingora/0.8.0/pingora/server/type.ShutdownWatch.html Demonstrates how to use the `borrow` method to get a reference to the latest value without marking it as seen. Be cautious of potential deadlocks with long-lived borrows across await points. ```rust use tokio::sync::watch; let (_, rx) = watch::channel("hello"); assert_eq!(*rx.borrow(), "hello"); ``` -------------------------------- ### Box::new Example Source: https://docs.rs/pingora/0.8.0/pingora/cache/storage/type.HitHandler.html Demonstrates creating a Box using Box::new and converting a value into a Box using Box::from. ```rust let x = 5; let boxed = Box::new(5); assert_eq!(Box::from(x), boxed); ``` -------------------------------- ### Start GenBackgroundService Source: https://docs.rs/pingora/0.8.0/pingora/services/background/struct.GenBackgroundService.html This function is invoked when the server is ready to initiate the service. It manages the service's lifecycle and dependencies. ```rust fn start_service<'life0, 'async_trait>( &'life0 mut self, _fds: Option>>, shutdown: Receiver, _listeners_per_fd: usize, ready: ServiceReadyNotifier, ) -> Pin + Send + 'async_trait>> where 'life0: 'async_trait, GenBackgroundService: 'async_trait, ``` -------------------------------- ### Service Startup Source: https://docs.rs/pingora/0.8.0/pingora/lb/prelude/struct.LoadBalancer.html This section details the `start` function used to initiate Pingora services. It can run indefinitely or until a shutdown signal is received. ```APIDOC ## fn start<'life0, 'async_trait>( &'life0 self, shutdown: Receiver, ) -> Pin + Send + 'async_trait>> where 'life0: 'async_trait, LoadBalancer: 'async_trait, ### Description This function is called when the pingora server tries to start all the services. The background service can return at anytime or wait for the `shutdown` signal. ### Method (Implicitly called by the server, not a direct API endpoint) ### Endpoint (N/A - internal function) ### Parameters #### Path Parameters (None) #### Query Parameters (None) #### Request Body (None) ### Request Example (N/A) ### Response #### Success Response (Implicit) - `Pin + Send + 'async_trait>>`: A future that completes when the service stops. #### Response Example (N/A) ``` -------------------------------- ### Implementing ErrorTrait Example Source: https://docs.rs/pingora/0.8.0/pingora/prelude/trait.ErrorTrait.html An example demonstrating how to implement the Error trait for a custom error type. ```APIDOC ## Example: Implementing ErrorTrait ### Code ```rust use std::error::Error; use std::fmt; use std::path::PathBuf; #[derive(Debug)] struct ReadConfigError { path: PathBuf } impl fmt::Display for ReadConfigError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let path = self.path.display(); write!(f, "unable to read configuration at {path}") } } impl Error for ReadConfigError {} ``` ``` -------------------------------- ### Set Start Time Source: https://docs.rs/pingora/0.8.0/pingora/cache/trace/type.Span.html Sets the start time for the span. The time is provided by a closure returning a `SystemTime`. ```rust pub fn set_start_time(&mut self, f: F) where F: FnOnce() -> SystemTime, ``` -------------------------------- ### Server Constructors Source: https://docs.rs/pingora/0.8.0/pingora/prelude/struct.Server.html Methods for creating new Server instances. ```APIDOC ## Server Constructors ### `new_with_opt_and_conf` #### Description Create a new `Server`, using the `Opt` and `ServerConf` values provided. This method is intended for pingora frontends that are NOT using the built-in command line and configuration file parsing, and are instead using their own. If a configuration file path is provided as part of `opt`, it will be ignored and a warning will be logged. #### Method `pub fn new_with_opt_and_conf( raw_opt: impl Into>, conf: ServerConf, ) -> Server` ### `new` #### Description Create a new `Server`. Only one `Server` needs to be created for a process. A `Server` can hold multiple independent services. Command line options can either be passed by parsing the command line arguments via `Opt::parse_args()`, or be generated by other means. #### Method `pub fn new(opt: impl Into>) -> Result>` ``` -------------------------------- ### Bootstrap Server as a Service Source: https://docs.rs/pingora/0.8.0/pingora/prelude/struct.Server.html Creates a service to handle server bootstrapping, including zero-downtime upgrades and initialization tasks. ```rust pub fn bootstrap_as_a_service(&mut self) -> ServiceHandle ``` -------------------------------- ### Create a new PeerOptions instance Source: https://docs.rs/pingora/0.8.0/pingora/upstreams/peer/struct.PeerOptions.html Initializes a new `PeerOptions` struct with default values. This is the starting point for configuring peer connection settings. ```rust pub fn new() -> PeerOptions ``` -------------------------------- ### Error Display Example Source: https://docs.rs/pingora/0.8.0/pingora/prelude/trait.ErrorTrait.html Example demonstrating how an error's Display implementation is used to format error messages. ```rust let err = "NaN".parse::().unwrap_err(); assert_eq!(err.to_string(), "invalid digit found in string"); ``` -------------------------------- ### Example Implementation: BlocklistFilter Source: https://docs.rs/pingora/0.8.0/pingora/listeners/connection_filter/trait.ConnectionFilter.html An example implementation of the ConnectionFilter trait that blocks connections from a predefined list of IP addresses. ```APIDOC ## Example ```rust use async_trait::async_trait; use pingora_core::listeners::ConnectionFilter; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; #[derive(Debug)] struct BlocklistFilter { blocked_ips: Vec, } #[async_trait] impl ConnectionFilter for BlocklistFilter { async fn should_accept(&self, addr: &SocketAddr) -> bool { !self.blocked_ips.contains(&addr.ip()) } } ``` ``` -------------------------------- ### Create By Reference Adapter for Allocator Source: https://docs.rs/pingora/0.8.0/pingora/prelude/type.BError.html Example of creating a "by reference" adapter for an `Allocator` instance using the `by_ref` method. This is a nightly-only experimental API. ```rust fn by_ref(&self) -> &Self ``` -------------------------------- ### Get Type ID of a Type Source: https://docs.rs/pingora/0.8.0/pingora/lb/selection/algorithms/struct.Random.html Gets the `TypeId` of the current type. This is a blanket implementation for any type that is 'static and ?Sized. ```rust fn type_id(&self) -> TypeId; ``` -------------------------------- ### Create New Server Instance Source: https://docs.rs/pingora/0.8.0/pingora/prelude/struct.Server.html Creates a new Server instance, optionally parsing command-line arguments. Only one Server should be created per process. ```rust pub fn new(opt: impl Into>) -> Result> ``` -------------------------------- ### Get TypeId of any type T Source: https://docs.rs/pingora/0.8.0/pingora/apps/struct.HttpPersistentSettings.html Gets the `TypeId` of `self`. This is part of the `Any` trait implementation and is useful for runtime type identification. ```rust fn type_id(&self) -> TypeId ``` -------------------------------- ### Create HttpProxy Instance Source: https://docs.rs/pingora/0.8.0/pingora/proxy/struct.HttpProxy.html Instantiate a new HttpProxy with a given ProxyHttp implementation and ServerConf. Remember to call handle_init_modules() afterwards, or prefer using http_proxy_service() for automatic initialization. ```rust use pingora_proxy::HttpProxy; use std::sync::Arc; let mut proxy = HttpProxy::new(my_proxy_app, server_conf); proxy.handle_init_modules(); let proxy = Arc::new(proxy); // Use proxy.process_new_http() in your custom accept loop ``` -------------------------------- ### Get Stream Reference - HttpSession Source: https://docs.rs/pingora/0.8.0/pingora/protocols/http/client/enum.HttpSession.html Gets a reference to the underlying Stream for an HTTP/1 session. Returns `None` if the session is over HTTP/2. ```rust pub fn stream(&self) -> Option<&Box> ``` -------------------------------- ### HttpProxy::handle_init_modules Source: https://docs.rs/pingora/0.8.0/pingora/proxy/struct.HttpProxy.html Initializes the downstream modules for the HttpProxy. ```APIDOC ## pub fn handle_init_modules(&mut self) ### Description Initialize the downstream modules for this proxy. This method must be called after creating an `HttpProxy` with `HttpProxy::new()` and before processing any requests. It invokes `ProxyHttp::init_downstream_modules()` to set up any HTTP modules configured by the user’s proxy implementation. Note: When using `http_proxy_service()` or `http_proxy_service_with_name()`, this method is called automatically. ### Parameters - `&mut self` - A mutable reference to the HttpProxy instance. ``` -------------------------------- ### Get the number of extensions Source: https://docs.rs/pingora/0.8.0/pingora/cache/meta/struct.Extensions.html Use `len` to get the current number of extensions stored in the map. Returns `0` if empty. ```rust let mut ext = Extensions::new(); assert_eq!(ext.len(), 0); ext.insert(5i32); assert_eq!(ext.len(), 1); ``` -------------------------------- ### Implementing ErrorTrait Example Source: https://docs.rs/pingora/0.8.0/pingora/trait.ErrorTrait.html An example demonstrating how to implement the `Error` trait for a custom error type, including `Debug` and `Display` implementations. ```APIDOC ### Example Implementing the `Error` trait only requires that `Debug` and `Display` are implemented too. ```rust use std::error::Error; use std::fmt; use std::path::PathBuf; #[derive(Debug)] struct ReadConfigError { path: PathBuf } impl fmt::Display for ReadConfigError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let path = self.path.display(); write!(f, "unable to read configuration at {path}") } } impl Error for ReadConfigError {} ``` ``` -------------------------------- ### HTTP Method Constants and Usage Source: https://docs.rs/pingora/0.8.0/pingora/http/struct.Method.html Demonstrates how to use Method constants and check their properties. Ensure the http crate is a dependency. ```rust use http::Method; assert_eq!(Method::GET, Method::from_bytes(b"GET").unwrap()); assert!(Method::GET.is_idempotent()); assert_eq!(Method::POST.as_str(), "POST"); ``` -------------------------------- ### Create and Prepare Subrequest Source: https://docs.rs/pingora/0.8.0/pingora/proxy/struct.SubrequestSpawner.html Creates a subrequest, returning a PreparedSubrequest and a SubrequestHandle. The subrequest can be run by calling its `run()` method. ```rust pub fn create_subrequest( &self, session: &Session, ctx: Ctx, ) -> (PreparedSubrequest, SubrequestHandle) ``` -------------------------------- ### Get Underlying Allocator of an Arc Source: https://docs.rs/pingora/0.8.0/pingora/upstreams/peer/type.ProxyDigestUserDataHook.html Use `Arc::allocator` to get a reference to the allocator used by an Arc. This is an associated function and a nightly-only experimental API. ```rust #![feature(allocator_api)] use std::sync::Arc; use std::alloc::System; let x = Arc::new_in("hello".to_owned(), System); let alloc = Arc::allocator(&x); ``` -------------------------------- ### Get Underlying Allocator of an Arc Source: https://docs.rs/pingora/0.8.0/pingora/protocols/tls/type.HandshakeCompleteHook.html Use `Arc::allocator` to get a reference to the allocator used by an Arc. This is an associated function and a nightly-only experimental API. ```rust use std::sync::Arc; use std::alloc::System; let x = Arc::new_in("hello".to_owned(), System); let alloc = Arc::allocator(&x); ``` -------------------------------- ### BackendSelection build_with_config Method Source: https://docs.rs/pingora/0.8.0/pingora/lb/selection/trait.BackendSelection.html Creates a BackendSelection from backends and configuration. The default implementation ignores the configuration and calls `Self::build`. ```rust fn build_with_config( backends: &BTreeSet, _config: &Self::Config, ) -> Self { Self::build(backends) } ``` -------------------------------- ### Start Follower Span Source: https://docs.rs/pingora/0.8.0/pingora/cache/trace/type.SpanHandle.html Starts a new span that 'FollowsFrom' the current span, but only if the current span is sampled. Requires the operation name and a closure to define the span. ```rust pub fn follower(&self, operation_name: N, f: F) -> Span where N: Into>, T: Clone, F: FnOnce(StartSpanOptions<'_, AllSampler, T>) -> Span, ``` -------------------------------- ### Generic Implementations (Any, Borrow, BorrowMut, CloneToUninit, From, Instrument, Into, Receiver, Same, ToOwned, TryFrom, TryInto, VZip, WithSubscriber) Source: https://docs.rs/pingora/0.8.0/pingora/prelude/struct.ResponseHeader.html Covers various blanket implementations for generic types, including Any, Borrow, BorrowMut, CloneToUninit, From, Instrument, Into, Receiver, Same, ToOwned, TryFrom, TryInto, VZip, and WithSubscriber. ```APIDOC ## Blanket Implementations ### impl Any for T where T: 'static + ?Sized, #### fn type_id(&self) -> TypeId Gets the `TypeId` of `self`. ### impl Borrow for T where T: ?Sized, #### fn borrow(&self) -> &T Immutably borrows from an owned value. ### impl BorrowMut for T where T: ?Sized, #### fn borrow_mut(&mut self) -> &mut T Mutably borrows from an owned value. ### impl CloneToUninit for T where T: Clone, #### unsafe fn clone_to_uninit(&self, dest: *mut u8) 🔬This is a nightly-only experimental API. (`clone_to_uninit`) Performs copy-assignment from `self` to `dest`. ### impl From for T #### fn from(t: T) -> T Returns the argument unchanged. ### impl Instrument for T #### fn instrument(self, span: Span) -> Instrumented Instruments this type with the provided `Span`, returning an `Instrumented` wrapper. #### fn in_current_span(self) -> Instrumented Instruments this type with the current `Span`, returning an `Instrumented` wrapper. ### impl Into for T where U: From, #### fn into(self) -> U Calls `U::from(self)`. That is, this conversion is whatever the implementation of `From for U` chooses to do. ### impl Receiver for P where P: Deref + ?Sized, T: ?Sized, #### type Target = T 🔬This is a nightly-only experimental API. (`arbitrary_self_types`) The target type on which the method may be called. ### impl Same for T #### type Output = T Should always be `Self` ### impl ToOwned for T where T: Clone, #### type Owned = T The resulting type after obtaining ownership. #### fn to_owned(&self) -> T Creates owned data from borrowed data, usually by cloning. #### fn clone_into(&self, target: &mut T) Uses borrowed data to replace owned data, usually by cloning. ### impl TryFrom for T where U: Into, #### type Error = Infallible The type returned in the event of a conversion error. #### fn try_from(value: U) -> Result>::Error> Performs the conversion. ### impl TryInto for T where U: TryFrom, #### type Error = >::Error The type returned in the event of a conversion error. #### fn try_into(self) -> Result>::Error> Performs the conversion. ### impl VZip for T where V: MultiLane, #### fn vzip(self) -> V ### impl WithSubscriber for T #### fn with_subscriber(self, subscriber: S) -> WithDispatch where S: Into, Attaches the provided `Subscriber` to this type, returning a `WithDispatch` wrapper. #### fn with_current_subscriber(self) -> WithDispatch Attaches the current default `Subscriber` to this type, returning a `WithDispatch` wrapper. ``` -------------------------------- ### Add TLS Listening Endpoint Source: https://docs.rs/pingora/0.8.0/pingora/services/listening/struct.Service.html Configures a service to listen using TLS, requiring paths to the certificate and key files. Returns a `Result` to handle potential errors during setup. ```rust pub fn add_tls( &mut self, addr: &str, cert_path: &str, key_path: &str, ) -> Result<(), Box> ``` -------------------------------- ### Start Child Span Source: https://docs.rs/pingora/0.8.0/pingora/cache/trace/type.SpanHandle.html Starts a new span that is a 'ChildOf' the current span, but only if the current span is sampled. Requires the operation name and a closure to define the span. ```rust pub fn child(&self, operation_name: N, f: F) -> Span where N: Into>, T: Clone, F: FnOnce(StartSpanOptions<'_, AllSampler, T>) -> Span, ``` -------------------------------- ### Get String Slice from ImmutStr Source: https://docs.rs/pingora/0.8.0/pingora/enum.ImmutStr.html Provides a method to get a string slice (&str) from an ImmutStr, regardless of whether it's a static reference or an owned string. ```rust pub fn as_str(&self) -> &str ``` -------------------------------- ### HttpProxy::new Source: https://docs.rs/pingora/0.8.0/pingora/proxy/struct.HttpProxy.html Constructor for creating a new HttpProxy instance. ```APIDOC ## pub fn new(inner: SV, conf: Arc) -> HttpProxy ### Description Create a new `HttpProxy` with the given `ProxyHttp` implementation and `ServerConf`. After creating an `HttpProxy`, you should call `HttpProxy::handle_init_modules()` to initialize the downstream modules before processing requests. For most use cases, prefer using `http_proxy_service()` which wraps the `HttpProxy` in a `Service`. This constructor is useful when you need to integrate `HttpProxy` into a custom accept loop (e.g., for SNI-based routing decisions before TLS termination). ### Parameters - **inner** (SV) - The `ProxyHttp` implementation. - **conf** (Arc) - The server configuration. ### Example ```rust use pingora_proxy::HttpProxy; use std::sync::Arc; let mut proxy = HttpProxy::new(my_proxy_app, server_conf); proxy.handle_init_modules(); let proxy = Arc::new(proxy); // Use proxy.process_new_http() in your custom accept loop ``` ``` -------------------------------- ### Create Static Discovery with Backends Source: https://docs.rs/pingora/0.8.0/pingora/lb/discovery/struct.Static.html Creates a new boxed Static service discovery instance with a provided set of backends. Ensure the 'lb' feature is enabled. ```rust pub fn new(backends: BTreeSet) -> Box ``` -------------------------------- ### Receiver::has_changed Example Source: https://docs.rs/pingora/0.8.0/pingora/server/type.ShutdownWatch.html Illustrates checking for changes using `has_changed` and then consuming the new value with `borrow_and_update`. This example also shows error handling when the sender is dropped. ```rust use tokio::sync::watch; #[tokio::main] async fn main() { let (tx, mut rx) = watch::channel("hello"); tx.send("goodbye").unwrap(); assert!(rx.has_changed().unwrap()); assert_eq!(*rx.borrow_and_update(), "goodbye"); // The value has been marked as seen assert!(!rx.has_changed().unwrap()); drop(tx); // The `tx` handle has been dropped assert!(rx.has_changed().is_err()); } ``` -------------------------------- ### Get Next Backend Index with RoundRobin Source: https://docs.rs/pingora/0.8.0/pingora/lb/selection/algorithms/struct.RoundRobin.html Returns the next index of a backend using the RoundRobin algorithm. The caller should perform modulo to get the valid index of the backend. ```rust fn next(&self, _key: &[u8]) -> u64 ``` -------------------------------- ### Create New BasicPeer with Unix Domain Socket Source: https://docs.rs/pingora/0.8.0/pingora/upstreams/peer/struct.BasicPeer.html Creates a new BasicPeer using a Unix domain socket path. This is available only on Unix-like systems. ```rust pub fn new_uds

(path: P) -> Result> where P: AsRef ``` -------------------------------- ### Service On Startup Delay Method Source: https://docs.rs/pingora/0.8.0/pingora/services/trait.Service.html Informs the service about the delay experienced while waiting for its dependencies. The default behavior is to log the time. Future enhancements may allow intermittent calls for live updates and decision-making. ```rust fn on_startup_delay(&self, time_waited: Duration) { ... } ``` -------------------------------- ### Get a reference to an extension Source: https://docs.rs/pingora/0.8.0/pingora/cache/meta/struct.Extensions.html Use `get` to retrieve an immutable reference to an extension by its type. Returns `None` if the extension is not found. Requires the type to be `Send`, `Sync`, and `'static`. ```rust let mut ext = Extensions::new(); assert!(ext.get::().is_none()); ext.insert(5i32); assert_eq!(ext.get::(), Some(&5i32)); ``` -------------------------------- ### Try Clone Box with System Allocator in Rust Source: https://docs.rs/pingora/0.8.0/pingora/cache/storage/type.MissHandler.html Shows how to use the nightly-only `try_clone_from_ref_in` API to clone a Box, returning a Result to handle potential allocation errors. Requires the `clone_from_ref` and `allocator_api` features. ```rust #![feature(clone_from_ref)] #![feature(allocator_api)] use std::alloc::System; let hello: Box = Box::try_clone_from_ref_in("hello", System)?; ``` -------------------------------- ### Get or insert an extension Source: https://docs.rs/pingora/0.8.0/pingora/cache/meta/struct.Extensions.html Use `get_or_insert` to get a mutable reference to an extension, inserting a provided value if it doesn't exist. Requires the type to be `Clone`, `Send`, `Sync`, and `'static`. ```rust let mut ext = Extensions::new(); *ext.get_or_insert(1i32) += 2; assert_eq!(*ext.get::().unwrap(), 3); ``` -------------------------------- ### Example: String from char Source: https://docs.rs/pingora/0.8.0/pingora/cache/cache_control/type.DirectiveKey.html Demonstrates allocating an owned String from a single character. This is useful for simple character to string conversions. ```rust let c: char = 'a'; let s: String = String::from(c); assert_eq!("a", &s[..]); ``` -------------------------------- ### Start LoadBalancer as Background Service Source: https://docs.rs/pingora/0.8.0/pingora/lb/struct.LoadBalancer.html Implements the `BackgroundService` trait for `LoadBalancer`. This method is called when the pingora server starts services and should signal readiness via `ready_notifier.notify_ready()` upon completion of initialization. ```rust fn start_with_ready_notifier<'life0, 'async_trait>( &'life0 self, shutdown: Receiver, ready: ServiceReadyNotifier, ) -> Pin + Send + 'async_trait>> where 'life0: 'async_trait, LoadBalancer: 'async_trait, ``` -------------------------------- ### Get the number of unique keys in HeaderMap Source: https://docs.rs/pingora/0.8.0/pingora/http/struct.HMap.html Use `keys_len()` to get the count of distinct header names (keys) present in the map. This count will be less than or equal to the total number of values. ```rust let mut map = HeaderMap::new(); assert_eq!(0, map.keys_len()); map.insert(ACCEPT, "text/plain".parse().unwrap()); map.insert(HOST, "localhost".parse().unwrap()); assert_eq!(2, map.keys_len()); map.insert(ACCEPT, "text/html".parse().unwrap()); assert_eq!(2, map.keys_len()); ``` -------------------------------- ### Manager Constructor Methods Source: https://docs.rs/pingora/0.8.0/pingora/cache/eviction/lru/struct.Manager.html Details the methods available for creating and initializing a Manager instance. ```APIDOC ## impl Manager ### pub fn with_capacity(limit: usize, capacity: usize) -> Manager Create a Manager with the given size limit and estimated per shard capacity. The `capacity` is for preallocating to avoid reallocation cost when the LRU grows. ### pub fn with_capacity_and_watermark( limit: usize, capacity: usize, watermark: Option, ) -> Manager Create a Manager with an optional watermark in addition to weight limit. When `watermark` is set, the underlying LRU will also evict to keep total item count under or equal to that watermark. ``` -------------------------------- ### Build LoadBalancer with Backends Source: https://docs.rs/pingora/0.8.0/pingora/lb/struct.LoadBalancer.html Initializes a LoadBalancer with a given set of Backends. ```rust pub fn from_backends(backends: Backends) -> LoadBalancer ``` -------------------------------- ### Any for T Source: https://docs.rs/pingora/0.8.0/pingora/http/struct.Method.html Gets the `TypeId` of `self`. ```APIDOC ## GET /websites/rs_pingora_0_8_0/Any/type_id ### Description Gets the `TypeId` of `self`. ### Method GET ### Endpoint /websites/rs_pingora_0_8_0/Any/type_id ### Response #### Success Response (200) - **type_id** (TypeId) - The TypeId of the object. ### Response Example ```json { "type_id": "a1b2c3d4e5f67890" } ``` ``` -------------------------------- ### Declare Service Dependency with ServiceHandle Source: https://docs.rs/pingora/0.8.0/pingora/services/struct.ServiceHandle.html Shows how to declare that one service depends on another using the `add_dependency` method of ServiceHandle. The dependent service will not start until the specified dependency has started and signaled readiness. ```rust let db_id = server.add_service(database_service); let api_id = server.add_service(api_service); // API service depends on database api_id.add_dependency(&db_id); ``` -------------------------------- ### Create HttpProxy Instance Source: https://docs.rs/pingora/0.8.0/pingora/prelude/fn.http_proxy.html Use this function to create an HttpProxy instance for custom integration into an accept loop. It requires server configuration and a proxy application. The returned HttpProxy is ready to process HTTP requests. ```rust pub fn http_proxy(conf: &Arc, inner: SV) -> HttpProxy where SV: ProxyHttp, ``` ```rust use pingora_proxy::http_proxy; use std::sync::Arc; // Create the proxy let proxy = Arc::new(http_proxy(&server_conf, my_proxy_app)); // In your custom accept loop: loop { let (stream, addr) = listener.accept().await?; // Peek SNI, decide routing... if should_terminate_tls { let tls_stream = my_acceptor.accept(stream).await?; let session = HttpSession::new_http1(Box::new(tls_stream)); proxy.process_new_http(session, &shutdown).await; } } ``` -------------------------------- ### Get Next Backend Index with Random Algorithm Source: https://docs.rs/pingora/0.8.0/pingora/lb/selection/algorithms/struct.Random.html Returns the next index of a backend using the Random selection algorithm. The caller is responsible for performing the modulo operation to get a valid index. ```rust fn next(&self, _key: &[u8]) -> u64; ``` -------------------------------- ### Connector::new Source: https://docs.rs/pingora/0.8.0/pingora/connectors/http/struct.Connector.html Creates a new Connector with default options. ```APIDOC ## pub fn new(options: Option) -> Connector ### Description Creates a new Connector with default options. ### Method `new` ### Parameters #### Query Parameters - **options** (Option) - Optional - Configuration options for the connector. ``` -------------------------------- ### Get or insert an extension with a closure Source: https://docs.rs/pingora/0.8.0/pingora/cache/meta/struct.Extensions.html Use `get_or_insert_with` to get a mutable reference to an extension, inserting a value created by a closure if it doesn't exist. Requires the type to be `Clone`, `Send`, `Sync`, and `'static`. ```rust let mut ext = Extensions::new(); *ext.get_or_insert_with(|| 1i32) += 2; assert_eq!(*ext.get::().unwrap(), 3); ``` -------------------------------- ### Get Raw Pointer to Arc Data Source: https://docs.rs/pingora/0.8.0/pingora/protocols/tls/type.HandshakeCompleteHook.html Use `Arc::as_ptr` to get a raw pointer to the data within an Arc without consuming the Arc. The pointer is valid as long as strong counts exist. ```rust use std::sync::Arc; let x = Arc::new("hello".to_owned()); let y = Arc::clone(&x); let x_ptr = Arc::as_ptr(&x); assert_eq!(x_ptr, Arc::as_ptr(&y)); assert_eq!(unsafe { &*x_ptr }, "hello"); ``` -------------------------------- ### Box::from_non_null Example (Nightly) Source: https://docs.rs/pingora/0.8.0/pingora/cache/storage/type.MissHandler.html Shows how to construct a Box from a NonNull pointer. This is an experimental API and requires the nightly Rust toolchain. Similar to from_raw, it requires careful memory management. ```rust #![feature(box_vec_non_null)] let x = Box::new(5); let non_null = Box::into_non_null(x); let x = unsafe { Box::from_non_null(non_null) }; ``` ```rust #![feature(box_vec_non_null)] use std::alloc::{alloc, Layout}; use std::ptr::NonNull; unsafe { let non_null = NonNull::new(alloc(Layout::new::()).cast::()) .expect("allocation failed"); // In general .write is required to avoid attempting to destruct // the (uninitialized) previous contents of `non_null`. non_null.write(5); let x = Box::from_non_null(non_null); } ``` -------------------------------- ### Get or insert default extension Source: https://docs.rs/pingora/0.8.0/pingora/cache/meta/struct.Extensions.html Use `get_or_insert_default` to get a mutable reference to an extension, inserting its default value if it doesn't exist. Requires the type to implement `Default`, `Clone`, `Send`, `Sync`, and `'static`. ```rust let mut ext = Extensions::new(); *ext.get_or_insert_default::() += 2; assert_eq!(*ext.get::().unwrap(), 2); ``` -------------------------------- ### Manually Create Box with System Allocator Source: https://docs.rs/pingora/0.8.0/pingora/cache/type.MissHandler.html Demonstrates manually creating a Box using the system allocator. This involves allocating memory, writing the value, and then constructing the Box. Requires `unsafe` block. ```rust #![feature(allocator_api)] use std::alloc::{Allocator, Layout, System}; unsafe { let non_null = System.allocate(Layout::new::())?.cast::(); // In general .write is required to avoid attempting to destruct // the (uninitialized) previous contents of `non_null`. non_null.write(5); let x = Box::from_non_null_in(non_null, System); } ``` -------------------------------- ### TypeId Source: https://docs.rs/pingora/0.8.0/pingora/cache/key/struct.CompactCacheKey.html Gets the TypeId of self. ```APIDOC ## fn type_id(&self) -> TypeId ### Description Gets the `TypeId` of `self`. ### Method GET ### Endpoint N/A (Method on an object) ### Parameters None ### Request Example None ### Response #### Success Response (200) - **TypeId** (TypeId) - The unique identifier for the type of the object. ``` -------------------------------- ### Clone Box with System Allocator in Rust Source: https://docs.rs/pingora/0.8.0/pingora/cache/storage/type.MissHandler.html Demonstrates cloning a Box using the nightly-only `clone_from_ref_in` API. Requires the `clone_from_ref` and `allocator_api` features. ```rust #![feature(clone_from_ref)] #![feature(allocator_api)] use std::alloc::System; let hello: Box = Box::clone_from_ref_in("hello", System); ``` -------------------------------- ### Experimental Error Provide Method Example Source: https://docs.rs/pingora/0.8.0/pingora/prelude/trait.ErrorTrait.html Demonstrates the experimental `provide` method for type-based access to error context, using nightly Rust features. ```rust #![feature(error_generic_member_access)] use core::fmt; use core::error::{request_ref, Request}; #[derive(Debug)] enum MyLittleTeaPot { Empty, } #[derive(Debug)] struct MyBacktrace { // ... } impl MyBacktrace { fn new() -> MyBacktrace { // ... } } #[derive(Debug)] struct Error { backtrace: MyBacktrace, } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "Example Error") } } impl std::error::Error for Error { fn provide<'a>(&'a self, request: &mut Request<'a>) { request .provide_ref::(&self.backtrace); } } fn main() { let backtrace = MyBacktrace::new(); let error = Error { backtrace }; let dyn_error = &error as &dyn std::error::Error; let backtrace_ref = request_ref::(dyn_error).unwrap(); assert!(core::ptr::eq(&error.backtrace, backtrace_ref)); assert!(request_ref::(dyn_error).is_none()); } ``` -------------------------------- ### Box::new Example Source: https://docs.rs/pingora/0.8.0/pingora/cache/storage/type.MissHandler.html Demonstrates converting a value into a Box using Box::new. This allocates memory on the heap and moves the value to it. ```rust let x = 5; let boxed = Box::new(5); assert_eq!(Box::from(x), boxed); ```