nautilus_network/http/mod.rs
1// -------------------------------------------------------------------------------------------------
2// Copyright (C) 2015-2026 Nautech Systems Pty Ltd. All rights reserved.
3// https://nautechsystems.io
4//
5// Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6// You may not use this file except in compliance with the License.
7// You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16//! Asynchronous HTTP requests with rate limiting, connection reuse, and bounded responses.
17//!
18//! # Architecture
19//!
20//! [`HttpClient`] applies quota policy before delegating requests to [`InnerHttpClient`]. The inner
21//! client owns one reusable Hyper client, preserving its connection pool across requests and clones.
22//!
23//! # Rate limiting and requests
24//!
25//! Requests can await default and per-key quotas from one or more shared
26//! [`RateLimiter`](crate::ratelimiter::RateLimiter) instances. Sharing a limiter across clients
27//! enforces one process-wide budget for scopes such as an IP address or account. The client accepts
28//! default and per-request headers, repeated query values, raw bodies, and client-level and
29//! per-request timeouts.
30//!
31//! # Proxy routing
32//!
33//! By default the client honors ambient proxy configuration: with `use_system_proxy` left at its
34//! default of `true` and no explicit `proxy_url`, requests are routed through the proxy named by
35//! `HTTP_PROXY`, `HTTPS_PROXY`, or `ALL_PROXY` (lowercase variants included), except destinations
36//! matched by `NO_PROXY`.
37//!
38//! This default is a deliberate trust decision on the process environment: an actor who controls
39//! it chooses the proxy that observes all plaintext HTTP traffic and the CONNECT tunnels that
40//! carry HTTPS.
41//!
42//! An optional explicit `proxy_url` applies to both HTTP and HTTPS traffic and always takes
43//! precedence over ambient lookup. Passing `use_system_proxy(false)` disables ambient lookup, so
44//! requests route directly only when `proxy_url` is unset.
45//!
46//! HTTP status errors remain [`HttpResponse`] values for adapter-specific handling. The transport
47//! retries requests canceled before transmission on reused connections, and allows two retries for
48//! remote HTTP/2 `GOAWAY(NO_ERROR)` or `REFUSED_STREAM` errors. Other transport failures and HTTP
49//! status codes do not trigger retries. Adapters can apply [`crate::retry::RetryManager`] when the
50//! operation and venue error are safe to retry.
51//!
52//! # Connection and response policy
53//!
54//! Production clients built through [`HttpClient::builder`] enable `TCP_NODELAY`, pooled idle
55//! connections, and HTTP/2 keepalive while idle.
56//!
57//! HTTP/2 connections use fixed flow-control windows of 16 MiB per stream and 32 MiB per
58//! connection, larger than Hyper's fixed defaults of 2 MiB and 5 MiB. Setting
59//! `NAUTILUS_HTTP2_ADAPTIVE_WINDOW=true` before building a client enables Hyper's adaptive windows
60//! instead, which start at 65,535 bytes and grow toward 16 MiB through PING probes and SETTINGS
61//! updates. Cloudflare-fronted endpoints can reset large response bodies mid-transfer under
62//! adaptive windows. The value `false` keeps fixed windows, and any other value fails the build.
63//!
64//! Buffered responses retain only configured header fields and reject bodies larger than 100 MiB,
65//! including chunked bodies without a declared length. [`HttpClient::get_stream`] consumes bodies
66//! incrementally without a total size limit. Request URLs in transport errors and response-stream
67//! diagnostics are limited to their origin (scheme, host, and port). Setting `redact_url(true)` on the
68//! builder omits the origin too. This policy controls the URL context added by this client;
69//! diagnostic messages from lower layers are unchanged. The client logs request metadata only, never URLs.
70//!
71//! Hyper owns the lifecycle of individual pooled connections, so this client exposes no socket
72//! state sink or explicit reconnect operation. Callers observe connection failure through each
73//! request result and retain the client to preserve its pool.
74
75pub mod client;
76pub mod error;
77pub mod types;
78
79#[cfg(not(all(feature = "simulation", madsim)))]
80mod connector;
81#[cfg(all(feature = "simulation", madsim))]
82mod simulation;
83#[cfg(not(all(feature = "simulation", madsim)))]
84mod transport;
85
86mod stream;
87
88#[cfg(all(test, not(all(feature = "simulation", madsim))))]
89mod tests;
90
91// Re-exports
92pub use client::{HttpClient, HttpRedirectPolicy, InnerHttpClient};
93pub use error::HttpClientError;
94pub use http::{
95 Method, StatusCode,
96 header::{RETRY_AFTER, USER_AGENT},
97};
98use nautilus_core::consts::NAUTILUS_USER_AGENT;
99pub use stream::HttpResponseStream;
100pub use types::{HttpMethod, HttpResponse, HttpStatus, parse_retry_after};
101pub use url::Url;
102
103/// Returns the standard headers every NautilusTrader HTTP and WebSocket client sends.
104///
105/// Carries the NautilusTrader [`USER_AGENT`] with the compile-time version.
106#[must_use]
107pub fn create_standard_nautilus_headers() -> Vec<(String, String)> {
108 vec![(USER_AGENT.to_string(), NAUTILUS_USER_AGENT.to_string())]
109}