1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
//! # rust-web-server
//!
//! A static file web server and HTTP toolkit written in Rust.
//! Supports HTTP/3 (QUIC), HTTP/2, and HTTP/1.1.
//!
//! ## Use as a library
//!
//! Add to `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! rust-web-server = "17"
//! ```
//!
//! ## Quick start: add a custom route
//!
//! ```rust,no_run
//! use rust_web_server::controller::Controller;
//! use rust_web_server::request::{METHOD, Request};
//! use rust_web_server::response::{Response, STATUS_CODE_REASON_PHRASE};
//! use rust_web_server::range::Range;
//! use rust_web_server::mime_type::MimeType;
//! use rust_web_server::server::ConnectionInfo;
//!
//! pub struct PingController;
//!
//! impl Controller for PingController {
//! fn is_matching(request: &Request, _: &ConnectionInfo) -> bool {
//! request.method == METHOD.get && request.request_uri == "/ping"
//! }
//!
//! fn process(_: &Request, mut response: Response, _: &ConnectionInfo) -> Response {
//! response.status_code = *STATUS_CODE_REASON_PHRASE.n200_ok.status_code;
//! response.reason_phrase = STATUS_CODE_REASON_PHRASE.n200_ok.reason_phrase.to_string();
//! response.content_range_list = vec![
//! Range::get_content_range(b"pong".to_vec(), MimeType::TEXT_PLAIN.to_string())
//! ];
//! response
//! }
//! }
//! ```
//!
//! See [DEVELOPER.md](https://github.com/bohdaq/rust-web-server/blob/main/DEVELOPER.md)
//! for the full building blocks reference and use case examples.
// Allows `::rust_web_server::…` paths to resolve from within this crate's own
// tests, which is required by proc-macro derive output that uses that prefix.
extern crate self as rust_web_server;
pub mod app;
#[cfg(feature = "auth")]
pub mod auth;
#[cfg(feature = "macros")]
pub use rws_macros::{delete, get, patch, post, put, route, Config, FromRequest, Validate};
#[cfg(all(feature = "macros", any(feature = "model-sqlite", feature = "model-postgres", feature = "model-mysql")))]
pub use rws_macros::Model;
#[cfg(feature = "http2")]
pub mod async_state;
pub mod session;
pub mod sse;
pub mod compression;
pub mod cookie;
pub mod error;
pub mod extract;
pub mod ip_filter;
pub mod macros;
pub mod blocklist;
pub mod cache;
pub mod config_reload;
pub mod server_config;
pub mod feature;
pub mod maintenance;
pub mod metrics;
pub mod mcp;
pub mod request_log;
pub mod request_id;
pub mod otel;
#[cfg(feature = "acme")]
pub mod acme;
pub mod middleware;
pub mod rate_limit;
pub mod router;
pub mod state;
pub mod test_client;
pub mod application;
pub mod body;
pub mod client_hint;
pub mod controller;
pub mod core;
pub mod cors;
pub mod entry_point;
pub mod ext;
pub mod header;
pub mod http;
pub mod json;
pub mod language;
pub mod log;
pub mod mime_type;
pub mod null;
pub mod range;
pub mod request;
pub mod response;
pub mod server;
pub mod symbol;
pub mod thread_pool;
pub mod url;
pub mod pagination;
pub mod proxy;
pub mod rewrite;
pub mod scheduler;
pub mod tcp_proxy;
pub mod udp_proxy;
pub mod ws_proxy;
pub mod canary;
pub mod circuit_breaker;
pub mod service_discovery;
pub mod config_binding;
pub mod di;
pub mod proxy_config;
pub mod ingress;
#[cfg(feature = "tera")]
pub mod template;
pub mod validate;
pub mod virtual_host;
#[cfg(any(feature = "model-sqlite", feature = "model-postgres", feature = "model-mysql"))]
pub mod model;
pub mod websocket;
pub mod http_client;
#[cfg(feature = "crypto")]
pub mod crypto;
#[cfg(feature = "csrf")]
pub mod csrf;
#[cfg(feature = "sso")]
pub mod sso;
#[cfg(feature = "mailer")]
pub mod mailer;
#[cfg(feature = "jobs")]
pub mod jobs;
#[cfg(any(feature = "storage-local", feature = "storage-s3", feature = "storage-azure"))]
pub mod storage;
#[cfg(feature = "openapi")]
pub mod openapi;
#[cfg(feature = "webhook")]
pub mod webhook;
pub mod timeout;
pub mod prelude;
#[cfg(feature = "http2")]
#[doc(hidden)]
pub mod tls;
#[cfg(feature = "http2")]
#[doc(hidden)]
pub mod h2_handler;
#[cfg(feature = "http3")]
#[doc(hidden)]
pub mod h3_handler;
/// Shared infrastructure for tests that write process-wide environment variables.
///
/// Tests that call `override_environment_variables_from_config` or
/// `CommandLineArgument::set_environment_variable` must hold this lock for
/// their entire duration so they don't race with other tests reading the
/// same variables.
#[cfg(test)]
pub mod test_env {
use std::sync::{Mutex, OnceLock};
static LOCK: OnceLock<Mutex<()>> = OnceLock::new();
pub fn lock() -> std::sync::MutexGuard<'static, ()> {
LOCK.get_or_init(|| Mutex::new(()))
.lock()
.unwrap_or_else(|e| e.into_inner())
}
}