ttpkit_http/
request.rs

1//! Request types.
2
3use bytes::BytesMut;
4use tokio_util::codec::{Decoder, Encoder};
5
6use crate::{
7    CodecError, Method, Protocol, Version,
8    header::{FieldIter, HeaderField, HeaderFieldValue, Iter},
9    ttpkit::request::{
10        RequestHeader as GenericRequestHeader, RequestHeaderBuilder as GenericRequestHeaderBuilder,
11        RequestHeaderDecoder as GenericRequestHeaderDecoder,
12        RequestHeaderEncoder as GenericRequestHeaderEncoder,
13    },
14};
15
16pub use crate::ttpkit::request::{RequestHeaderDecoderOptions, RequestPath};
17
18/// HTTP request header.
19#[derive(Clone)]
20pub struct RequestHeader {
21    inner: GenericRequestHeader<Protocol, Version, Method>,
22}
23
24impl RequestHeader {
25    /// Create a new request header.
26    #[inline]
27    pub(crate) const fn new(header: GenericRequestHeader<Protocol, Version, Method>) -> Self {
28        Self { inner: header }
29    }
30
31    /// Get the request method.
32    #[inline]
33    pub fn method(&self) -> Method {
34        *self.inner.method()
35    }
36
37    /// Get the request protocol version.
38    #[inline]
39    pub fn version(&self) -> Version {
40        *self.inner.version()
41    }
42
43    /// Get the request path.
44    #[inline]
45    pub fn path(&self) -> &RequestPath {
46        self.inner.path()
47    }
48
49    /// Get all header fields.
50    #[inline]
51    pub fn get_all_header_fields(&self) -> Iter<'_> {
52        self.inner.get_all_header_fields()
53    }
54
55    /// Get header fields corresponding to a given name.
56    pub fn get_header_fields<'a, N>(&'a self, name: &'a N) -> FieldIter<'a>
57    where
58        N: AsRef<[u8]> + ?Sized,
59    {
60        self.inner.get_header_fields(name)
61    }
62
63    /// Get the last header field of a given name.
64    pub fn get_header_field<'a, N>(&'a self, name: &'a N) -> Option<&'a HeaderField>
65    where
66        N: AsRef<[u8]> + ?Sized,
67    {
68        self.inner.get_header_field(name)
69    }
70
71    /// Get value of the last header field with a given name.
72    pub fn get_header_field_value<'a, N>(&'a self, name: &'a N) -> Option<&'a HeaderFieldValue>
73    where
74        N: AsRef<[u8]> + ?Sized,
75    {
76        self.inner.get_header_field_value(name)
77    }
78}
79
80/// HTTP request builder.
81#[derive(Clone)]
82pub struct RequestBuilder {
83    inner: GenericRequestHeaderBuilder<Protocol, Version, Method>,
84}
85
86impl RequestBuilder {
87    /// Create a new builder.
88    #[inline]
89    const fn new(version: Version, method: Method, path: RequestPath) -> Self {
90        Self {
91            inner: GenericRequestHeader::builder(Protocol, version, method, path),
92        }
93    }
94
95    /// Set the protocol version.
96    #[inline]
97    pub fn set_version(mut self, version: Version) -> Self {
98        self.inner = self.inner.set_version(version);
99        self
100    }
101
102    /// Set the request method.
103    #[inline]
104    pub fn set_method(mut self, method: Method) -> Self {
105        self.inner = self.inner.set_method(method);
106        self
107    }
108
109    /// Set the request path.
110    #[inline]
111    pub fn set_path(mut self, path: RequestPath) -> Self {
112        self.inner = self.inner.set_path(path);
113        self
114    }
115
116    /// Replace the current header fields having the same name (if any).
117    pub fn set_header_field<T>(mut self, field: T) -> Self
118    where
119        T: Into<HeaderField>,
120    {
121        self.inner = self.inner.set_header_field(field);
122        self
123    }
124
125    /// Add a given header field.
126    pub fn add_header_field<T>(mut self, field: T) -> Self
127    where
128        T: Into<HeaderField>,
129    {
130        self.inner = self.inner.add_header_field(field);
131        self
132    }
133
134    /// Remove all header fields with a given name.
135    pub fn remove_header_fields<N>(mut self, name: &N) -> Self
136    where
137        N: AsRef<[u8]> + ?Sized,
138    {
139        self.inner = self.inner.remove_header_fields(name);
140        self
141    }
142
143    /// Build just the request header.
144    #[inline]
145    pub fn header(self) -> RequestHeader {
146        RequestHeader::new(self.inner.build())
147    }
148
149    /// Build the request.
150    pub fn body<B>(self, body: B) -> Request<B> {
151        Request::new(self.header(), body)
152    }
153}
154
155impl From<RequestHeader> for RequestBuilder {
156    #[inline]
157    fn from(header: RequestHeader) -> Self {
158        Self {
159            inner: header.inner.into(),
160        }
161    }
162}
163
164/// HTTP request.
165pub struct Request<B> {
166    header: RequestHeader,
167    body: B,
168}
169
170impl Request<()> {
171    /// Get a request builder.
172    #[inline]
173    pub const fn builder(version: Version, method: Method, path: RequestPath) -> RequestBuilder {
174        RequestBuilder::new(version, method, path)
175    }
176}
177
178impl<B> Request<B> {
179    /// Create a new request.
180    pub(crate) const fn new(header: RequestHeader, body: B) -> Self {
181        Self { header, body }
182    }
183
184    /// Get the request header.
185    #[inline]
186    pub fn header(&self) -> &RequestHeader {
187        &self.header
188    }
189
190    /// Get the request method.
191    #[inline]
192    pub fn method(&self) -> Method {
193        self.header.method()
194    }
195
196    /// Get the request protocol version.
197    #[inline]
198    pub fn version(&self) -> Version {
199        self.header.version()
200    }
201
202    /// Get the request path.
203    #[inline]
204    pub fn path(&self) -> &RequestPath {
205        self.header.path()
206    }
207
208    /// Get all header fields.
209    #[inline]
210    pub fn get_all_header_fields(&self) -> Iter<'_> {
211        self.header.get_all_header_fields()
212    }
213
214    /// Get header fields corresponding to a given name.
215    pub fn get_header_fields<'a, N>(&'a self, name: &'a N) -> FieldIter<'a>
216    where
217        N: AsRef<[u8]> + ?Sized,
218    {
219        self.header.get_header_fields(name)
220    }
221
222    /// Get the last header field of a given name.
223    pub fn get_header_field<'a, N>(&'a self, name: &'a N) -> Option<&'a HeaderField>
224    where
225        N: AsRef<[u8]> + ?Sized,
226    {
227        self.header.get_header_field(name)
228    }
229
230    /// Get value of the last header field with a given name.
231    pub fn get_header_field_value<'a, N>(&'a self, name: &'a N) -> Option<&'a HeaderFieldValue>
232    where
233        N: AsRef<[u8]> + ?Sized,
234    {
235        self.header.get_header_field_value(name)
236    }
237
238    /// Take the request body.
239    #[inline]
240    pub fn body(self) -> B {
241        self.body
242    }
243
244    /// Split the request into its header and body.
245    #[inline]
246    pub fn deconstruct(self) -> (RequestHeader, B) {
247        (self.header, self.body)
248    }
249}
250
251/// Request header decoder.
252pub struct RequestHeaderDecoder {
253    inner: GenericRequestHeaderDecoder<Protocol, Version, Method>,
254}
255
256impl RequestHeaderDecoder {
257    /// Create a new decoder.
258    #[inline]
259    pub fn new(options: RequestHeaderDecoderOptions) -> Self {
260        Self {
261            inner: GenericRequestHeaderDecoder::new(options),
262        }
263    }
264
265    /// Reset the decoder and make it ready for parsing a new request header.
266    #[inline]
267    pub fn reset(&mut self) {
268        self.inner.reset();
269    }
270
271    /// Decode a given request header chunk.
272    pub fn decode(&mut self, data: &mut BytesMut) -> Result<Option<RequestHeader>, CodecError> {
273        let res = self.inner.decode(data)?.map(RequestHeader::new);
274
275        Ok(res)
276    }
277
278    /// Decode a given request header chunk at the end of the stream.
279    pub fn decode_eof(&mut self, data: &mut BytesMut) -> Result<Option<RequestHeader>, CodecError> {
280        let res = self.inner.decode_eof(data)?.map(RequestHeader::new);
281
282        Ok(res)
283    }
284}
285
286impl Decoder for RequestHeaderDecoder {
287    type Item = RequestHeader;
288    type Error = CodecError;
289
290    #[inline]
291    fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
292        Self::decode(self, buf)
293    }
294
295    #[inline]
296    fn decode_eof(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
297        Self::decode_eof(self, buf)
298    }
299}
300
301/// Request header encoder.
302pub struct RequestHeaderEncoder {
303    inner: GenericRequestHeaderEncoder,
304}
305
306impl RequestHeaderEncoder {
307    /// Create a new encoder.
308    #[inline]
309    pub const fn new() -> Self {
310        Self {
311            inner: GenericRequestHeaderEncoder::new(),
312        }
313    }
314
315    /// Encode a given request header into a given buffer.
316    #[inline]
317    pub fn encode(&mut self, header: &RequestHeader, dst: &mut BytesMut) {
318        self.inner.encode(&header.inner, dst);
319    }
320}
321
322impl Default for RequestHeaderEncoder {
323    #[inline]
324    fn default() -> Self {
325        Self::new()
326    }
327}
328
329impl Encoder<&RequestHeader> for RequestHeaderEncoder {
330    type Error = CodecError;
331
332    #[inline]
333    fn encode(&mut self, header: &RequestHeader, dst: &mut BytesMut) -> Result<(), Self::Error> {
334        Self::encode(self, header, dst);
335
336        Ok(())
337    }
338}