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
#![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)]
/*!
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
// please note that this api is still especially unstable.
// any other http client would work here too
let url = format!("http://localhost:{}/", port);
type ClientConn<'a> = trillium_client::Conn<'a, trillium_smol::TcpConnector>;
let mut client_conn = ClientConn::get(&*url).execute().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;

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::Headers;

mod header_name;
pub use header_name::{HeaderName, KnownHeaderName};

mod header_values;
pub use header_values::HeaderValues;

mod header_value;
pub use header_value::HeaderValue;

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";