miasht/server/
response.rs1use std::io::{self, Write};
2use futures::{Async, Future, Poll};
3
4use {Error, Status, TransportStream};
5use status::RawStatus;
6use header::{Header, HeadersMut};
7use super::Connection;
8
9pub fn builder<T>(mut connection: Connection<T>, status: RawStatus) -> ResponseBuilder<T>
10where
11 T: TransportStream,
12{
13 connection.inner.buffer.enter_write_phase();
14 let _ = write!(
15 connection.inner.buffer,
16 "{} {}\r\n",
17 connection.version, status
18 );
19 ResponseBuilder(connection)
20}
21
22#[derive(Debug)]
23pub struct ResponseBuilder<T>(Connection<T>);
24impl<T: TransportStream> ResponseBuilder<T> {
25 pub fn headers_mut(&mut self) -> HeadersMut {
26 HeadersMut::new(&mut self.0.inner.buffer)
27 }
28 pub fn add_raw_header(&mut self, name: &str, value: &[u8]) -> &mut Self {
29 self.headers_mut().add_raw_header(name, value);
30 self
31 }
32 pub fn add_header<'a, H: Header<'a>>(&mut self, header: &H) -> &mut Self {
33 self.headers_mut().add_header(header);
34 self
35 }
36 pub fn finish(mut self) -> Response<T> {
37 let _ = write!(self.0.inner.buffer, "\r\n");
38 Response(Some(self.0))
39 }
40}
41
42#[derive(Debug)]
43pub struct Response<T>(Option<Connection<T>>);
44impl<T: TransportStream> Write for Response<T> {
45 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
46 if let Some(ref mut c) = self.0 {
47 c.inner.flush_buffer()?;
48 c.inner.stream.write(buf)
49 } else {
50 Err(io::Error::new(
51 io::ErrorKind::WriteZero,
52 "Cannot write into finished response",
53 ))
54 }
55 }
56 fn flush(&mut self) -> io::Result<()> {
57 if let Some(ref mut c) = self.0 {
58 c.inner.flush_buffer()?;
59 c.inner.stream.flush()?;
60 }
61 Ok(())
62 }
63}
64impl<T: TransportStream> Future for Response<T> {
65 type Item = Connection<T>;
66 type Error = Error;
67 fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
68 match self.flush() {
69 Err(e) => {
70 track_assert_eq!(
71 e.kind(),
72 io::ErrorKind::WouldBlock,
73 Status::InternalServerError
74 );
75 Ok(Async::NotReady)
76 }
77 Ok(()) => {
78 let connection = self.0.take().expect("Cannot poll Response twice");
79 Ok(Async::Ready(connection))
80 }
81 }
82 }
83}