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