• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 use core::mem::take;
15 
16 use crate::error::{ErrorKind, HttpError};
17 use crate::h1::H1Error;
18 use crate::headers::Headers;
19 use crate::response::status::StatusCode;
20 use crate::response::ResponsePart;
21 use crate::util::header_bytes::{HEADER_NAME_BYTES, HEADER_VALUE_BYTES};
22 use crate::version::Version;
23 
24 /// `HTTP/1` response decoder, which support decoding multi-segment byte
25 /// streams into `Response`.
26 ///
27 /// # Examples
28 ///
29 /// ```
30 /// use ylong_http::h1::ResponseDecoder;
31 /// use ylong_http::version::Version;
32 ///
33 /// // The complete message is:
34 /// // "HTTP/1.1 304 OK\r\nContent-Length:4\r\n\r\nbody"
35 /// let strings = ["HTTP/1.1 304 OK\r\nCon", "tent-Length:", "4\r\n\r\nbody"];
36 ///
37 /// // We need to create a decoder first.
38 /// let mut decoder = ResponseDecoder::new();
39 ///
40 /// // Then we use it to decode some bytes.
41 /// // The first part of bytes is correct, but we need more bytes to get a `ResponsePart`.
42 /// assert_eq!(decoder.decode(strings[0].as_bytes()), Ok(None));
43 /// // The second part is also correct, but we still need more bytes.
44 /// assert_eq!(decoder.decode(strings[1].as_bytes()), Ok(None));
45 /// // After decoding the third part, a complete `ResponsePart` is decoded.
46 /// let (part, body) = decoder.decode(strings[2].as_bytes()).unwrap().unwrap();
47 ///
48 /// // Then we can use the decode result.
49 /// assert_eq!(part.version.as_str(), "HTTP/1.1");
50 /// assert_eq!(part.status.as_u16(), 304);
51 /// assert_eq!(
52 ///     part.headers
53 ///         .get("content-length")
54 ///         .unwrap()
55 ///         .to_string()
56 ///         .unwrap(),
57 ///     "4"
58 /// );
59 /// assert_eq!(body, b"body");
60 /// ```
61 pub struct ResponseDecoder {
62     // Parsing phase, corresponding to each component of response-message.
63     stage: ParseStage,
64     version: Option<Version>,
65     status_code: Option<StatusCode>,
66     headers: Option<Headers>,
67     // Cache the parsed header key.
68     head_key: Vec<u8>,
69     // Cache the response-message component whose current bytes segment is incomplete
70     rest: Vec<u8>,
71     // The value is true when the last byte of the current byte segment is CR.
72     new_line: bool,
73 }
74 
75 // Component parsing status
76 enum TokenStatus<T, E> {
77     // The current component is completely parsed.
78     Complete(T),
79     // The current component is not completely parsed.
80     Partial(E),
81 }
82 
83 // ResponseDecoder parsing phase, All components of response-message are as
84 // follows:
85 // ---------------------------------------------------------
86 // | HTTP-version SP status-code SP [ reason-phrase ]CRLF  | // status-line
87 // | *( field-name ":" OWS field-value OWS CRLF )          | // field-line
88 // | CRLF                                                  |
89 // | [message-body ]                                       |
90 // ---------------------------------------------------------
91 #[derive(Clone)]
92 enum ParseStage {
93     // Decoder initialization phase, The decoder parses the bytes for the first time.
94     Initial,
95     // "HTTP-version" phase of parsing response-message
96     Version,
97     // "status-code" phase of parsing response-message
98     StatusCode,
99     // "reason-phrase" phase of parsing response-message
100     Reason,
101     // CRLF after "reason-phrase" of parsing response-message
102     StatusCrlf,
103     // "field-line" phase of parsing response-message
104     Header(HeaderStage),
105     // CRLF after "field-line" of parsing response-message
106     BlankLine,
107 }
108 
109 // Stage of parsing field-line, the filed line component is as follows:
110 // ------------------------------------------------
111 // | *( field-name ":" OWS field-value OWS CRLF )  |
112 // ------------------------------------------------
113 #[derive(Clone)]
114 enum HeaderStage {
115     // Check whether the response-message contains field-line.
116     Start,
117     Key,
118     // OWS phase before "field-value"
119     OwsBefore,
120     Value,
121     Crlf,
122     // After a filed-line line is parsed, the parsing phase is EndCrlf.
123     // In this case, you need to check whether all field lines are ended.
124     EndCrlf,
125 }
126 
127 impl Default for ResponseDecoder {
default() -> Self128     fn default() -> Self {
129         Self::new()
130     }
131 }
132 
133 type TokenResult<'a> = Result<TokenStatus<(&'a [u8], &'a [u8]), &'a [u8]>, HttpError>;
134 
135 macro_rules! get_unparsed_or_return {
136     ($case:expr, $buffer:expr) => {{
137         match $case {
138             Some(unparsed) => $buffer = unparsed,
139             None => return Ok(None),
140         }
141     }};
142 }
143 
144 macro_rules! detect_blank_and_return {
145     ($case:expr, $buffer:expr) => {{
146         if $buffer.is_empty() {
147             $case = ParseStage::Header(HeaderStage::EndCrlf);
148             return Ok(None);
149         } else if $buffer[0] == b'\r' || $buffer[0] == b'\n' {
150             return Ok(Some($buffer));
151         }
152     }};
153 }
154 
155 impl ResponseDecoder {
156     /// Creates a new `ResponseDecoder`.
157     ///
158     /// # Examples
159     ///
160     /// ```
161     /// use ylong_http::h1::ResponseDecoder;
162     ///
163     /// let decoder = ResponseDecoder::new();
164     /// ```
new() -> Self165     pub fn new() -> Self {
166         ResponseDecoder {
167             stage: ParseStage::Initial,
168             version: None,
169             status_code: None,
170             headers: None,
171             head_key: vec![],
172             rest: vec![],
173             new_line: false,
174         }
175     }
176 
177     /// Decodes some bytes to get a complete `ResponsePart`. This method can be
178     /// invoked multiple times util a complete `ResponsePart` is returned.
179     ///
180     /// Only status line and field line is decoded. The body of `Response` is
181     /// not be decoded.
182     ///
183     /// Returns `Ok(None)` if decoder needs more bytes to decode.
184     ///
185     /// Returns `ResponsePart` and the remaining bytes if decoder has complete
186     /// decoding. The remaining bytes will be returned as a slice.
187     ///
188     /// Returns `Err` if the input is not syntactically valid.
189     ///
190     /// # Examples
191     ///
192     /// ```
193     /// use ylong_http::h1::ResponseDecoder;
194     /// use ylong_http::version::Version;
195     ///
196     /// let valid = ["HTTP/1.1", " 304 OK\r\n\r\n"];
197     /// let mut decoder = ResponseDecoder::new();
198     /// // Returns `Ok(None)` if decoder needs more bytes to decode.
199     /// assert_eq!(decoder.decode(valid[0].as_bytes()), Ok(None));
200     /// // Returns `ResponsePart` and a slice of bytes if decoder has complete decoding.
201     /// let (part, body) = decoder.decode(valid[1].as_bytes()).unwrap().unwrap();
202     /// assert_eq!(part.version, Version::HTTP1_1);
203     /// assert_eq!(part.status.as_u16(), 304);
204     /// assert!(part.headers.is_empty());
205     /// assert!(body.is_empty());
206     ///
207     /// // Returns `Err` if the input is not syntactically valid.
208     /// let mut decoder = ResponseDecoder::new();
209     /// let invalid_str = "invalid str".as_bytes();
210     /// assert!(decoder.decode(invalid_str).is_err());
211     /// ```
decode<'a>( &mut self, buf: &'a [u8], ) -> Result<Option<(ResponsePart, &'a [u8])>, HttpError>212     pub fn decode<'a>(
213         &mut self,
214         buf: &'a [u8],
215     ) -> Result<Option<(ResponsePart, &'a [u8])>, HttpError> {
216         match self.stage {
217             ParseStage::Initial => self.version_phase(buf),
218             ParseStage::Version => self.version_phase(buf),
219             ParseStage::StatusCode => self.status_code_phase(buf),
220             ParseStage::Reason => self.reason_phase(buf),
221             ParseStage::StatusCrlf => self.status_crlf_phase(buf),
222             ParseStage::Header(_) => self.header_phase(buf),
223             ParseStage::BlankLine => self.blank_line_phase(buf),
224         }
225     }
226 
version_phase<'a>( &mut self, buffer: &'a [u8], ) -> Result<Option<(ResponsePart, &'a [u8])>, HttpError>227     fn version_phase<'a>(
228         &mut self,
229         buffer: &'a [u8],
230     ) -> Result<Option<(ResponsePart, &'a [u8])>, HttpError> {
231         self.stage = ParseStage::Version;
232         match status_token(buffer)? {
233             TokenStatus::Complete((version, unparsed)) => {
234                 let version = self.take_value(version);
235                 match version.as_slice() {
236                     b"HTTP/1.0" => {
237                         self.version = Some(Version::HTTP1_0);
238                     }
239                     b"HTTP/1.1" => {
240                         self.version = Some(Version::HTTP1_1);
241                     }
242                     // TODO: Support for other `HTTP` versions.
243                     _ => return Err(ErrorKind::H1(H1Error::InvalidResponse).into()),
244                 }
245                 self.status_code_phase(unparsed)
246             }
247             TokenStatus::Partial(rest) => {
248                 self.rest.extend_from_slice(rest);
249                 Ok(None)
250             }
251         }
252     }
253 
status_code_phase<'a>( &mut self, buffer: &'a [u8], ) -> Result<Option<(ResponsePart, &'a [u8])>, HttpError>254     fn status_code_phase<'a>(
255         &mut self,
256         buffer: &'a [u8],
257     ) -> Result<Option<(ResponsePart, &'a [u8])>, HttpError> {
258         self.stage = ParseStage::StatusCode;
259         match status_token(buffer)? {
260             TokenStatus::Complete((code, unparsed)) => {
261                 let code = self.take_value(code);
262                 self.status_code = Some(
263                     StatusCode::from_bytes(code.as_slice())
264                         .map_err(|_| HttpError::from(ErrorKind::H1(H1Error::InvalidResponse)))?,
265                 );
266                 self.reason_phase(unparsed)
267             }
268             TokenStatus::Partial(rest) => {
269                 self.rest.extend_from_slice(rest);
270                 Ok(None)
271             }
272         }
273     }
274 
reason_phase<'a>( &mut self, buffer: &'a [u8], ) -> Result<Option<(ResponsePart, &'a [u8])>, HttpError>275     fn reason_phase<'a>(
276         &mut self,
277         buffer: &'a [u8],
278     ) -> Result<Option<(ResponsePart, &'a [u8])>, HttpError> {
279         self.stage = ParseStage::Reason;
280         match decode_reason(buffer)? {
281             Some(unparsed) => self.status_crlf_phase(unparsed),
282             None => Ok(None),
283         }
284     }
285 
status_crlf_phase<'a>( &mut self, buffer: &'a [u8], ) -> Result<Option<(ResponsePart, &'a [u8])>, HttpError>286     fn status_crlf_phase<'a>(
287         &mut self,
288         buffer: &'a [u8],
289     ) -> Result<Option<(ResponsePart, &'a [u8])>, HttpError> {
290         self.stage = ParseStage::StatusCrlf;
291         match self.decode_status_crlf(buffer)? {
292             Some(unparsed) => self.header_phase_with_init(unparsed),
293             None => Ok(None),
294         }
295     }
296 
header_phase_with_init<'a>( &mut self, buffer: &'a [u8], ) -> Result<Option<(ResponsePart, &'a [u8])>, HttpError>297     fn header_phase_with_init<'a>(
298         &mut self,
299         buffer: &'a [u8],
300     ) -> Result<Option<(ResponsePart, &'a [u8])>, HttpError> {
301         let headers = Headers::new();
302         self.headers = Some(headers);
303         if buffer.is_empty() {
304             self.stage = ParseStage::Header(HeaderStage::Start);
305             return Ok(None);
306         } else if buffer[0] == b'\r' || buffer[0] == b'\n' {
307             return self.blank_line_phase(buffer);
308         } else {
309             self.stage = ParseStage::Header(HeaderStage::Key);
310         }
311         match self.decode_header(buffer)? {
312             Some(unparsed) => self.blank_line_phase(unparsed),
313             None => Ok(None),
314         }
315     }
316 
header_phase<'a>( &mut self, buffer: &'a [u8], ) -> Result<Option<(ResponsePart, &'a [u8])>, HttpError>317     fn header_phase<'a>(
318         &mut self,
319         buffer: &'a [u8],
320     ) -> Result<Option<(ResponsePart, &'a [u8])>, HttpError> {
321         match self.decode_header(buffer)? {
322             Some(unparsed) => self.blank_line_phase(unparsed),
323             None => Ok(None),
324         }
325     }
326 
blank_line_phase<'a>( &mut self, buffer: &'a [u8], ) -> Result<Option<(ResponsePart, &'a [u8])>, HttpError>327     fn blank_line_phase<'a>(
328         &mut self,
329         buffer: &'a [u8],
330     ) -> Result<Option<(ResponsePart, &'a [u8])>, HttpError> {
331         self.stage = ParseStage::BlankLine;
332         match self.decode_status_crlf(buffer)? {
333             Some(unparsed) => {
334                 let response_part = ResponsePart {
335                     version: self.version.take().unwrap(),
336                     status: self.status_code.take().unwrap(),
337                     headers: self.headers.take().unwrap(),
338                 };
339                 Ok(Some((response_part, unparsed)))
340             }
341             None => Ok(None),
342         }
343     }
344 
decode_status_crlf<'a>(&mut self, buffer: &'a [u8]) -> Result<Option<&'a [u8]>, HttpError>345     fn decode_status_crlf<'a>(&mut self, buffer: &'a [u8]) -> Result<Option<&'a [u8]>, HttpError> {
346         match consume_crlf(buffer, take(&mut self.new_line))? {
347             TokenStatus::Complete(unparsed) => {
348                 self.new_line = false;
349                 Ok(Some(unparsed))
350             }
351             TokenStatus::Partial(0) => Ok(None),
352             TokenStatus::Partial(1) => {
353                 self.new_line = true;
354                 Ok(None)
355             }
356             _ => Err(ErrorKind::H1(H1Error::InvalidResponse).into()),
357         }
358     }
359 
decode_header<'a>(&mut self, buffer: &'a [u8]) -> Result<Option<&'a [u8]>, HttpError>360     fn decode_header<'a>(&mut self, buffer: &'a [u8]) -> Result<Option<&'a [u8]>, HttpError> {
361         return match &self.stage {
362             ParseStage::Header(header_stage) => match header_stage {
363                 HeaderStage::Start => {
364                     if buffer.is_empty() {
365                         return Ok(None);
366                     } else if buffer[0] == b'\r' || buffer[0] == b'\n' {
367                         return Ok(Some(buffer));
368                     } else {
369                         self.decode_header_from_key(buffer)
370                     }
371                 }
372                 HeaderStage::Key => self.decode_header_from_key(buffer),
373                 HeaderStage::OwsBefore => self.decode_header_from_ows_before(buffer),
374                 HeaderStage::Value => self.decode_header_from_value(buffer),
375                 HeaderStage::Crlf => self.decode_header_from_crlf(buffer),
376                 HeaderStage::EndCrlf => self.decode_header_from_crlf_end(buffer),
377             },
378             _ => Err(ErrorKind::H1(H1Error::InvalidResponse).into()),
379         };
380     }
381 
decode_header_from_value<'a>( &mut self, buffer: &'a [u8], ) -> Result<Option<&'a [u8]>, HttpError>382     fn decode_header_from_value<'a>(
383         &mut self,
384         buffer: &'a [u8],
385     ) -> Result<Option<&'a [u8]>, HttpError> {
386         let mut buffer = buffer;
387         loop {
388             get_unparsed_or_return!(self.decode_value(buffer)?, buffer);
389             get_unparsed_or_return!(self.decode_crlf(false, buffer)?, buffer);
390             detect_blank_and_return!(self.stage, buffer);
391             get_unparsed_or_return!(self.decode_key(buffer)?, buffer);
392             get_unparsed_or_return!(self.decode_ows(buffer)?, buffer);
393         }
394     }
395 
decode_header_from_key<'a>( &mut self, buffer: &'a [u8], ) -> Result<Option<&'a [u8]>, HttpError>396     fn decode_header_from_key<'a>(
397         &mut self,
398         buffer: &'a [u8],
399     ) -> Result<Option<&'a [u8]>, HttpError> {
400         let mut buffer = buffer;
401         loop {
402             get_unparsed_or_return!(self.decode_key(buffer)?, buffer);
403             get_unparsed_or_return!(self.decode_ows(buffer)?, buffer);
404             get_unparsed_or_return!(self.decode_value(buffer)?, buffer);
405             get_unparsed_or_return!(self.decode_crlf(false, buffer)?, buffer);
406             detect_blank_and_return!(self.stage, buffer);
407         }
408     }
409 
decode_header_from_ows_before<'a>( &mut self, buffer: &'a [u8], ) -> Result<Option<&'a [u8]>, HttpError>410     fn decode_header_from_ows_before<'a>(
411         &mut self,
412         buffer: &'a [u8],
413     ) -> Result<Option<&'a [u8]>, HttpError> {
414         let mut buffer = buffer;
415         loop {
416             get_unparsed_or_return!(self.decode_ows(buffer)?, buffer);
417             get_unparsed_or_return!(self.decode_value(buffer)?, buffer);
418             get_unparsed_or_return!(self.decode_crlf(false, buffer)?, buffer);
419             detect_blank_and_return!(self.stage, buffer);
420             get_unparsed_or_return!(self.decode_key(buffer)?, buffer);
421         }
422     }
423 
decode_header_from_crlf<'a>( &mut self, buffer: &'a [u8], ) -> Result<Option<&'a [u8]>, HttpError>424     fn decode_header_from_crlf<'a>(
425         &mut self,
426         buffer: &'a [u8],
427     ) -> Result<Option<&'a [u8]>, HttpError> {
428         let mut buffer = buffer;
429         loop {
430             get_unparsed_or_return!(self.decode_crlf(false, buffer)?, buffer);
431             detect_blank_and_return!(self.stage, buffer);
432             get_unparsed_or_return!(self.decode_key(buffer)?, buffer);
433             get_unparsed_or_return!(self.decode_ows(buffer)?, buffer);
434             get_unparsed_or_return!(self.decode_value(buffer)?, buffer);
435         }
436     }
437 
decode_header_from_crlf_end<'a>( &mut self, buffer: &'a [u8], ) -> Result<Option<&'a [u8]>, HttpError>438     fn decode_header_from_crlf_end<'a>(
439         &mut self,
440         buffer: &'a [u8],
441     ) -> Result<Option<&'a [u8]>, HttpError> {
442         let mut buffer = buffer;
443         loop {
444             detect_blank_and_return!(self.stage, buffer);
445             get_unparsed_or_return!(self.decode_key(buffer)?, buffer);
446             get_unparsed_or_return!(self.decode_ows(buffer)?, buffer);
447             get_unparsed_or_return!(self.decode_value(buffer)?, buffer);
448             get_unparsed_or_return!(self.decode_crlf(false, buffer)?, buffer);
449         }
450     }
451 
decode_ows<'a>(&mut self, buffer: &'a [u8]) -> Result<Option<&'a [u8]>, HttpError>452     fn decode_ows<'a>(&mut self, buffer: &'a [u8]) -> Result<Option<&'a [u8]>, HttpError> {
453         self.stage = ParseStage::Header(HeaderStage::OwsBefore);
454         trim_ows(buffer)
455     }
456 
decode_key<'a>(&mut self, buffer: &'a [u8]) -> Result<Option<&'a [u8]>, HttpError>457     fn decode_key<'a>(&mut self, buffer: &'a [u8]) -> Result<Option<&'a [u8]>, HttpError> {
458         self.stage = ParseStage::Header(HeaderStage::Key);
459         match get_header_name(buffer)? {
460             TokenStatus::Complete((key, unparsed)) => {
461                 if !self.rest.is_empty() {
462                     self.rest.extend_from_slice(key);
463                     let key = take(&mut self.rest);
464                     self.head_key = key;
465                 } else {
466                     self.head_key = key.to_vec();
467                 }
468                 Ok(Some(unparsed))
469             }
470             TokenStatus::Partial(rest) => {
471                 self.rest.extend_from_slice(rest);
472                 Ok(None)
473             }
474         }
475     }
476 
477     // TODO: Try use `&[u8]` instead of `Vec<u8>`.
take_value(&mut self, value: &[u8]) -> Vec<u8>478     fn take_value(&mut self, value: &[u8]) -> Vec<u8> {
479         if !self.rest.is_empty() {
480             self.rest.extend_from_slice(value);
481             take(&mut self.rest)
482         } else {
483             value.to_vec()
484         }
485     }
486 
decode_value<'a>(&mut self, buffer: &'a [u8]) -> Result<Option<&'a [u8]>, HttpError>487     fn decode_value<'a>(&mut self, buffer: &'a [u8]) -> Result<Option<&'a [u8]>, HttpError> {
488         self.stage = ParseStage::Header(HeaderStage::Value);
489         match get_header_value(buffer)? {
490             TokenStatus::Complete((value, unparsed)) => {
491                 let complete_value = self.take_value(value);
492                 let header_value = if let Some(last_visible) = complete_value
493                     .iter()
494                     .rposition(|b| *b != b' ' && *b != b'\t')
495                 {
496                     complete_value[..last_visible + 1].to_vec()
497                 } else {
498                     // Return value even it is empty.
499                     Vec::new()
500                 };
501                 self.headers = header_insert(
502                     take(&mut self.head_key),
503                     header_value,
504                     self.headers.take().unwrap(),
505                 )?;
506                 Ok(Some(unparsed))
507             }
508             TokenStatus::Partial(rest) => {
509                 self.rest.extend_from_slice(rest);
510                 Ok(None)
511             }
512         }
513     }
514 
decode_crlf<'a>( &mut self, cr_meet: bool, buffer: &'a [u8], ) -> Result<Option<&'a [u8]>, HttpError>515     fn decode_crlf<'a>(
516         &mut self,
517         cr_meet: bool,
518         buffer: &'a [u8],
519     ) -> Result<Option<&'a [u8]>, HttpError> {
520         self.stage = ParseStage::Header(HeaderStage::Crlf);
521         match consume_crlf(buffer, cr_meet)? {
522             TokenStatus::Complete(unparsed) => {
523                 self.new_line = false;
524                 Ok(Some(unparsed))
525             }
526             TokenStatus::Partial(step) => {
527                 if step == 1 {
528                     self.new_line = true;
529                 }
530                 Ok(None)
531             }
532         }
533     }
534 }
535 
status_token(buffer: &[u8]) -> TokenResult536 fn status_token(buffer: &[u8]) -> TokenResult {
537     for (i, &b) in buffer.iter().enumerate() {
538         if b == b' ' {
539             return Ok(TokenStatus::Complete((&buffer[..i], &buffer[i + 1..])));
540         } else if !is_valid_byte(b) {
541             return Err(ErrorKind::H1(H1Error::InvalidResponse).into());
542         }
543     }
544     Ok(TokenStatus::Partial(buffer))
545 }
546 
decode_reason(buffer: &[u8]) -> Result<Option<&[u8]>, HttpError>547 fn decode_reason(buffer: &[u8]) -> Result<Option<&[u8]>, HttpError> {
548     for (i, b) in buffer.iter().enumerate() {
549         if *b == b'\r' || *b == b'\n' {
550             return Ok(Some(&buffer[i..]));
551         } else if !is_legal_reason_byte(*b) {
552             return Err(ErrorKind::H1(H1Error::InvalidResponse).into());
553         }
554     }
555     Ok(None)
556 }
557 
consume_crlf(buffer: &[u8], cr_meet: bool) -> Result<TokenStatus<&[u8], usize>, HttpError>558 fn consume_crlf(buffer: &[u8], cr_meet: bool) -> Result<TokenStatus<&[u8], usize>, HttpError> {
559     if buffer.is_empty() {
560         return Ok(TokenStatus::Partial(0));
561     }
562     match buffer[0] {
563         b'\r' => {
564             if cr_meet {
565                 Err(ErrorKind::H1(H1Error::InvalidResponse).into())
566             } else if buffer.len() == 1 {
567                 Ok(TokenStatus::Partial(1))
568             } else if buffer[1] == b'\n' {
569                 Ok(TokenStatus::Complete(&buffer[2..]))
570             } else {
571                 Err(ErrorKind::H1(H1Error::InvalidResponse).into())
572             }
573         }
574         b'\n' => Ok(TokenStatus::Complete(&buffer[1..])),
575         _ => Err(ErrorKind::H1(H1Error::InvalidResponse).into()),
576     }
577 }
578 
get_header_name(buffer: &[u8]) -> TokenResult579 fn get_header_name(buffer: &[u8]) -> TokenResult {
580     for (i, b) in buffer.iter().enumerate() {
581         if *b == b':' {
582             return Ok(TokenStatus::Complete((&buffer[..i], &buffer[i + 1..])));
583         } else if !HEADER_NAME_BYTES[*b as usize] {
584             return Err(ErrorKind::H1(H1Error::InvalidResponse).into());
585         }
586     }
587     Ok(TokenStatus::Partial(buffer))
588 }
589 
get_header_value(buffer: &[u8]) -> TokenResult590 fn get_header_value(buffer: &[u8]) -> TokenResult {
591     for (i, b) in buffer.iter().enumerate() {
592         if *b == b'\r' || *b == b'\n' {
593             return Ok(TokenStatus::Complete((&buffer[..i], &buffer[i..])));
594         } else if !HEADER_VALUE_BYTES[*b as usize] {
595             return Err(ErrorKind::H1(H1Error::InvalidResponse).into());
596         }
597     }
598     Ok(TokenStatus::Partial(buffer))
599 }
600 
trim_ows(buffer: &[u8]) -> Result<Option<&[u8]>, HttpError>601 fn trim_ows(buffer: &[u8]) -> Result<Option<&[u8]>, HttpError> {
602     for (i, &b) in buffer.iter().enumerate() {
603         match b {
604             b' ' | b'\t' => {}
605             _ => return Ok(Some(&buffer[i..])),
606         }
607     }
608     Ok(None)
609 }
610 
header_insert( header_name: Vec<u8>, header_value: Vec<u8>, mut headers: Headers, ) -> Result<Option<Headers>, HttpError>611 fn header_insert(
612     header_name: Vec<u8>,
613     header_value: Vec<u8>,
614     mut headers: Headers,
615 ) -> Result<Option<Headers>, HttpError> {
616     let name = unsafe { String::from_utf8_unchecked(header_name) };
617     let value = unsafe { String::from_utf8_unchecked(header_value) };
618     // TODO: Convert `HeaderName` to lowercase when decoding it.
619     let key = name.to_lowercase();
620     let header_name = key.as_str();
621     let header_value = value.as_str();
622     // If the response contains headers with the same name, add them to one
623     // `Headers`.
624     headers.append(header_name, header_value)?;
625     Ok(Some(headers))
626 }
627 
628 //  token = 1*tchar
629 //  tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" /
630 //  "-" / "." / "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
is_valid_byte(byte: u8) -> bool631 fn is_valid_byte(byte: u8) -> bool {
632     byte > 0x1F && byte < 0x7F
633 }
634 
635 // reason-phase = 1*(HTAB / SP / VCHAR / obs-text)
is_legal_reason_byte(byte: u8) -> bool636 fn is_legal_reason_byte(byte: u8) -> bool {
637     byte == 0x09 || byte == 0x20 || (0x21..=0x7E).contains(&byte) || (0x80..=0xFF).contains(&byte)
638 }
639 
640 // TODO: Add more test cases.
641 #[cfg(test)]
642 mod ut_decoder {
643     use super::{H1Error, ResponseDecoder};
644     use crate::error::{ErrorKind, HttpError};
645 
646     macro_rules! test_unit_complete {
647         ($res1:expr, $res2:expr, $res3:expr, $res4:expr, $res5:expr) => {{
648             let mut decoder = ResponseDecoder::new();
649             let result = decoder.decode($res1).unwrap().unwrap();
650             assert_eq!($res2, result.0.version.as_str());
651             assert_eq!($res3, result.0.status.as_u16());
652             assert_eq!($res4.len(), result.0.headers.len());
653             for (key, value) in $res4 {
654                 assert_eq!(
655                     value,
656                     result.0.headers.get(key).unwrap().to_string().unwrap()
657                 )
658             }
659             assert_eq!($res5, result.1);
660         }};
661     }
662 
663     macro_rules! test_unit_segment {
664         ($res1:expr, $res2:expr, $res3:expr, $res4:expr, $res5:expr) => {{
665             let mut decoder = ResponseDecoder::new();
666             let result = decoder.decode($res1.0).unwrap();
667             assert_eq!(true, result.is_none());
668             let result = decoder.decode($res1.1).unwrap().unwrap();
669             assert_eq!($res2, result.0.version.as_str());
670             assert_eq!($res3, result.0.status.as_u16());
671             assert_eq!($res4.len(), result.0.headers.len());
672             for (key, value) in $res4 {
673                 assert_eq!(
674                     value,
675                     result.0.headers.get(key).unwrap().to_string().unwrap()
676                 )
677             }
678             assert_eq!($res5, result.1);
679         }};
680     }
681 
682     macro_rules! test_unit_invalid {
683         ($res1:expr, $res2:expr) => {{
684             let mut decoder = ResponseDecoder::new();
685             let result = decoder.decode($res1);
686             assert_eq!($res2, result.err());
687         }};
688     }
689 
690     /// UT test cases for `ResponseDecoder::decode`.
691     ///
692     /// # Brief
693     /// 1. Creates a `ResponseDecoder` by calling `ResponseDecoder::new`.
694     /// 2. Decodes response bytes by calling `ResponseDecoder::decode`
695     /// 3. Checks if the test result is correct.
696     #[test]
ut_response_decoder_decode_0()697     fn ut_response_decoder_decode_0() {
698         // Decode a complete response separated by CRLF.
699         test_unit_complete!(
700             "HTTP/1.1 304 OK\r\nAge:270646\r\nDate:Mon, 19 Dec 2022 01:46:59 GMT\r\nEtag:\"3147526947+gzip\"\r\n\r\nbody part".as_bytes(),
701             "HTTP/1.1",
702             304_u16,
703             [("age", "270646"), ("date", "Mon, 19 Dec 2022 01:46:59 GMT"), ("etag", r#""3147526947+gzip""#)],
704             r#"body part"#.as_bytes()
705         );
706         // Decode a complete response separated by LF.
707         test_unit_complete!(
708             "HTTP/1.1 304 OK\nAge:270646\nDate:Mon, 19 Dec 2022 01:46:59 GMT\nEtag:\"3147526947+gzip\"\n\nbody part".as_bytes(),
709             "HTTP/1.1",
710             304_u16,
711             [("age", "270646"), ("date", "Mon, 19 Dec 2022 01:46:59 GMT"), ("etag", r#""3147526947+gzip""#)],
712             r#"body part"#.as_bytes()
713         );
714         // Decode a response without reason-phrase.
715         test_unit_complete!(
716             "HTTP/1.1 304 \r\nAge:270646\r\nDate:Mon, 19 Dec 2022 01:46:59 GMT\r\nEtag:\"3147526947+gzip\"\r\n\r\nbody part".as_bytes(),
717             "HTTP/1.1",
718             304_u16,
719             [("age", "270646"), ("date", "Mon, 19 Dec 2022 01:46:59 GMT"), ("etag", r#""3147526947+gzip""#)],
720             r#"body part"#.as_bytes()
721         );
722 
723         // Decode a response that contains the OWS.
724         test_unit_complete!(
725             "HTTP/1.1 304 \r\nAge: \t 270646 \t \t\r\nDate: \t Mon, 19 Dec 2022 01:46:59 GMT \t \t\r\nEtag:\t \"3147526947+gzip\" \t \t\r\n\r\nbody part".as_bytes(),
726             "HTTP/1.1",
727             304_u16,
728             [("age", "270646"), ("date", "Mon, 19 Dec 2022 01:46:59 GMT"), ("etag", r#""3147526947+gzip""#)],
729             r#"body part"#.as_bytes()
730         );
731         // Decode a response without a message-body
732         test_unit_complete!(
733             "HTTP/1.1 304 \r\nAge: \t 270646 \t \t\r\nDate: \t Mon, 19 Dec 2022 01:46:59 GMT \t \t\r\nEtag:\t \"3147526947+gzip\" \t \t\r\n\r\n".as_bytes(),
734             "HTTP/1.1",
735             304_u16,
736             [("age", "270646"), ("date", "Mon, 19 Dec 2022 01:46:59 GMT"), ("etag", r#""3147526947+gzip""#)],
737             r#""#.as_bytes()
738         );
739         // Decode has multiple set-cookie responses.
740         test_unit_complete!(
741             "HTTP/1.1 304 \r\nSet-Cookie: \t template=; Path=/; Domain=example.com; Expires=Mon, 19 Dec 2022 12:58:54 UTC \t \t\r\n\
742         Set-Cookie: \t ezov=06331; Path=/; Domain=example.com; Expires=Mon, 19 Dec 2022 12:58:54 UTC \t \t\r\n\r\n".as_bytes(),
743             "HTTP/1.1",
744             304_u16,
745            [("set-cookie", "template=; Path=/; Domain=example.com; Expires=Mon, 19 Dec 2022 12:58:54 UTC, ezov=06331; Path=/; Domain=example.com; Expires=Mon, 19 Dec 2022 12:58:54 UTC")],
746             r#""#.as_bytes()
747         );
748         // Decode a response without a header.
749         test_unit_complete!(
750             "HTTP/1.1 304 \r\n\r\n".as_bytes(),
751             "HTTP/1.1",
752             304_u16,
753             [] as [(&str, &str); 0],
754             r#""#.as_bytes()
755         );
756         // Decode a response without a header and separated by LF.
757         test_unit_complete!(
758             "HTTP/1.1 304 \n\n".as_bytes(),
759             "HTTP/1.1",
760             304_u16,
761             [] as [(&str, &str); 0],
762             r#""#.as_bytes()
763         );
764         // Decode a response with a header and an empty value.
765         test_unit_complete!(
766             "HTTP/1.1 304 \r\nempty_header: \r\n\r\n".as_bytes(),
767             "HTTP/1.1",
768             304_u16,
769             [("empty_header", "")],
770             r#""#.as_bytes()
771         );
772         // Decode a response with a header and an empty value.
773         test_unit_complete!(
774             "HTTP/1.0 304 \r\nempty_header: \r\n\r\n".as_bytes(),
775             "HTTP/1.0",
776             304_u16,
777             [("empty_header", "")],
778             r#""#.as_bytes()
779         );
780     }
781 
782     /// UT test cases for `ResponseDecoder::decode`.
783     ///
784     /// # Brief
785     /// Decode a segmented transmission response and test `ParseStage` parsing
786     /// rules.
787     /// 1. Creates a `ResponseDecoder` by calling `ResponseDecoder::new`.
788     /// 2. Decodes response bytes by calling `ResponseDecoder::decode`
789     /// 3. Checks if the test result is correct.
790     #[test]
ut_response_decoder_decode_1()791     fn ut_response_decoder_decode_1() {
792         test_unit_segment!(
793             ("HT".as_bytes(), "TP/1.1 304 OK\r\nAge: \t 270646 \t \t\r\nDate: \t Mon, 19 Dec 2022 01:46:59 GMT \t \t\r\nEtag:\t \"3147526947+gzip\" \t \t\r\n\r\nbody part".as_bytes()),
794             "HTTP/1.1",
795             304_u16,
796             [("age", "270646"), ("date", "Mon, 19 Dec 2022 01:46:59 GMT"), ("etag", r#""3147526947+gzip""#)],
797             r#"body part"#.as_bytes()
798         );
799         test_unit_segment!(
800             ("HTTP/1.1 3".as_bytes(), "04 OK\r\nAge: \t 270646 \t \t\r\nDate: \t Mon, 19 Dec 2022 01:46:59 GMT \t \t\r\nEtag:\t \"3147526947+gzip\" \t \t\r\n\r\nbody part".as_bytes()),
801             "HTTP/1.1",
802             304_u16,
803             [("age", "270646"), ("date", "Mon, 19 Dec 2022 01:46:59 GMT"), ("etag", r#""3147526947+gzip""#)],
804             r#"body part"#.as_bytes()
805         );
806         test_unit_segment!(
807             ("HTTP/1.1 304 O".as_bytes(), "K\r\nAge: \t 270646 \t \t\r\nDate: \t Mon, 19 Dec 2022 01:46:59 GMT \t \t\r\nEtag:\t \"3147526947+gzip\" \t \t\r\n\r\nbody part".as_bytes()),
808             "HTTP/1.1",
809             304_u16,
810             [("age", "270646"), ("date", "Mon, 19 Dec 2022 01:46:59 GMT"), ("etag", r#""3147526947+gzip""#)],
811             r#"body part"#.as_bytes()
812         );
813         test_unit_segment!(
814             ("HTTP/1.1 304 OK\r".as_bytes(), "\nAge: \t 270646 \t \t\r\nDate: \t Mon, 19 Dec 2022 01:46:59 GMT \t \t\r\nEtag:\t \"3147526947+gzip\" \t \t\r\n\r\nbody part".as_bytes()),
815             "HTTP/1.1",
816             304_u16,
817             [("age", "270646"), ("date", "Mon, 19 Dec 2022 01:46:59 GMT"), ("etag", r#""3147526947+gzip""#)],
818             r#"body part"#.as_bytes()
819         );
820         test_unit_segment!(
821             ("HTTP/1.1 304 OK\r\nA".as_bytes(), "ge: \t 270646 \t \t\r\nDate: \t Mon, 19 Dec 2022 01:46:59 GMT \t \t\r\nEtag:\t \"3147526947+gzip\" \t \t\r\n\r\nbody part".as_bytes()),
822             "HTTP/1.1",
823             304_u16,
824             [("age", "270646"), ("date", "Mon, 19 Dec 2022 01:46:59 GMT"), ("etag", r#""3147526947+gzip""#)],
825             r#"body part"#.as_bytes()
826         );
827         test_unit_segment!(
828             ("HTTP/1.1 304 OK\r\nAge: ".as_bytes(), "\t 270646 \t \t\r\nDate: \t Mon, 19 Dec 2022 01:46:59 GMT \t \t\r\nEtag:\t \"3147526947+gzip\" \t \t\r\n\r\nbody part".as_bytes()),
829             "HTTP/1.1",
830             304_u16,
831             [("age", "270646"), ("date", "Mon, 19 Dec 2022 01:46:59 GMT"), ("etag", r#""3147526947+gzip""#)],
832             r#"body part"#.as_bytes()
833         );
834         test_unit_segment!(
835             ("HTTP/1.1 304 OK\r\nAge: \t 270".as_bytes(), "646 \t \t\r\nDate: \t Mon, 19 Dec 2022 01:46:59 GMT \t \t\r\nEtag:\t \"3147526947+gzip\" \t \t\r\n\r\nbody part".as_bytes()),
836             "HTTP/1.1",
837             304_u16,
838             [("age", "270646"), ("date", "Mon, 19 Dec 2022 01:46:59 GMT"), ("etag", r#""3147526947+gzip""#)],
839             r#"body part"#.as_bytes()
840         );
841         test_unit_segment!(
842             ("HTTP/1.1 304 OK\r\nAge: \t 270646 \t".as_bytes(), " \t\r\nDate: \t Mon, 19 Dec 2022 01:46:59 GMT \t \t\r\nEtag:\t \"3147526947+gzip\" \t \t\r\n\r\nbody part".as_bytes()),
843             "HTTP/1.1",
844             304_u16,
845             [("age", "270646"), ("date", "Mon, 19 Dec 2022 01:46:59 GMT"), ("etag", r#""3147526947+gzip""#)],
846             r#"body part"#.as_bytes()
847         );
848         test_unit_segment!(
849             ("HTTP/1.1 304 OK\r\nAge: \t 270646 \t \t\r".as_bytes(), "\nDate: \t Mon, 19 Dec 2022 01:46:59 GMT \t \t\r\nEtag:\t \"3147526947+gzip\" \t \t\r\n\r\nbody part".as_bytes()),
850             "HTTP/1.1",
851             304_u16,
852             [("age", "270646"), ("date", "Mon, 19 Dec 2022 01:46:59 GMT"), ("etag", r#""3147526947+gzip""#)],
853             r#"body part"#.as_bytes()
854         );
855         test_unit_segment!(
856             ("HTTP/1.1 304 OK\r\nAge: \t 270646 \t \t\r\n".as_bytes(), "Date: \t Mon, 19 Dec 2022 01:46:59 GMT \t \t\r\nEtag:\t \"3147526947+gzip\" \t \t\r\n\r\nbody part".as_bytes()),
857             "HTTP/1.1",
858             304_u16,
859             [("age", "270646"), ("date", "Mon, 19 Dec 2022 01:46:59 GMT"), ("etag", r#""3147526947+gzip""#)],
860             r#"body part"#.as_bytes()
861         );
862         test_unit_segment!(
863             ("HTTP/1.1 304 OK\r\nAge: \t 270646 \t \t\r\nDa".as_bytes(), "te: \t Mon, 19 Dec 2022 01:46:59 GMT \t \t\r\nEtag:\t \"3147526947+gzip\" \t \t\r\n\r\nbody part".as_bytes()),
864             "HTTP/1.1",
865             304_u16,
866             [("age", "270646"), ("date", "Mon, 19 Dec 2022 01:46:59 GMT"), ("etag", r#""3147526947+gzip""#)],
867             r#"body part"#.as_bytes()
868         );
869         test_unit_segment!(
870             ("HTTP/1.1 304 OK\r\nAge: \t 270646 \t \t\r\nDate: \t Mon, 19 Dec 2022 01:46:59 GMT \t \t\r\nEtag:\t \"3147526947+gzip\" \t \t\r\n".as_bytes(), "\r\nbody part".as_bytes()),
871             "HTTP/1.1",
872             304_u16,
873             [("age", "270646"), ("date", "Mon, 19 Dec 2022 01:46:59 GMT"), ("etag", r#""3147526947+gzip""#)],
874             r#"body part"#.as_bytes()
875         );
876         test_unit_segment!(
877             ("HTTP/1.1 304 OK\r\nAge: \t 270646 \t \t\r\nDate: \t Mon, 19 Dec 2022 01:46:59 GMT \t \t\r\nEtag:\t \"3147526947+gzip\" \t \t\r\n\r".as_bytes(), "\nbody part".as_bytes()),
878             "HTTP/1.1",
879             304_u16,
880             [("age", "270646"), ("date", "Mon, 19 Dec 2022 01:46:59 GMT"), ("etag", r#""3147526947+gzip""#)],
881             r#"body part"#.as_bytes()
882         );
883         test_unit_segment!(
884             ("HTTP/1.1 304 OK\r\n".as_bytes(), "\r\nbody part".as_bytes()),
885             "HTTP/1.1",
886             304_u16,
887             [] as [(&str, &str); 0],
888             r#"body part"#.as_bytes()
889         );
890         test_unit_segment!(
891             ("HTTP/1.1 304 OK\r\n".as_bytes(), "\nbody part".as_bytes()),
892             "HTTP/1.1",
893             304_u16,
894             [] as [(&str, &str); 0],
895             r#"body part"#.as_bytes()
896         );
897     }
898 
899     /// UT test cases for `ResponseDecoder::decode`.
900     ///
901     /// # Brief
902     /// Decode an incorrect response bytes.
903     /// 1. Creates a `ResponseDecoder` by calling `ResponseDecoder::new`.
904     /// 2. Decodes response bytes by calling `ResponseDecoder::decode`
905     /// 3. Checks if the test result is correct.
906     #[test]
ut_response_decoder_decode_2()907     fn ut_response_decoder_decode_2() {
908         test_unit_invalid!("HTTP/1.2 304 OK\r\nAge:270646\r\nDate:Mon, 19 Dec 2022 01:46:59 GMT\r\nEtag:\"3147526947+gzip\"\r\n\r\nbody part".as_bytes(), Some(HttpError::from(ErrorKind::H1(H1Error::InvalidResponse))));
909         test_unit_invalid!("HTTP/1.1 3040 OK\r\nAge:270646\r\nDate:Mon, 19 Dec 2022 01:46:59 GMT\r\nEtag:\"3147526947+gzip\"\r\n\r\nbody part".as_bytes(), Some(HttpError::from(ErrorKind::H1(H1Error::InvalidResponse))));
910         test_unit_invalid!("HTTP/1.1 3 4 OK\r\nAge:270646\r\nDate:Mon, 19 Dec 2022 01:46:59 GMT\r\nEtag:\"3147526947+gzip\"\r\n\r\nbody part".as_bytes(), Some(HttpError::from(ErrorKind::H1(H1Error::InvalidResponse))));
911         test_unit_invalid!("HTTP/1.1 304 \0K\r\nAge:270646\r\nDate:Mon, 19 Dec 2022 01:46:59 GMT\r\nEtag:\"3147526947+gzip\"\r\n\r\nbody part".as_bytes(), Some(HttpError::from(ErrorKind::H1(H1Error::InvalidResponse))));
912         test_unit_invalid!("HTTP/1.1 304 OK\r\r\nAge:270646\r\nDate:Mon, 19 Dec 2022 01:46:59 GMT\r\nEtag:\"3147526947+gzip\"\r\n\r\nbody part".as_bytes(), Some(HttpError::from(ErrorKind::H1(H1Error::InvalidResponse))));
913         test_unit_invalid!("HTTP/1.1 304 OK\r\nA;ge:270646\r\nDate:Mon, 19 Dec 2022 01:46:59 GMT\r\nEtag:\"3147526947+gzip\"\r\n\r\nbody part".as_bytes(), Some(HttpError::from(ErrorKind::H1(H1Error::InvalidResponse))));
914         test_unit_invalid!("HTTP/1.1 304 OK\r\nA;ge:270646\r\nDate:Mon, 19 Dec 2022 01:46:59 GMT\r\nEtag:\"3147526947+gzip\"\r\n\r\nbody part".as_bytes(), Some(HttpError::from(ErrorKind::H1(H1Error::InvalidResponse))));
915         test_unit_invalid!("HTTP/1.1 304 OK\r\nAge:270\r646\r\nDate:Mon, 19 Dec 2022 01:46:59 GMT\r\nEtag:\"3147526947+gzip\"\r\n\r\nbody part".as_bytes(), Some(HttpError::from(ErrorKind::H1(H1Error::InvalidResponse))));
916         test_unit_invalid!("HTTP/1.1 304 OK\r\nAge:270\r646\r\nDate:Mon, 19 Dec 2022 01:46:59 GMT\r\nEtag:\"3147526947+gzip\"\r\n\r\nbody part".as_bytes(), Some(HttpError::from(ErrorKind::H1(H1Error::InvalidResponse))));
917         test_unit_invalid!("HTTP/1.1 304 OK\r\nAge:270646\r\r\nDate:Mon, 19 Dec 2022 01:46:59 GMT\r\nEtag:\"3147526947+gzip\"\r\n\r\nbody part".as_bytes(), Some(HttpError::from(ErrorKind::H1(H1Error::InvalidResponse))));
918         test_unit_invalid!("HTTP/1.1 304 OK\r\nAge:270646\r\n\rDate:Mon, 19 Dec 2022 01:46:59 GMT\r\nEtag:\"3147526947+gzip\"\r\n\r\nbody part".as_bytes(), Some(HttpError::from(ErrorKind::H1(H1Error::InvalidResponse))));
919         test_unit_invalid!("HTTP/1.1 304 OK\r\nAge:270646\r\n\rDate:Mon, 19 Dec 2022 01:46:59 GMT\r\nEtag:\"3147526947+gzip\"\r\n\r\r\nbody part".as_bytes(), Some(HttpError::from(ErrorKind::H1(H1Error::InvalidResponse))));
920     }
921 }
922