Skip to main content

ntex/web/
mod.rs

1//! Web application framework.
2//!
3//! ```rust,no_run
4//! use ntex::{web, SharedCfg};
5//!
6//! async fn index(info: web::types::Path<(String, u32)>) -> String {
7//!     format!("Hello {}! id:{}", info.0, info.1)
8//! }
9//!
10//! #[ntex::main]
11//! async fn main() -> std::io::Result<()> {
12//!     web::server(async |_| web::App::new().service(
13//!         web::resource("/{name}/{id}/index.html").to(index))
14//!     )
15//!         .bind("127.0.0.1:8080", SharedCfg::default())?
16//!         .run()
17//!         .await
18//! }
19//! ```
20//!
21//! ## Documentation and community resources
22//!
23//! Additional resources:
24//!
25//! - [User guide](https://ntex.rs)
26//! - [GitHub repository](https://github.com/ntex-rs/ntex)
27//! - [Cargo package](https://crates.io/crates/ntex)
28//!
29//! Useful API entry points include:
30//!
31//! - [`App`] configures routes, application state, and middleware.
32//! - [`HttpServer`] creates and configures HTTP server instances.
33//! - [`HttpRequest`] provides request metadata and application state.
34//! - [`HttpResponse`] and [`WebResponse`] represent HTTP responses.
35//! - [`resource()`] and [`route()`] configure resource and route matching.
36//!
37//! ## Features
38//!
39//! - HTTP/1.x and HTTP/2
40//! - Streaming and pipelining
41//! - Keep-alive connections and slow-request handling
42//! - WebSocket clients and servers
43//! - Transparent zstd, gzip, and deflate content encoding
44//! - Configurable request routing
45//! - TLS through OpenSSL or rustls
46//! - Composable middleware
47//!
48//! ## Crate features
49//!
50//! - `cookie` enables HTTP cookie support.
51//! - `compress` enables gzip, deflate and zstd content compression and
52//!   decompression.
53//! - `openssl` enables TLS support through OpenSSL.
54//! - `rustls` enables TLS support through rustls.
55//! - `ws` enables the [`ws`] module.
56#![allow(clippy::unused_async_trait_impl, clippy::mismatching_type_param_order)]
57mod app;
58mod app_service;
59mod config;
60pub mod error;
61mod error_default;
62mod extract;
63pub mod guard;
64mod handler;
65mod httprequest;
66mod info;
67pub mod middleware;
68mod request;
69mod resource;
70mod responder;
71mod response;
72mod rmap;
73mod route;
74mod scope;
75mod server;
76mod service;
77pub mod stack;
78mod state;
79pub mod test;
80pub mod types;
81mod util;
82
83#[cfg(feature = "ws")]
84pub mod ws;
85
86// re-export proc macro
87pub use ntex_macros::web_connect as connect;
88pub use ntex_macros::web_delete as delete;
89pub use ntex_macros::web_get as get;
90pub use ntex_macros::web_head as head;
91pub use ntex_macros::web_options as options;
92pub use ntex_macros::web_patch as patch;
93pub use ntex_macros::web_post as post;
94pub use ntex_macros::web_put as put;
95pub use ntex_macros::web_query as query;
96pub use ntex_macros::web_trace as trace;
97
98pub use crate::http::Response as HttpResponse;
99pub use crate::http::ResponseBuilder as HttpResponseBuilder;
100
101pub use self::app::{App, AppServices};
102pub use self::config::{ServiceConfig, WebAppConfig};
103pub use self::error::{DefaultError, InternalError, WebError, WebResponseError};
104pub use self::extract::FromRequest;
105pub use self::handler::{Handler, HandlerSt};
106pub use self::httprequest::HttpRequest;
107pub use self::request::WebRequest;
108pub use self::resource::{Resource, ResourceServices};
109pub use self::responder::Responder;
110pub use self::response::WebResponse;
111pub use self::route::Route;
112pub use self::scope::{Scope, ScopeServices};
113pub use self::server::HttpServer;
114pub use self::service::WebServiceFactory;
115pub use self::state::{AppState, State};
116pub use self::util::*;
117
118use crate::error::Failure;
119use crate::service::boxed::{BoxService, BoxServiceFactory};
120
121pub(crate) type HttpHandler<St: State, In> =
122    BoxService<St, WebRequest<In>, WebResponse, WebError<St, St::Error>>;
123pub(crate) type HttpService<St: State, In> =
124    BoxServiceFactory<St, WebRequest<In>, WebResponse, WebError<St, St::Error>, Failure>;
125
126pub mod dev {
127    //! Internal web framework types commonly needed by library authors.
128    //!
129    //! Importing this module's contents can reduce repetitive imports in
130    //! libraries that build abstractions on top of [`crate::web`].
131
132    pub use crate::web::app_service::AppService;
133    pub use crate::web::info::ConnectionInfo;
134    pub use crate::web::rmap::ResourceMap;
135    pub use crate::web::route::IntoRoutes;
136    pub use crate::web::service::{WebServiceAdapter, WebServiceConfig, WebServiceFactory};
137
138    /// Application state used by `App::default()`.
139    pub type DefaultState = ();
140
141    use crate::web::{Handler, HandlerSt};
142
143    pub(crate) fn insert_slash(mut patterns: Vec<String>) -> Vec<String> {
144        for path in &mut patterns {
145            if !path.is_empty() && !path.starts_with('/') {
146                path.insert(0, '/');
147            }
148        }
149        patterns
150    }
151
152    #[doc(hidden)]
153    #[inline]
154    pub fn __assert_handler<St, In, Fun, Res>(f: Fun) -> impl Handler<St, (), Output = Res>
155    where
156        St: super::State,
157        Fun: AsyncFn() -> Res + 'static,
158        Res: super::Responder<St>,
159    {
160        f
161    }
162
163    #[doc(hidden)]
164    #[inline]
165    pub fn __assert_handler_st<St, In, Fun, Res>(f: Fun) -> impl HandlerSt<St, In, (), Output = Res>
166    where
167        St: super::State,
168        Fun: AsyncFn(&St, In) -> Res + 'static,
169        Res: super::Responder<St>,
170    {
171        f
172    }
173
174    macro_rules! assert_handler ({ $name:ident, $($T:ident),+} => {
175        #[doc(hidden)]
176        #[inline(always)]
177        pub fn $name<St, Fun, Res, $($T,)+>(
178            f: Fun,
179        ) -> impl Handler<St, ($($T,)+), Output = Res>
180        where
181            St: $crate::web::State,
182            Fun: AsyncFn($($T,)+) -> Res + 'static,
183            Res: super::Responder<St> + 'static,
184           $($T: $crate::web::FromRequest<St>),+,
185        {
186            f
187        }
188    });
189
190    assert_handler!(__assert_handler1, A);
191    assert_handler!(__assert_handler2, A, B);
192    assert_handler!(__assert_handler3, A, B, C);
193    assert_handler!(__assert_handler4, A, B, C, D);
194    assert_handler!(__assert_handler5, A, B, C, D, E);
195    assert_handler!(__assert_handler6, A, B, C, D, E, F);
196    assert_handler!(__assert_handler7, A, B, C, D, E, F, G);
197    assert_handler!(__assert_handler8, A, B, C, D, E, F, G, H);
198    assert_handler!(__assert_handler9, A, B, C, D, E, F, G, H, I);
199    assert_handler!(__assert_handler10, A, B, C, D, E, F, G, H, I, J);
200
201    macro_rules! assert_handler_st ({ $name:ident, $($T:ident),+} => {
202        #[doc(hidden)]
203        #[inline(always)]
204        pub fn $name<St, In, Fun, Res, $($T,)+>(
205            f: Fun,
206        ) -> impl HandlerSt<St, In, ($($T,)+), Output = Res>
207        where
208            St: $crate::web::State,
209            Fun: AsyncFn(&St, In, $($T,)+) -> Res + 'static,
210            Res: super::Responder<St> + 'static,
211           $($T: $crate::web::FromRequest<St>),+,
212        {
213            f
214        }
215    });
216
217    assert_handler_st!(__assert_handler_st1, A);
218    assert_handler_st!(__assert_handler_st2, A, B);
219    assert_handler_st!(__assert_handler_st3, A, B, C);
220    assert_handler_st!(__assert_handler_st4, A, B, C, D);
221    assert_handler_st!(__assert_handler_st5, A, B, C, D, E);
222    assert_handler_st!(__assert_handler_st6, A, B, C, D, E, F);
223    assert_handler_st!(__assert_handler_st7, A, B, C, D, E, F, G);
224    assert_handler_st!(__assert_handler_st8, A, B, C, D, E, F, G, H);
225    assert_handler_st!(__assert_handler_st9, A, B, C, D, E, F, G, H, I);
226    assert_handler_st!(__assert_handler_st10, A, B, C, D, E, F, G, H, I, J);
227}