scuffle_http/lib.rs
1//! An HTTP server with support for HTTP/1, HTTP/2 and HTTP/3.
2//!
3//! It abstracts away [`hyper`](https://crates.io/crates/hyper) and [`h3`](https://crates.io/crates/h3) to provide a rather simple interface for creating and running a server that can handle all three protocols.
4//!
5//! See the [examples](./examples) directory for usage examples.
6#![cfg_attr(feature = "docs", doc = "\n\nSee the [changelog][changelog] for a full release history.")]
7#![cfg_attr(feature = "docs", doc = "## Feature flags")]
8#![cfg_attr(feature = "docs", doc = document_features::document_features!())]
9//! ## Why do we need this?
10//!
11//! This crate is designed to be a simple and easy to use HTTP server that supports HTTP/1, HTTP/2 and HTTP/3.
12//!
13//! Currently, there are simply no other crates that provide support for all three protocols with a unified API.
14//! This crate aims to fill that gap.
15//!
16//! ## Example
17//!
18//! The following example demonstrates how to create a simple HTTP server (without TLS) that responds with "Hello, world!" to all requests on port 3000.
19//!
20//! ```rust
21//! # use scuffle_future_ext::FutureExt;
22//! # tokio_test::block_on(async {
23//! # let run = async {
24//! let service = scuffle_http::service::fn_http_service(|req| async move {
25//! scuffle_http::Response::builder()
26//! .status(scuffle_http::http::StatusCode::OK)
27//! .header(scuffle_http::http::header::CONTENT_TYPE, "text/plain")
28//! .body("Hello, world!".to_string())
29//! });
30//! let service_factory = scuffle_http::service::service_clone_factory(service);
31//!
32//! scuffle_http::HttpServer::builder()
33//! .service_factory(service_factory)
34//! .bind("[::]:3000".parse().unwrap())
35//! .build()
36//! .run()
37//! .await
38//! .expect("server failed");
39//! # };
40//! # run.with_timeout(std::time::Duration::from_secs(1)).await.expect_err("test should have timed out");
41//! # });
42//! ```
43//!
44//! ### Missing Features
45//!
46//! - Upgrading to websocket connections from HTTP/3 connections (this is usually done via HTTP/1.1 anyway)
47//!
48//! ## License
49//!
50//! This project is licensed under the MIT or Apache-2.0 license.
51//! You can choose between one of them if you use this work.
52//!
53//! `SPDX-License-Identifier: MIT OR Apache-2.0`
54#![cfg_attr(all(coverage_nightly, test), feature(coverage_attribute))]
55#![cfg_attr(docsrs, feature(doc_auto_cfg))]
56#![deny(missing_docs)]
57#![deny(unsafe_code)]
58#![deny(unreachable_pub)]
59#![deny(clippy::mod_module_files)]
60
61#[cfg(all(feature = "http3", not(feature = "tls-rustls")))]
62compile_error!("feature \"tls-rustls\" must be enabled when \"http3\" is enabled.");
63
64#[cfg(all(feature = "webtransport", not(feature = "http3")))]
65compile_error!("feature \"http3\" must be enabled when \"webtransport\" is enabled.");
66
67#[cfg(any(feature = "http1", feature = "http2", feature = "http3"))]
68pub mod backend;
69pub mod body;
70pub mod error;
71pub mod extensions;
72mod server;
73pub mod service;
74mod tests;
75
76pub use http;
77pub use http::Response;
78pub use server::{HttpServer, HttpServerBuilder};
79
80/// An incoming request.
81pub type IncomingRequest = http::Request<body::IncomingBody>;
82
83/// Changelogs generated by [scuffle_changelog]
84#[cfg(feature = "docs")]
85#[scuffle_changelog::changelog]
86pub mod changelog {}