proto_tower_http_1/data/
mod.rs

1pub mod request;
2
3use crate::data::request::HTTP1Request;
4use tokio::io::{AsyncReadExt, AsyncWriteExt};
5
6/// A service downstream from HTTP1ServerLayer will receive these structs
7pub enum HTTP1ServerEvent<READER, WRITER>
8where
9    READER: AsyncReadExt + Send + Unpin + 'static,
10    WRITER: AsyncWriteExt + Send + Unpin + 'static,
11{
12    Request(HTTP1Request),
13    /// A protocol upgrade including the original request and subsequent response
14    ProtocolUpgrade(HTTP1Request, HTTP1Response, (READER, WRITER)),
15}
16
17/// When the client is called, it returns this value
18#[derive(Debug, Eq, PartialEq)]
19pub enum HTTP1ClientResponse<Reader, Writer>
20where
21    Reader: AsyncReadExt + Send + Unpin + 'static,
22    Writer: AsyncWriteExt + Send + Unpin + 'static,
23{
24    Response(HTTP1Response),
25    /// If the response is a protocol upgrade, you will get this instead of a normal response
26    ProtocolUpgrade(HTTP1Response, (Reader, Writer)),
27}
28
29pub enum Http1ServerResponseEvent {
30    /// Use this for protocol upgrades
31    NoResponseExpected,
32    /// Use this for request responses
33    Response(HTTP1Response),
34}
35
36#[derive(Debug, Eq, PartialEq)]
37pub enum ProtoHttp1LayerError<SvcError> {
38    /// An error in the implementation of this layer
39    #[allow(dead_code)]
40    Implementation(String),
41    /// The internal service returned a wrong response
42    InternalServiceWrongResponse,
43    /// An error in the internal service
44    InternalServiceError(SvcError),
45}
46
47/// An HTTP/1.1 response
48#[derive(Debug, Eq, PartialEq)]
49pub struct HTTP1Response {
50    pub status: http::StatusCode,
51    pub headers: http::HeaderMap,
52    pub body: Vec<u8>,
53}
54
55impl HTTP1Response {
56    pub async fn write_onto<WRITER: AsyncWriteExt + Send + Unpin + 'static>(&self, writer: &mut WRITER) {
57        // RESPONSE
58        const VERSION: &[u8] = "HTTP/1.1".as_bytes();
59        writer.write_all(VERSION).await.unwrap();
60        writer.write_all(" ".as_bytes()).await.unwrap();
61        writer.write_all(self.status.as_str().as_bytes()).await.unwrap();
62        writer.write_all(" ".as_bytes()).await.unwrap();
63        writer.write_all(self.status.canonical_reason().unwrap_or("UNKNOWN REASON").as_bytes()).await.unwrap();
64        writer.write_all("\r\n".as_bytes()).await.unwrap();
65
66        // HEADERS
67        for (k, v) in self.headers.iter() {
68            writer.write_all(k.as_str().as_bytes()).await.unwrap();
69            writer.write_all(": ".as_bytes()).await.unwrap();
70            writer.write_all(v.as_bytes()).await.unwrap();
71            writer.write_all("\r\n".as_bytes()).await.unwrap();
72        }
73        writer.write_all("\r\n".as_bytes()).await.unwrap();
74
75        // BODY
76        writer.write_all(&self.body).await.unwrap();
77    }
78}