solicit/server/
mod.rs

1//! The module contains a simple HTTP/2 server implementation.
2
3use http::{Response, HttpResult, HttpError, HttpScheme, Header, StreamId};
4use http::transport::TransportStream;
5use http::connection::{HttpConnection, EndStream, SendStatus};
6use http::session::{DefaultSessionState, SessionState, Stream};
7use http::server::ServerConnection;
8
9/// The struct represents a fully received request.
10pub struct ServerRequest<'a> {
11    pub stream_id: StreamId,
12    pub headers: &'a [Header],
13    pub body: &'a [u8],
14}
15
16/// The struct implements a simple HTTP/2 server that allows users to register a request handler (a
17/// callback taking a `ServerRequest` and returning a `Response`) which is run on all received
18/// requests.
19///
20/// The `handle_next` method needs to be called regularly in order to have the server process
21/// received frames, as well as send out the responses.
22///
23/// This is an exceedingly simple implementation of an HTTP/2 server and is mostly an example of
24/// how the `solicit::http` API can be used to make one.
25///
26/// # Examples
27///
28/// ```no_run
29/// extern crate solicit;
30/// use std::str;
31/// use std::net::{TcpListener, TcpStream};
32/// use std::thread;
33///
34/// use solicit::server::SimpleServer;
35///
36/// use solicit::http::Response;
37///
38/// fn main() {
39///     fn handle_client(stream: TcpStream) {
40///         let mut server = SimpleServer::new(stream, |req| {
41///             println!("Received request:");
42///             for header in req.headers.iter() {
43///                 println!("  {}: {}",
44///                 str::from_utf8(&header.0).unwrap(),
45///                 str::from_utf8(&header.1).unwrap());
46///             }
47///             println!("Body:\n{}", str::from_utf8(&req.body).unwrap());
48///
49///             // Return a dummy response for every request
50///             Response {
51///                 headers: vec![
52///                     (b":status".to_vec(), b"200".to_vec()),
53///                     (b"x-solicit".to_vec(), b"Hello, World!".to_vec()),
54///                 ],
55///                 body: vec![65],
56///                 stream_id: req.stream_id,
57///            }
58///         }).unwrap();
59///         while let Ok(_) = server.handle_next() {}
60///         println!("Server done (client disconnected)");
61///     }
62///
63///     let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
64///     for stream in listener.incoming() {
65///         let stream = stream.unwrap();
66///         thread::spawn(move || {
67///             handle_client(stream)
68///         });
69///     }
70/// }
71/// ```
72pub struct SimpleServer<TS, H> where TS: TransportStream, H: FnMut(ServerRequest) -> Response {
73    conn: ServerConnection<TS, TS>,
74    handler: H,
75}
76
77impl<TS, H> SimpleServer<TS, H>
78        where TS: TransportStream, H: FnMut(ServerRequest) -> Response {
79    /// Creates a new `SimpleServer` that will use the given `TransportStream` to communicate to
80    /// the client. Assumes that the stream is fully uninitialized -- no preface sent or read yet.
81    pub fn new(mut stream: TS, handler: H) -> HttpResult<SimpleServer<TS, H>> {
82        // First assert that the preface is received
83        let mut preface = [0; 24];
84        TransportStream::read_exact(&mut stream, &mut preface).unwrap();
85        if &preface != b"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" {
86            return Err(HttpError::UnableToConnect);
87        }
88
89        let conn = HttpConnection::<TS, TS>::with_stream(stream, HttpScheme::Http);
90        let mut server = SimpleServer {
91            conn: ServerConnection::with_connection(conn, DefaultSessionState::new()),
92            handler: handler,
93        };
94
95        // Initialize the connection -- send own settings and process the peer's
96        try!(server.conn.init());
97
98        // Set up done
99        Ok(server)
100    }
101
102    /// Handles the next incoming frame, blocking to receive it if nothing is available on the
103    /// underlying stream.
104    ///
105    /// Handling the frame can trigger the handler callback. Any responses returned by the handler
106    /// are immediately flushed out to the client (blocking the call until it's done).
107    pub fn handle_next(&mut self) -> HttpResult<()> {
108        try!(self.conn.handle_next_frame());
109        let responses = try!(self.handle_requests());
110        try!(self.prepare_responses(responses));
111        try!(self.flush_streams());
112        try!(self.reap_streams());
113
114        Ok(())
115    }
116
117    /// Invokes the request handler for each fully received request. Collects all the responses
118    /// into the returned `Vec`.
119    fn handle_requests(&mut self) -> HttpResult<Vec<Response>> {
120        let handler = &mut self.handler;
121        Ok(self.conn.state.iter().filter(|s| s.is_closed_remote()).map(|stream| {
122            let req = ServerRequest {
123                stream_id: stream.stream_id,
124                headers: stream.headers.as_ref().unwrap(),
125                body: &stream.body,
126            };
127            handler(req)
128        }).collect())
129    }
130
131    /// Prepares the streams for each of the given responses. Headers for each response are
132    /// immediately sent and the data staged into the streams' outgoing buffer.
133    fn prepare_responses(&mut self, responses: Vec<Response>) -> HttpResult<()> {
134        for response in responses.into_iter() {
135            try!(self.conn.start_response(
136                    response.headers,
137                    response.stream_id,
138                    EndStream::No));
139            let mut stream = self.conn.state.get_stream_mut(response.stream_id).unwrap();
140            stream.set_full_data(response.body);
141        }
142
143        Ok(())
144    }
145
146    /// Flushes the outgoing buffers of all streams.
147    #[inline]
148    fn flush_streams(&mut self) -> HttpResult<()> {
149        while let SendStatus::Sent = try!(self.conn.send_next_data()) {}
150
151        Ok(())
152    }
153
154    /// Removes closed streams from the connection state.
155    #[inline]
156    fn reap_streams(&mut self) -> HttpResult<()> {
157        // Moves the streams out of the state and then drops them
158        let _ = self.conn.state.get_closed();
159        Ok(())
160    }
161}