peta/
response.rs

1use super::date;
2use super::status;
3use super::writer;
4
5use bytes::{BufMut, BytesMut};
6use tokio::prelude::*;
7
8/// Creates HTTP response.
9///
10/// # Example
11/// ```
12/// let res = Response::new();
13///
14/// res.status(status::OK);
15/// res.header("key", "value");
16/// res.header("another", "value");
17///
18/// res.body_str("Hello world");
19///
20/// // write response to the socket
21/// res.write(writer)
22///
23/// ```
24pub struct Response {
25  // consider to use different body structure
26  body: Option<Vec<u8>>,
27  status: Option<&'static str>,
28  headers: Vec<(&'static str, &'static str)>,
29}
30
31impl Response {
32  /// Create new instance of Response.
33  ///
34  /// ```
35  /// let mut res = Response::new();
36  /// ```
37  pub fn new() -> Response {
38    Response {
39      body: None,
40      status: None,
41      headers: Vec::with_capacity(50),
42    }
43  }
44
45  /// Attache status to the http response (can use `status` module).
46  ///
47  /// ```
48  /// res.status(status::OK);
49  /// ```
50  pub fn status(&mut self, status: &'static str) {
51    self.status = Some(status);
52  }
53
54  /// Attache single header to http response, can be reused.
55  ///
56  /// ```
57  /// res.header("Header", "Value");
58  /// ```
59  pub fn header(&mut self, name: &'static str, value: &'static str) {
60    self.headers.push((name, value));
61  }
62
63  // need to add different ways to add body
64  /// Attache `Vec` body to the http response.
65  ///
66  /// ```
67  /// let body = vec![....];
68  /// res.body_vec(body);
69  /// ```
70  pub fn body_vec(&mut self, body: Vec<u8>) {
71    self.body = Some(body);
72  }
73
74  /// Transform `&str` to `Vec` and attach it to the http response.
75  ///
76  /// ```
77  /// res.body_str("Hello world");
78  /// ```
79  pub fn body_str(&mut self, body: &str) {
80    self.body = Some(body.as_bytes().to_vec());
81  }
82
83  // we should not pass buff in here
84  /// Process Response and return future which writes response to the `AsyncWrite` socket.
85  ///
86  /// ```
87  /// let (read, write) = socket.split();
88  /// ...
89  /// res.write(write);
90  /// ```
91  pub fn write<S: AsyncWrite>(&self, writer: S) -> writer::WriteAll<S> {
92    // write all data together
93    let mut buf = BytesMut::with_capacity(4096);
94
95    // write status, set default to 200 if does not exist
96    push(&mut buf, b"HTTP/1.1 ");
97    push(&mut buf, self.status.unwrap_or(status::OK).as_bytes());
98    push(&mut buf, b"\r\n");
99
100    // write headers
101    for val in &self.headers {
102      push(&mut buf, val.0.as_bytes());
103      push(&mut buf, b": ");
104      push(&mut buf, val.1.as_bytes());
105      push(&mut buf, b"\r\n");
106    }
107
108    // set date header
109    date::set_date_header(&mut buf);
110
111    // add content-length and actual body
112    match &self.body {
113      Some(body) => {
114        push(&mut buf, b"content-length: ");
115        push(&mut buf, body.len().to_string().as_bytes());
116        push(&mut buf, b"\r\n\r\n");
117        push(&mut buf, body.as_slice());
118      }
119      None => push(&mut buf, b"content-length: 0\r\n\r\n"),
120    };
121
122    // write to socket
123    writer::write_all(writer, buf)
124  }
125}
126
127// fast unsafe push
128pub(crate) fn push(buf: &mut BytesMut, data: &[u8]) {
129  if buf.remaining_mut() < data.len() {
130    buf.reserve(data.len());
131  }
132
133  unsafe {
134    buf.bytes_mut()[..data.len()].copy_from_slice(data);
135    buf.advance_mut(data.len());
136  }
137}