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
#![forbid(unsafe_code)]
#![deny(
clippy::dbg_macro,
missing_copy_implementations,
rustdoc::missing_crate_level_docs,
missing_debug_implementations,
nonstandard_style,
unused_qualifications
)]
#![warn(missing_docs, clippy::pedantic, clippy::perf, clippy::cargo)]
#![allow(clippy::must_use_candidate, clippy::module_name_repetitions)]
/*!
This crate provides the http 1.x implementation for Trillium.
## Stability
As this is primarily intended for internal use by the [Trillium
crate](https://docs.trillium.rs/trillium), the api is likely to be
less stable than that of the higher level abstractions in Trillium.
## Example
This is an elaborate example that demonstrates some of `trillium_http`'s
capabilities. Please note that trillium itself provides a much more
usable interface on top of `trillium_http`, at very little cost.
```
# fn main() -> trillium_http::Result<()> { smol::block_on(async {
use async_net::{TcpListener, TcpStream};
use futures_lite::StreamExt;
use stopper::Stopper;
use trillium_http::{Conn, Result};
let stopper = Stopper::new();
let listener = TcpListener::bind(("localhost", 0)).await?;
let port = listener.local_addr()?.port();
let server_stopper = stopper.clone();
let server_handle = smol::spawn(async move {
let mut incoming = server_stopper.stop_stream(listener.incoming());
while let Some(Ok(stream)) = incoming.next().await {
let stopper = server_stopper.clone();
smol::spawn(Conn::map(stream, stopper, |mut conn: Conn<TcpStream>| async move {
conn.set_response_body("hello world");
conn.set_status(200);
conn
})).detach()
}
Result::Ok(())
});
// this example uses the trillium client
// any other http client would work here too
let url = format!("http://localhost:{}/", port);
let client = trillium_client::Client::new(trillium_smol::ClientConfig::default());
let mut client_conn = client.get(&*url).await?;
assert_eq!(client_conn.status().unwrap(), 200);
assert_eq!(client_conn.response_headers().get_str("content-length"), Some("11"));
assert_eq!(
client_conn.response_body().read_string().await?,
"hello world"
);
stopper.stop(); // stop the server after one request
server_handle.await?; // wait for the server to shut down
# Result::Ok(()) }) }
```
*/
mod received_body;
pub use received_body::ReceivedBody;
#[cfg(feature = "unstable")]
pub use received_body::ReceivedBodyState;
mod error;
pub use error::{Error, Result};
mod conn;
pub use conn::{Conn, SERVER};
mod connection_status;
pub use connection_status::ConnectionStatus;
mod synthetic;
pub use synthetic::Synthetic;
mod upgrade;
pub use upgrade::Upgrade;
pub use stopper::Stopper;
mod mut_cow;
pub(crate) use mut_cow::MutCow;
mod util;
mod body;
pub use body::Body;
mod state_set;
pub use state_set::StateSet;
mod headers;
pub use headers::{HeaderName, HeaderValue, HeaderValues, Headers, KnownHeaderName};
mod status;
pub use status::Status;
mod method;
pub use method::Method;
mod version;
pub use version::Version;
/// Types to represent the bidirectional data stream over which the
/// HTTP protocol is communicated
pub mod transport;
/// A pre-rendered http response to send when the server is at capacity.
pub const SERVICE_UNAVAILABLE: &[u8] = b"HTTP/1.1 503 Service Unavailable\r
Connection: close\r
Content-Length: 0\r
Retry-After: 60\r
\r\n";
#[cfg(feature = "http-compat-1")]
pub mod http_compat1;
#[cfg(feature = "http-compat")]
pub mod http_compat0;
#[cfg(feature = "http-compat")]
pub use http_compat0 as http_compat; // for semver
mod bufwriter;
pub(crate) use bufwriter::BufWriter;
mod http_config;
pub use http_config::HttpConfig;
pub(crate) mod after_send;
mod buffer;
#[cfg(feature = "unstable")]
pub use buffer::Buffer;
#[cfg(not(feature = "unstable"))]
pub(crate) use buffer::Buffer;
mod copy;
#[cfg(feature = "unstable")]
pub use copy::copy;
#[cfg(not(feature = "unstable"))]
pub(crate) use copy::copy;
mod liveness;