silver_rs/
response.rs

1use bytes::{BufMut, BytesMut};
2use futures::future;
3
4use SilverResult;
5
6pub struct Response {
7    headers: Vec<(String, String)>,
8    response: String,
9    status: usize,
10}
11
12impl Response {
13    pub fn new() -> Response {
14        Response {
15            headers: Vec::new(),
16            response: String::new(),
17            status: 200,
18        }
19    }
20
21    pub fn status(&mut self, code: usize) -> &mut Response {
22        self.status = code;
23        self
24    }
25
26    pub fn header(&mut self, name: &str, val: &str) -> &mut Response {
27        self.headers.push((name.to_string(), val.to_string()));
28        self
29    }
30
31    pub fn body(&mut self, s: &str) -> &mut Response {
32        self.response = s.to_string();
33        self
34    }
35
36    pub fn ok(self) -> SilverResult {
37        future::ok(self)
38    }
39}
40
41pub fn encode(msg: &Response, buf: &mut BytesMut) {
42    let length = msg.response.len();
43
44    push(buf, &[72, 84, 84, 80, 47, 49, 46, 49, 32]); // "HTTP/1.1 "
45    push(buf, &usize_to_bytes(msg.status));
46    push(
47        buf,
48        &[
49            13, 10, 67, 111, 110, 116, 101, 110, 116, 45, 76, 101, 110, 103, 116, 104, 58, 32,
50        ],
51    ); // "Content-Length: "
52    push(buf, &usize_to_bytes(length));
53    push(buf, &[13, 10]); // "\r\n"
54
55    for &(ref k, ref v) in &msg.headers {
56        push(buf, k.as_bytes());
57        push(buf, &[58, 32]); // ": "
58        push(buf, v.as_bytes());
59        push(buf, &[13, 10]); // "\r\n"
60    }
61
62    push(buf, &[13, 10]); // "\r\n"
63    push(buf, msg.response.as_bytes());
64}
65
66fn push(buf: &mut BytesMut, data: &[u8]) {
67    buf.reserve(data.len());
68    unsafe {
69        buf.bytes_mut()[..data.len()].copy_from_slice(data);
70        buf.advance_mut(data.len());
71    }
72}
73
74fn usize_to_bytes(s: usize) -> [u8; 4] {
75    let mut data: [u8; 4] = [0; 4];
76    let mut length = s as u16;
77
78    // Convert u16 to ASCII bytes
79    for i in 1..5 {
80        data[4 - i] = (48 + (length % (10 * i) as u16)) as u8;
81        length = &length / (10 * i) as u16;
82    }
83
84    return data;
85}