accept.rs |
The `Accept` trait and supporting types.
This module contains:
- The [`Accept`](Accept) trait used to asynchronously accept incoming
connections.
- Utilities like `poll_fn` to ease creating a custom `Accept`. |
2766 |
conn.rs |
Lower-level Server connection API.
The types in this module are to provide a lower-level API based around a
single connection. Accepting a connection and binding it with a service
are not handled at this level. This module provides the building blocks to
customize those things externally.
If you don't have need to manage connections yourself, consider using the
higher-level [Server](super) API.
## Example
A simple example that uses the `Http` struct to talk HTTP over a Tokio TCP stream
```no_run
# #[cfg(all(feature = "http1", feature = "runtime"))]
# mod rt {
use http::{Request, Response, StatusCode};
use hyper::{server::conn::Http, service::service_fn, Body};
use std::{net::SocketAddr, convert::Infallible};
use tokio::net::TcpListener;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let addr: SocketAddr = ([127, 0, 0, 1], 8080).into();
let mut tcp_listener = TcpListener::bind(addr).await?;
loop {
let (tcp_stream, _) = tcp_listener.accept().await?;
tokio::task::spawn(async move {
if let Err(http_err) = Http::new()
.http1_only(true)
.http1_keep_alive(true)
.serve_connection(tcp_stream, service_fn(hello))
.await {
eprintln!("Error while serving HTTP connection: {}", http_err);
}
});
}
}
async fn hello(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
Ok(Response::new(Body::from("Hello World!")))
}
# }
``` |
36470 |
mod.rs |
HTTP Server
A `Server` is created to listen on a port, parse HTTP requests, and hand
them off to a `Service`.
There are two levels of APIs provide for constructing HTTP servers:
- The higher-level [`Server`](Server) type.
- The lower-level [`conn`](conn) module.
# Server
The [`Server`](Server) is main way to start listening for HTTP requests.
It wraps a listener with a [`MakeService`](crate::service), and then should
be executed to start serving requests.
[`Server`](Server) accepts connections in both HTTP1 and HTTP2 by default.
## Examples
```no_run
use std::convert::Infallible;
use std::net::SocketAddr;
use hyper::{Body, Request, Response, Server};
use hyper::service::{make_service_fn, service_fn};
async fn handle(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
Ok(Response::new(Body::from("Hello World")))
}
# #[cfg(feature = "runtime")]
#[tokio::main]
async fn main() {
// Construct our SocketAddr to listen on...
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
// And a MakeService to handle each connection...
let make_service = make_service_fn(|_conn| async {
Ok::<_, Infallible>(service_fn(handle))
});
// Then bind and serve...
let server = Server::bind(&addr).serve(make_service);
// And run forever...
if let Err(e) = server.await {
eprintln!("server error: {}", e);
}
}
# #[cfg(not(feature = "runtime"))]
# fn main() {}
```
If you don't need the connection and your service implements `Clone` you can use
[`tower::make::Shared`] instead of `make_service_fn` which is a bit simpler:
```no_run
# use std::convert::Infallible;
# use std::net::SocketAddr;
# use hyper::{Body, Request, Response, Server};
# use hyper::service::{make_service_fn, service_fn};
# use tower::make::Shared;
# async fn handle(_req: Request<Body>) -> Result<Response<Body>, Infallible> {
# Ok(Response::new(Body::from("Hello World")))
# }
# #[cfg(feature = "runtime")]
#[tokio::main]
async fn main() {
// Construct our SocketAddr to listen on...
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
// Shared is a MakeService that produces services by cloning an inner service...
let make_service = Shared::new(service_fn(handle));
// Then bind and serve...
let server = Server::bind(&addr).serve(make_service);
// And run forever...
if let Err(e) = server.await {
eprintln!("server error: {}", e);
}
}
# #[cfg(not(feature = "runtime"))]
# fn main() {}
```
Passing data to your request handler can be done like so:
```no_run
use std::convert::Infallible;
use std::net::SocketAddr;
use hyper::{Body, Request, Response, Server};
use hyper::service::{make_service_fn, service_fn};
# #[cfg(feature = "runtime")]
use hyper::server::conn::AddrStream;
#[derive(Clone)]
struct AppContext {
// Whatever data your application needs can go here
}
async fn handle(
context: AppContext,
addr: SocketAddr,
req: Request<Body>
) -> Result<Response<Body>, Infallible> {
Ok(Response::new(Body::from("Hello World")))
}
# #[cfg(feature = "runtime")]
#[tokio::main]
async fn main() {
let context = AppContext {
// ...
};
// A `MakeService` that produces a `Service` to handle each connection.
let make_service = make_service_fn(move |conn: &AddrStream| {
// We have to clone the context to share it with each invocation of
// `make_service`. If your data doesn't implement `Clone` consider using
// an `std::sync::Arc`.
let context = context.clone();
// You can grab the address of the incoming connection like so.
let addr = conn.remote_addr();
// Create a `Service` for responding to the request.
let service = service_fn(move |req| {
handle(context.clone(), addr, req)
});
// Return the service to hyper.
async move { Ok::<_, Infallible>(service) }
});
// Run the server like above...
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
let server = Server::bind(&addr).serve(make_service);
if let Err(e) = server.await {
eprintln!("server error: {}", e);
}
}
# #[cfg(not(feature = "runtime"))]
# fn main() {}
```
[`tower::make::Shared`]: https://docs.rs/tower/latest/tower/make/struct.Shared.html |
5243 |
server.rs |
|
28024 |
server_stub.rs |
|
505 |
shutdown.rs |
|
4139 |
tcp.rs |
|
15850 |