Skip to main content

soth_mitm/
lib.rs

1// Internal items are only reachable when __internal is enabled; suppress dead-code
2// warnings for the public build where those modules are gated out.
3#![cfg_attr(not(feature = "__internal"), allow(dead_code))]
4
5//! # soth-mitm
6//!
7//! Rust intercepting proxy crate with deterministic handler/event contracts.
8//!
9//! `soth-mitm` provides a MITM (man-in-the-middle) proxy that intercepts HTTP/1.1,
10//! HTTP/2, WebSocket, gRPC, and SSE traffic over TLS. It exposes a trait-based
11//! handler API that lets you inspect, allow, or block requests in real time.
12//!
13//! ## Quick Start
14//!
15//! ```rust,no_run
16//! use bytes::Bytes;
17//! use soth_mitm::{
18//!     HandlerDecision, InterceptHandler, MitmConfig, MitmProxyBuilder, RawRequest,
19//! };
20//!
21//! struct MyHandler;
22//!
23//! impl InterceptHandler for MyHandler {
24//!     async fn on_request(&self, request: &RawRequest) -> HandlerDecision {
25//!         if request.path.contains("/blocked") {
26//!             return HandlerDecision::Block {
27//!                 status: 403,
28//!                 body: Bytes::from_static(b"blocked"),
29//!             };
30//!         }
31//!         HandlerDecision::Allow
32//!     }
33//! }
34//!
35//! fn main() -> Result<(), Box<dyn std::error::Error>> {
36//!     let mut config = MitmConfig::default();
37//!     config
38//!         .interception
39//!         .destinations
40//!         .push("api.example.com:443".to_string());
41//!
42//!     let _proxy = MitmProxyBuilder::new(config, MyHandler).build()?;
43//!     Ok(())
44//! }
45//! ```
46//!
47//! ## Feature Flags
48//!
49//! | Flag | Default | Description |
50//! |------|---------|-------------|
51//! | `openssl-backend` | off | Enables OpenSSL-based CA material validation on cert load |
52//! | `__internal` | off | Exposes internal modules for integration tests — **not stable API** |
53//!
54//! ## Minimum Supported Rust Version
55//!
56//! This crate requires **Rust 1.88** or later.
57//!
58//! ## License
59//!
60//! Licensed under the [Mozilla Public License 2.0](https://www.mozilla.org/en-US/MPL/2.0/).
61
62// Consolidated sub-crate modules
63pub(crate) mod engine;
64pub(crate) mod observe;
65pub(crate) mod policy;
66pub(crate) mod protocol;
67pub(crate) mod server;
68pub(crate) mod tls;
69
70// Facade modules
71mod actions;
72mod builder;
73mod ca;
74mod ca_trust;
75mod config;
76mod destination;
77mod errors;
78#[cfg(test)]
79mod fingerprint_capture;
80mod handler;
81mod metrics;
82mod process;
83mod proxy;
84mod runtime;
85mod types;
86
87pub use actions::HandlerDecision;
88pub use builder::MitmProxyBuilder;
89pub use ca::{
90    generate_ca, install_ca_system_trust, is_ca_trusted, load_ca, load_ca_from_files,
91    uninstall_ca_system_trust, CertificateAuthority,
92};
93pub use config::{
94    BodyConfig, ConnectionPoolConfig, FlowRuntimeConfig, H2ResponseOverflowMode, HandlerConfig,
95    InterceptMode, InterceptionScope, MitmConfig, ProcessAttributionConfig, TlsConfig,
96    UpstreamConfig,
97};
98pub use errors::{CaError, MitmError};
99pub use handler::InterceptHandler;
100pub use metrics::ProxyMetrics;
101pub use proxy::{MitmProxy, MitmProxyHandle};
102pub use types::{
103    ConnectionMeta, FlowId, FrameDirection, FrameKind, ProcessInfo, RawRequest, RawResponse,
104    SocketFamily, StreamChunk, TlsInfo, TlsVersion,
105};
106
107// Re-export key transitive types that appear in the public API surface.
108// Users should not need to add separate `bytes`, `http`, or `uuid` deps.
109pub use bytes::Bytes;
110pub use http::HeaderMap;
111pub use uuid::Uuid;
112
113// --- Internal modules gated behind the `__internal` feature ---
114// These expose consolidated sub-crate internals for integration tests and
115// benchmarks. They are NOT part of the stable public API and may change
116// without notice between any versions.
117
118#[cfg(feature = "__internal")]
119#[doc(hidden)]
120pub mod bench_tls {
121    pub use crate::tls::{build_http1_client_config, build_http1_server_config_for_host};
122}
123
124#[cfg(feature = "__internal")]
125#[doc(hidden)]
126pub mod test_engine {
127    pub use crate::engine::{
128        parse_connect_request_head_with_mode, parse_connect_request_line_with_mode, server,
129        CompatibilityOverrideConfig, ConnectParseError, ConnectParseMode, DownstreamCertProfile,
130        InterceptMode, MitmConfig, MitmConfigError, MitmEngine, RouteEndpointConfig, RouteMode,
131        TlsFingerprintClass, TlsFingerprintMode, TlsProfile, UpstreamClientAuthMode,
132        UpstreamSniMode,
133    };
134}
135
136#[cfg(feature = "__internal")]
137#[doc(hidden)]
138pub mod test_policy {
139    pub use crate::policy::{DefaultPolicyEngine, FlowAction, PolicyEngine};
140}
141
142#[cfg(feature = "__internal")]
143#[doc(hidden)]
144pub mod test_protocol {
145    pub use crate::protocol::{
146        validate_stage_order,
147        // anti-hijack
148        AntiHijackSanitizationStage,
149        ApplicationProtocol,
150        DecoderFailureCode,
151        // decoder chain
152        DecoderFrame,
153        DecoderPipelineRegistry,
154        DecoderPipelineResult,
155        DecoderStage,
156        DecoderStageProcessor,
157        DecoderStageStatus,
158        // grpc envelope
159        GrpcEnvelopeMalformedCode,
160        GrpcEnvelopeParser,
161        GrpcEnvelopeParserLimits,
162        GrpcEnvelopeRecord,
163        LayeredDecoderPipeline,
164        SseParser,
165        StageProcessOutcome,
166        // websocket
167        WebSocketTurn,
168        WebSocketTurnAggregator,
169        WsDirection,
170        WsFrameKind,
171        SANITIZED_ATTRIBUTE,
172        SANITIZED_PREFIX_ATTRIBUTE,
173        SANITIZED_PROVENANCE_ATTRIBUTE,
174    };
175}
176
177#[cfg(feature = "__internal")]
178#[doc(hidden)]
179pub mod test_observe {
180    pub use crate::observe::event_log_v2::{
181        deterministic_event_record_v2, DeterministicEventRecordV2, EventLogV2Config,
182        EventLogV2Consumer,
183    };
184    pub use crate::observe::{
185        Event, EventConsumer, EventEnvelope, EventType, FlowContext, NoopEventConsumer,
186        VecEventConsumer, EVENT_SCHEMA_VERSION,
187    };
188}
189
190#[cfg(feature = "__internal")]
191#[doc(hidden)]
192pub mod test_server {
193    pub use crate::server::{
194        adapt_mitmproxy_tls_callback, parse_http1_request_head_bytes,
195        parse_http1_response_head_bytes, FlowHooks, FrameKind, H2ResponseOverflowMode,
196        MitmproxyTlsAdapterEvent, MitmproxyTlsCallback, MitmproxyTlsHook, NoopFlowHooks,
197        RawRequest, RawResponse, RuntimeGovernor, SidecarConfig, SidecarServer, StreamChunk,
198        TlsDiagnostics, TlsDiagnosticsSnapshot, TlsLearningDecision, TlsLearningGuardrails,
199        TlsLearningOutcome, TlsLearningSignal, TlsLearningSnapshot,
200    };
201}
202
203#[cfg(feature = "__internal")]
204#[doc(hidden)]
205pub mod test_tls {
206    pub use crate::tls::{
207        build_http1_client_config, build_http1_server_config_for_host, build_http_client_config,
208        build_http_server_config_for_host, classify_tls_error, CertificateAuthorityConfig,
209        MitmCertificateStore, TlsFailureReason,
210    };
211}