1use std::{io, marker::PhantomData, mem::MaybeUninit, task::Poll};
2
3use actix_codec::Decoder;
4use bytes::{Bytes, BytesMut};
5use http::{
6 header::{self, HeaderName, HeaderValue},
7 Method, StatusCode, Uri, Version,
8};
9use tracing::{debug, error, trace};
10
11use super::chunked::ChunkedState;
12use crate::{error::ParseError, header::HeaderMap, ConnectionType, Request, ResponseHead};
13
14pub(crate) const MAX_BUFFER_SIZE: usize = 131_072;
15const MAX_HEADERS: usize = 96;
16
17pub(crate) struct MessageDecoder<T: MessageType>(PhantomData<T>);
19
20#[derive(Debug)]
21pub(crate) enum PayloadType {
23 None,
24 Payload(PayloadDecoder),
25 Stream(PayloadDecoder),
26}
27
28impl<T: MessageType> Default for MessageDecoder<T> {
29 fn default() -> Self {
30 MessageDecoder(PhantomData)
31 }
32}
33
34impl<T: MessageType> Decoder for MessageDecoder<T> {
35 type Item = (T, PayloadType);
36 type Error = ParseError;
37
38 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
39 T::decode(src)
40 }
41}
42
43pub(crate) enum PayloadLength {
44 Payload(PayloadType),
45 UpgradeWebSocket,
46 None,
47}
48
49impl PayloadLength {
50 fn is_none(&self) -> bool {
52 matches!(self, Self::None)
53 }
54
55 fn is_zero(&self) -> bool {
57 matches!(
58 self,
59 PayloadLength::Payload(PayloadType::Payload(PayloadDecoder {
60 kind: Kind::Length(0)
61 }))
62 )
63 }
64}
65
66pub(crate) trait MessageType: Sized {
67 fn set_connection_type(&mut self, conn_type: Option<ConnectionType>);
68
69 fn set_expect(&mut self);
70
71 fn headers_mut(&mut self) -> &mut HeaderMap;
72
73 fn decode(src: &mut BytesMut) -> Result<Option<(Self, PayloadType)>, ParseError>;
74
75 fn set_headers(
76 &mut self,
77 slice: &Bytes,
78 raw_headers: &[HeaderIndex],
79 version: Version,
80 ) -> Result<PayloadLength, ParseError> {
81 let mut ka = None;
82 let mut has_upgrade_websocket = false;
83 let mut expect = false;
84 let mut chunked = false;
85 let mut seen_te = false;
86 let mut content_length = None;
87
88 {
89 let headers = self.headers_mut();
90
91 for idx in raw_headers.iter() {
92 let name = HeaderName::from_bytes(&slice[idx.name.0..idx.name.1]).unwrap();
93
94 let value = unsafe {
97 HeaderValue::from_maybe_shared_unchecked(slice.slice(idx.value.0..idx.value.1))
98 };
99
100 match name {
101 header::CONTENT_LENGTH if content_length.is_some() => {
102 debug!("multiple Content-Length");
103 return Err(ParseError::Header);
104 }
105
106 header::CONTENT_LENGTH => match value.to_str().map(str::trim) {
107 Ok(val) if val.starts_with('+') => {
108 debug!("illegal Content-Length: {:?}", val);
109 return Err(ParseError::Header);
110 }
111
112 Ok(val) => {
113 if let Ok(len) = val.parse::<u64>() {
114 content_length = Some(len);
117 } else {
118 debug!("illegal Content-Length: {:?}", val);
119 return Err(ParseError::Header);
120 }
121 }
122
123 Err(_) => {
124 debug!("illegal Content-Length: {:?}", value);
125 return Err(ParseError::Header);
126 }
127 },
128
129 header::TRANSFER_ENCODING if seen_te => {
131 debug!("multiple Transfer-Encoding not allowed");
132 return Err(ParseError::Header);
133 }
134
135 header::TRANSFER_ENCODING if version == Version::HTTP_11 => {
136 seen_te = true;
137
138 if let Ok(val) = value.to_str().map(str::trim) {
139 if val.eq_ignore_ascii_case("chunked") {
140 chunked = true;
141 } else if val.eq_ignore_ascii_case("identity") {
142 } else {
144 debug!("illegal Transfer-Encoding: {:?}", val);
145 return Err(ParseError::Header);
146 }
147 } else {
148 return Err(ParseError::Header);
149 }
150 }
151
152 header::CONNECTION => {
154 ka = if let Ok(conn) = value.to_str().map(str::trim) {
155 if conn.eq_ignore_ascii_case("keep-alive") {
156 Some(ConnectionType::KeepAlive)
157 } else if conn.eq_ignore_ascii_case("close") {
158 Some(ConnectionType::Close)
159 } else if conn.eq_ignore_ascii_case("upgrade") {
160 Some(ConnectionType::Upgrade)
161 } else {
162 None
163 }
164 } else {
165 None
166 };
167 }
168
169 header::UPGRADE => {
170 if let Ok(val) = value.to_str().map(str::trim) {
171 if val.eq_ignore_ascii_case("websocket") {
172 has_upgrade_websocket = true;
173 }
174 }
175 }
176
177 header::EXPECT => {
178 let bytes = value.as_bytes();
179 if bytes.len() >= 4 && &bytes[0..4] == b"100-" {
180 expect = true;
181 }
182 }
183
184 _ => {}
185 }
186
187 headers.append(name, value);
188 }
189 }
190
191 self.set_connection_type(ka);
192
193 if expect {
194 self.set_expect()
195 }
196
197 if chunked {
199 Ok(PayloadLength::Payload(PayloadType::Payload(
201 PayloadDecoder::chunked(),
202 )))
203 } else if has_upgrade_websocket {
204 Ok(PayloadLength::UpgradeWebSocket)
205 } else if let Some(len) = content_length {
206 Ok(PayloadLength::Payload(PayloadType::Payload(
208 PayloadDecoder::length(len),
209 )))
210 } else {
211 Ok(PayloadLength::None)
212 }
213 }
214}
215
216impl MessageType for Request {
217 fn set_connection_type(&mut self, conn_type: Option<ConnectionType>) {
218 if let Some(ctype) = conn_type {
219 self.head_mut().set_connection_type(ctype);
220 }
221 }
222
223 fn set_expect(&mut self) {
224 self.head_mut().set_expect();
225 }
226
227 fn headers_mut(&mut self) -> &mut HeaderMap {
228 &mut self.head_mut().headers
229 }
230
231 fn decode(src: &mut BytesMut) -> Result<Option<(Self, PayloadType)>, ParseError> {
232 let mut headers: [HeaderIndex; MAX_HEADERS] = EMPTY_HEADER_INDEX_ARRAY;
233
234 let (len, method, uri, ver, h_len) = {
235 let mut parsed = unsafe {
240 MaybeUninit::<[MaybeUninit<httparse::Header<'_>>; MAX_HEADERS]>::uninit()
241 .assume_init()
242 };
243
244 let mut req = httparse::Request::new(&mut []);
245
246 match req.parse_with_uninit_headers(src, &mut parsed)? {
247 httparse::Status::Complete(len) => {
248 let method = Method::from_bytes(req.method.unwrap().as_bytes())
249 .map_err(|_| ParseError::Method)?;
250 let uri = Uri::try_from(req.path.unwrap())?;
251 let version = if req.version.unwrap() == 1 {
252 Version::HTTP_11
253 } else {
254 Version::HTTP_10
255 };
256 HeaderIndex::record(src, req.headers, &mut headers);
257
258 (len, method, uri, version, req.headers.len())
259 }
260
261 httparse::Status::Partial => {
262 return if src.len() >= MAX_BUFFER_SIZE {
263 trace!("MAX_BUFFER_SIZE unprocessed data reached, closing");
264 Err(ParseError::TooLarge)
265 } else {
266 Ok(None)
268 };
269 }
270 }
271 };
272
273 let mut msg = Request::new();
274
275 let mut length = msg.set_headers(&src.split_to(len).freeze(), &headers[..h_len], ver)?;
277
278 if msg.head().headers.contains_key(header::TRANSFER_ENCODING) {
279 if ver == Version::HTTP_10 {
280 debug!("Transfer-Encoding is not allowed in HTTP/1.0 requests");
281 return Err(ParseError::Header);
282 }
283
284 if !crate::HttpMessage::chunked(&msg)? {
285 debug!("request Transfer-Encoding must be chunked");
286 return Err(ParseError::Header);
287 }
288
289 if msg.head().headers.contains_key(header::CONTENT_LENGTH) {
290 debug!("both Content-Length and Transfer-Encoding are set");
291 return Err(ParseError::Header);
292 }
293 }
294
295 if ver == Version::HTTP_10 && method == Method::POST && length.is_none() {
298 debug!("no Content-Length specified for HTTP/1.0 POST request");
299 return Err(ParseError::Header);
300 }
301
302 if length.is_zero() {
306 length = PayloadLength::None;
307 }
308
309 let decoder = match length {
311 PayloadLength::Payload(pl) => pl,
312 PayloadLength::UpgradeWebSocket => {
313 PayloadType::Stream(PayloadDecoder::eof())
315 }
316 PayloadLength::None => {
317 if method == Method::CONNECT {
318 PayloadType::Stream(PayloadDecoder::eof())
319 } else {
320 PayloadType::None
321 }
322 }
323 };
324
325 let head = msg.head_mut();
326 head.uri = uri;
327 head.method = method;
328 head.version = ver;
329
330 Ok(Some((msg, decoder)))
331 }
332}
333
334impl MessageType for ResponseHead {
335 fn set_connection_type(&mut self, conn_type: Option<ConnectionType>) {
336 if let Some(ctype) = conn_type {
337 ResponseHead::set_connection_type(self, ctype);
338 }
339 }
340
341 fn set_expect(&mut self) {}
342
343 fn headers_mut(&mut self) -> &mut HeaderMap {
344 &mut self.headers
345 }
346
347 fn decode(src: &mut BytesMut) -> Result<Option<(Self, PayloadType)>, ParseError> {
348 let mut headers: [HeaderIndex; MAX_HEADERS] = EMPTY_HEADER_INDEX_ARRAY;
349
350 let (len, ver, status, h_len) = {
351 let mut parsed = unsafe {
356 MaybeUninit::<[MaybeUninit<httparse::Header<'_>>; MAX_HEADERS]>::uninit()
357 .assume_init()
358 };
359
360 let mut res = httparse::Response::new(&mut []);
361
362 let mut config = httparse::ParserConfig::default();
363 config.allow_spaces_after_header_name_in_responses(true);
364
365 match config.parse_response_with_uninit_headers(&mut res, src, &mut parsed)? {
366 httparse::Status::Complete(len) => {
367 let version = if res.version.unwrap() == 1 {
368 Version::HTTP_11
369 } else {
370 Version::HTTP_10
371 };
372
373 let status =
374 StatusCode::from_u16(res.code.unwrap()).map_err(|_| ParseError::Status)?;
375 HeaderIndex::record(src, res.headers, &mut headers);
376
377 (len, version, status, res.headers.len())
378 }
379
380 httparse::Status::Partial => {
381 return if src.len() >= MAX_BUFFER_SIZE {
382 error!("MAX_BUFFER_SIZE unprocessed data reached, closing");
383 Err(ParseError::TooLarge)
384 } else {
385 Ok(None)
386 }
387 }
388 }
389 };
390
391 let mut msg = ResponseHead::new(status);
392 msg.version = ver;
393
394 let mut length = msg.set_headers(&src.split_to(len).freeze(), &headers[..h_len], ver)?;
396
397 if length.is_zero() {
401 length = PayloadLength::None;
402 }
403
404 let decoder = if let PayloadLength::Payload(pl) = length {
406 pl
407 } else if status == StatusCode::SWITCHING_PROTOCOLS {
408 PayloadType::Stream(PayloadDecoder::eof())
410 } else {
411 if msg.version == Version::HTTP_10 {
413 msg.set_connection_type(ConnectionType::Close);
414 PayloadType::Payload(PayloadDecoder::eof())
415 } else {
416 PayloadType::None
417 }
418 };
419
420 Ok(Some((msg, decoder)))
421 }
422}
423
424#[derive(Clone, Copy)]
425pub(crate) struct HeaderIndex {
426 pub(crate) name: (usize, usize),
427 pub(crate) value: (usize, usize),
428}
429
430pub(crate) const EMPTY_HEADER_INDEX: HeaderIndex = HeaderIndex {
431 name: (0, 0),
432 value: (0, 0),
433};
434
435pub(crate) const EMPTY_HEADER_INDEX_ARRAY: [HeaderIndex; MAX_HEADERS] =
436 [EMPTY_HEADER_INDEX; MAX_HEADERS];
437
438impl HeaderIndex {
439 pub(crate) fn record(
440 bytes: &[u8],
441 headers: &[httparse::Header<'_>],
442 indices: &mut [HeaderIndex],
443 ) {
444 let bytes_ptr = bytes.as_ptr() as usize;
445 for (header, indices) in headers.iter().zip(indices.iter_mut()) {
446 let name_start = header.name.as_ptr() as usize - bytes_ptr;
447 let name_end = name_start + header.name.len();
448 indices.name = (name_start, name_end);
449 let value_start = header.value.as_ptr() as usize - bytes_ptr;
450 let value_end = value_start + header.value.len();
451 indices.value = (value_start, value_end);
452 }
453 }
454}
455
456#[derive(Debug, Clone, PartialEq, Eq)]
457pub enum PayloadItem {
459 Chunk(Bytes),
460 Eof,
461}
462
463#[derive(Debug, Clone, PartialEq, Eq)]
467pub struct PayloadDecoder {
468 kind: Kind,
469}
470
471impl PayloadDecoder {
472 pub fn length(x: u64) -> PayloadDecoder {
474 PayloadDecoder {
475 kind: Kind::Length(x),
476 }
477 }
478
479 pub fn chunked() -> PayloadDecoder {
481 PayloadDecoder {
482 kind: Kind::Chunked(ChunkedState::Size, 0),
483 }
484 }
485
486 pub fn eof() -> PayloadDecoder {
488 PayloadDecoder { kind: Kind::Eof }
489 }
490}
491
492#[derive(Debug, Clone, PartialEq, Eq)]
493enum Kind {
494 Length(u64),
496
497 Chunked(ChunkedState, u64),
499
500 Eof,
515}
516
517impl Decoder for PayloadDecoder {
518 type Item = PayloadItem;
519 type Error = io::Error;
520
521 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
522 match self.kind {
523 Kind::Length(ref mut remaining) => {
524 if *remaining == 0 {
525 Ok(Some(PayloadItem::Eof))
526 } else {
527 if src.is_empty() {
528 return Ok(None);
529 }
530 let len = src.len() as u64;
531 let buf;
532 if *remaining > len {
533 buf = src.split().freeze();
534 *remaining -= len;
535 } else {
536 buf = src.split_to(*remaining as usize).freeze();
537 *remaining = 0;
538 };
539 trace!("Length read: {}", buf.len());
540 Ok(Some(PayloadItem::Chunk(buf)))
541 }
542 }
543
544 Kind::Chunked(ref mut state, ref mut size) => {
545 loop {
546 let mut buf = None;
547
548 *state = match state.step(src, size, &mut buf) {
550 Poll::Pending => return Ok(None),
551 Poll::Ready(Ok(state)) => state,
552 Poll::Ready(Err(err)) => return Err(err),
553 };
554
555 if *state == ChunkedState::End {
556 trace!("End of chunked stream");
557 return Ok(Some(PayloadItem::Eof));
558 }
559
560 if let Some(buf) = buf {
561 return Ok(Some(PayloadItem::Chunk(buf)));
562 }
563
564 if src.is_empty() {
565 return Ok(None);
566 }
567 }
568 }
569
570 Kind::Eof => {
571 if src.is_empty() {
572 Ok(None)
573 } else {
574 Ok(Some(PayloadItem::Chunk(src.split().freeze())))
575 }
576 }
577 }
578 }
579}
580
581#[cfg(test)]
582mod tests {
583 use super::*;
584 use crate::{header::SET_COOKIE, HttpMessage as _};
585
586 impl PayloadType {
587 pub(crate) fn unwrap(self) -> PayloadDecoder {
588 match self {
589 PayloadType::Payload(pl) => pl,
590 _ => panic!(),
591 }
592 }
593
594 pub(crate) fn is_unhandled(&self) -> bool {
595 matches!(self, PayloadType::Stream(_))
596 }
597 }
598
599 impl PayloadItem {
600 pub(crate) fn chunk(self) -> Bytes {
601 match self {
602 PayloadItem::Chunk(chunk) => chunk,
603 _ => panic!("error"),
604 }
605 }
606
607 pub(crate) fn eof(&self) -> bool {
608 matches!(*self, PayloadItem::Eof)
609 }
610 }
611
612 macro_rules! parse_ready {
613 ($e:expr) => {{
614 match MessageDecoder::<Request>::default().decode($e) {
615 Ok(Some((msg, _))) => msg,
616 Ok(_) => unreachable!("Eof during parsing http request"),
617 Err(err) => unreachable!("Error during parsing http request: {:?}", err),
618 }
619 }};
620 }
621
622 macro_rules! expect_parse_err {
623 ($e:expr) => {{
624 match MessageDecoder::<Request>::default().decode($e) {
625 Err(err) => match err {
626 ParseError::Io(_) => unreachable!("Parse error expected"),
627 _ => {}
628 },
629 _ => unreachable!("Error expected"),
630 }
631 }};
632 }
633
634 #[test]
635 fn test_parse() {
636 let mut buf = BytesMut::from("GET /test HTTP/1.1\r\n\r\n");
637
638 let mut reader = MessageDecoder::<Request>::default();
639 match reader.decode(&mut buf) {
640 Ok(Some((req, _))) => {
641 assert_eq!(req.version(), Version::HTTP_11);
642 assert_eq!(*req.method(), Method::GET);
643 assert_eq!(req.path(), "/test");
644 }
645 Ok(_) | Err(_) => unreachable!("Error during parsing http request"),
646 }
647 }
648
649 #[test]
650 fn test_parse_partial() {
651 let mut buf = BytesMut::from("PUT /test HTTP/1");
652
653 let mut reader = MessageDecoder::<Request>::default();
654 assert!(reader.decode(&mut buf).unwrap().is_none());
655
656 buf.extend(b".1\r\n\r\n");
657 let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
658 assert_eq!(req.version(), Version::HTTP_11);
659 assert_eq!(*req.method(), Method::PUT);
660 assert_eq!(req.path(), "/test");
661 }
662
663 #[test]
664 fn parse_h09_reject() {
665 let mut buf = BytesMut::from(
666 "GET /test1 HTTP/0.9\r\n\
667 \r\n",
668 );
669
670 let mut reader = MessageDecoder::<Request>::default();
671 reader.decode(&mut buf).unwrap_err();
672
673 let mut buf = BytesMut::from(
674 "POST /test2 HTTP/0.9\r\n\
675 Content-Length: 3\r\n\
676 \r\n
677 abc",
678 );
679
680 let mut reader = MessageDecoder::<Request>::default();
681 reader.decode(&mut buf).unwrap_err();
682 }
683
684 #[test]
685 fn parse_h10_get() {
686 let mut buf = BytesMut::from(
687 "GET /test1 HTTP/1.0\r\n\
688 \r\n",
689 );
690
691 let mut reader = MessageDecoder::<Request>::default();
692 let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
693 assert_eq!(req.version(), Version::HTTP_10);
694 assert_eq!(*req.method(), Method::GET);
695 assert_eq!(req.path(), "/test1");
696
697 let mut buf = BytesMut::from(
698 "GET /test2 HTTP/1.0\r\n\
699 Content-Length: 0\r\n\
700 \r\n",
701 );
702
703 let mut reader = MessageDecoder::<Request>::default();
704 let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
705 assert_eq!(req.version(), Version::HTTP_10);
706 assert_eq!(*req.method(), Method::GET);
707 assert_eq!(req.path(), "/test2");
708
709 let mut buf = BytesMut::from(
710 "GET /test3 HTTP/1.0\r\n\
711 Content-Length: 3\r\n\
712 \r\n
713 abc",
714 );
715
716 let mut reader = MessageDecoder::<Request>::default();
717 let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
718 assert_eq!(req.version(), Version::HTTP_10);
719 assert_eq!(*req.method(), Method::GET);
720 assert_eq!(req.path(), "/test3");
721 }
722
723 #[test]
724 fn parse_h10_post() {
725 let mut buf = BytesMut::from(
726 "POST /test1 HTTP/1.0\r\n\
727 Content-Length: 3\r\n\
728 \r\n\
729 abc",
730 );
731
732 let mut reader = MessageDecoder::<Request>::default();
733 let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
734 assert_eq!(req.version(), Version::HTTP_10);
735 assert_eq!(*req.method(), Method::POST);
736 assert_eq!(req.path(), "/test1");
737
738 let mut buf = BytesMut::from(
739 "POST /test2 HTTP/1.0\r\n\
740 Content-Length: 0\r\n\
741 \r\n",
742 );
743
744 let mut reader = MessageDecoder::<Request>::default();
745 let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
746 assert_eq!(req.version(), Version::HTTP_10);
747 assert_eq!(*req.method(), Method::POST);
748 assert_eq!(req.path(), "/test2");
749
750 let mut buf = BytesMut::from(
751 "POST /test3 HTTP/1.0\r\n\
752 \r\n",
753 );
754
755 let mut reader = MessageDecoder::<Request>::default();
756 let err = reader.decode(&mut buf).unwrap_err();
757 assert!(err.to_string().contains("Header"))
758 }
759
760 #[test]
761 fn test_parse_body() {
762 let mut buf = BytesMut::from("GET /test HTTP/1.1\r\nContent-Length: 4\r\n\r\nbody");
763
764 let mut reader = MessageDecoder::<Request>::default();
765 let (req, pl) = reader.decode(&mut buf).unwrap().unwrap();
766 let mut pl = pl.unwrap();
767 assert_eq!(req.version(), Version::HTTP_11);
768 assert_eq!(*req.method(), Method::GET);
769 assert_eq!(req.path(), "/test");
770 assert_eq!(
771 pl.decode(&mut buf).unwrap().unwrap().chunk().as_ref(),
772 b"body"
773 );
774 }
775
776 #[test]
777 fn test_parse_body_crlf() {
778 let mut buf = BytesMut::from("\r\nGET /test HTTP/1.1\r\nContent-Length: 4\r\n\r\nbody");
779
780 let mut reader = MessageDecoder::<Request>::default();
781 let (req, pl) = reader.decode(&mut buf).unwrap().unwrap();
782 let mut pl = pl.unwrap();
783 assert_eq!(req.version(), Version::HTTP_11);
784 assert_eq!(*req.method(), Method::GET);
785 assert_eq!(req.path(), "/test");
786 assert_eq!(
787 pl.decode(&mut buf).unwrap().unwrap().chunk().as_ref(),
788 b"body"
789 );
790 }
791
792 #[test]
793 fn test_parse_partial_eof() {
794 let mut buf = BytesMut::from("GET /test HTTP/1.1\r\n");
795 let mut reader = MessageDecoder::<Request>::default();
796 assert!(reader.decode(&mut buf).unwrap().is_none());
797
798 buf.extend(b"\r\n");
799 let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
800 assert_eq!(req.version(), Version::HTTP_11);
801 assert_eq!(*req.method(), Method::GET);
802 assert_eq!(req.path(), "/test");
803 }
804
805 #[test]
806 fn test_headers_split_field() {
807 let mut buf = BytesMut::from("GET /test HTTP/1.1\r\n");
808
809 let mut reader = MessageDecoder::<Request>::default();
810 assert! { reader.decode(&mut buf).unwrap().is_none() }
811
812 buf.extend(b"t");
813 assert! { reader.decode(&mut buf).unwrap().is_none() }
814
815 buf.extend(b"es");
816 assert! { reader.decode(&mut buf).unwrap().is_none() }
817
818 buf.extend(b"t: value\r\n\r\n");
819 let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
820 assert_eq!(req.version(), Version::HTTP_11);
821 assert_eq!(*req.method(), Method::GET);
822 assert_eq!(req.path(), "/test");
823 assert_eq!(
824 req.headers()
825 .get(HeaderName::try_from("test").unwrap())
826 .unwrap()
827 .as_bytes(),
828 b"value"
829 );
830 }
831
832 #[test]
833 fn test_headers_multi_value() {
834 let mut buf = BytesMut::from(
835 "GET /test HTTP/1.1\r\n\
836 Set-Cookie: c1=cookie1\r\n\
837 Set-Cookie: c2=cookie2\r\n\r\n",
838 );
839 let mut reader = MessageDecoder::<Request>::default();
840 let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
841
842 let val: Vec<_> = req
843 .headers()
844 .get_all(SET_COOKIE)
845 .map(|v| v.to_str().unwrap().to_owned())
846 .collect();
847 assert_eq!(val[0], "c1=cookie1");
848 assert_eq!(val[1], "c2=cookie2");
849 }
850
851 #[test]
852 fn test_conn_default_1_0() {
853 let req = parse_ready!(&mut BytesMut::from("GET /test HTTP/1.0\r\n\r\n"));
854 assert_eq!(req.head().connection_type(), ConnectionType::Close);
855 }
856
857 #[test]
858 fn test_conn_default_1_1() {
859 let req = parse_ready!(&mut BytesMut::from("GET /test HTTP/1.1\r\n\r\n"));
860 assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
861 }
862
863 #[test]
864 fn test_conn_close() {
865 let req = parse_ready!(&mut BytesMut::from(
866 "GET /test HTTP/1.1\r\n\
867 connection: close\r\n\r\n",
868 ));
869 assert_eq!(req.head().connection_type(), ConnectionType::Close);
870
871 let req = parse_ready!(&mut BytesMut::from(
872 "GET /test HTTP/1.1\r\n\
873 connection: Close\r\n\r\n",
874 ));
875 assert_eq!(req.head().connection_type(), ConnectionType::Close);
876 }
877
878 #[test]
879 fn test_conn_close_1_0() {
880 let req = parse_ready!(&mut BytesMut::from(
881 "GET /test HTTP/1.0\r\n\
882 connection: close\r\n\r\n",
883 ));
884 assert_eq!(req.head().connection_type(), ConnectionType::Close);
885 }
886
887 #[test]
888 fn test_conn_keep_alive_1_0() {
889 let req = parse_ready!(&mut BytesMut::from(
890 "GET /test HTTP/1.0\r\n\
891 connection: keep-alive\r\n\r\n",
892 ));
893 assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
894
895 let req = parse_ready!(&mut BytesMut::from(
896 "GET /test HTTP/1.0\r\n\
897 connection: Keep-Alive\r\n\r\n",
898 ));
899 assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
900 }
901
902 #[test]
903 fn test_conn_keep_alive_1_1() {
904 let req = parse_ready!(&mut BytesMut::from(
905 "GET /test HTTP/1.1\r\n\
906 connection: keep-alive\r\n\r\n",
907 ));
908 assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
909 }
910
911 #[test]
912 fn test_conn_other_1_0() {
913 let req = parse_ready!(&mut BytesMut::from(
914 "GET /test HTTP/1.0\r\n\
915 connection: other\r\n\r\n",
916 ));
917 assert_eq!(req.head().connection_type(), ConnectionType::Close);
918 }
919
920 #[test]
921 fn test_conn_other_1_1() {
922 let req = parse_ready!(&mut BytesMut::from(
923 "GET /test HTTP/1.1\r\n\
924 connection: other\r\n\r\n",
925 ));
926 assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
927 }
928
929 #[test]
930 fn test_conn_upgrade() {
931 let req = parse_ready!(&mut BytesMut::from(
932 "GET /test HTTP/1.1\r\n\
933 upgrade: websockets\r\n\
934 connection: upgrade\r\n\r\n",
935 ));
936
937 assert!(req.upgrade());
938 assert_eq!(req.head().connection_type(), ConnectionType::Upgrade);
939
940 let req = parse_ready!(&mut BytesMut::from(
941 "GET /test HTTP/1.1\r\n\
942 upgrade: Websockets\r\n\
943 connection: Upgrade\r\n\r\n",
944 ));
945
946 assert!(req.upgrade());
947 assert_eq!(req.head().connection_type(), ConnectionType::Upgrade);
948 }
949
950 #[test]
951 fn test_conn_upgrade_connect_method() {
952 let req = parse_ready!(&mut BytesMut::from(
953 "CONNECT /test HTTP/1.1\r\n\
954 content-type: text/plain\r\n\r\n",
955 ));
956
957 assert!(req.upgrade());
958 }
959
960 #[test]
961 fn test_headers_bad_content_length() {
962 expect_parse_err!(&mut BytesMut::from(
964 "GET /test HTTP/1.1\r\n\
965 content-length: line\r\n\r\n",
966 ));
967
968 expect_parse_err!(&mut BytesMut::from(
970 "GET /test HTTP/1.1\r\n\
971 content-length: -1\r\n\r\n",
972 ));
973 }
974
975 #[test]
976 fn octal_ish_cl_parsed_as_decimal() {
977 let mut buf = BytesMut::from(
978 "POST /test HTTP/1.1\r\n\
979 content-length: 011\r\n\r\n",
980 );
981 let mut reader = MessageDecoder::<Request>::default();
982 let (_req, pl) = reader.decode(&mut buf).unwrap().unwrap();
983 assert!(matches!(
984 pl,
985 PayloadType::Payload(pl) if pl == PayloadDecoder::length(11)
986 ));
987 }
988
989 #[test]
990 fn test_invalid_header() {
991 expect_parse_err!(&mut BytesMut::from(
992 "GET /test HTTP/1.1\r\n\
993 test line\r\n\r\n",
994 ));
995 }
996
997 #[test]
998 fn test_invalid_name() {
999 expect_parse_err!(&mut BytesMut::from(
1000 "GET /test HTTP/1.1\r\n\
1001 test[]: line\r\n\r\n",
1002 ));
1003 }
1004
1005 #[test]
1006 fn test_http_request_bad_status_line() {
1007 expect_parse_err!(&mut BytesMut::from("getpath \r\n\r\n"));
1008 }
1009
1010 #[test]
1011 fn test_http_request_upgrade_websocket() {
1012 let mut buf = BytesMut::from(
1013 "GET /test HTTP/1.1\r\n\
1014 connection: upgrade\r\n\
1015 upgrade: websocket\r\n\r\n\
1016 some raw data",
1017 );
1018 let mut reader = MessageDecoder::<Request>::default();
1019 let (req, pl) = reader.decode(&mut buf).unwrap().unwrap();
1020 assert_eq!(req.head().connection_type(), ConnectionType::Upgrade);
1021 assert!(req.upgrade());
1022 assert!(pl.is_unhandled());
1023 }
1024
1025 #[test]
1026 fn test_http_request_upgrade_h2c() {
1027 let mut buf = BytesMut::from(
1028 "GET /test HTTP/1.1\r\n\
1029 connection: upgrade, http2-settings\r\n\
1030 upgrade: h2c\r\n\
1031 http2-settings: dummy\r\n\r\n",
1032 );
1033 let mut reader = MessageDecoder::<Request>::default();
1034 let (req, pl) = reader.decode(&mut buf).unwrap().unwrap();
1035 assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
1041 assert!(req.upgrade());
1042 assert!(!pl.is_unhandled());
1043 }
1044
1045 #[test]
1046 fn test_http_request_parser_utf8() {
1047 let req = parse_ready!(&mut BytesMut::from(
1048 "GET /test HTTP/1.1\r\n\
1049 x-test: тест\r\n\r\n",
1050 ));
1051
1052 assert_eq!(
1053 req.headers().get("x-test").unwrap().as_bytes(),
1054 "тест".as_bytes()
1055 );
1056 }
1057
1058 #[test]
1059 fn test_http_request_parser_two_slashes() {
1060 let req = parse_ready!(&mut BytesMut::from("GET //path HTTP/1.1\r\n\r\n"));
1061 assert_eq!(req.path(), "//path");
1062 }
1063
1064 #[test]
1065 fn test_http_request_parser_bad_method() {
1066 expect_parse_err!(&mut BytesMut::from("!12%()+=~$ /get HTTP/1.1\r\n\r\n"));
1067 }
1068
1069 #[test]
1070 fn test_http_request_parser_bad_version() {
1071 expect_parse_err!(&mut BytesMut::from("GET //get HT/11\r\n\r\n"));
1072 }
1073
1074 #[test]
1075 fn test_response_http10_read_until_eof() {
1076 let mut buf = BytesMut::from("HTTP/1.0 200 Ok\r\n\r\ntest data");
1077
1078 let mut reader = MessageDecoder::<ResponseHead>::default();
1079 let (_msg, pl) = reader.decode(&mut buf).unwrap().unwrap();
1080 let mut pl = pl.unwrap();
1081
1082 let chunk = pl.decode(&mut buf).unwrap().unwrap();
1083 assert_eq!(chunk, PayloadItem::Chunk(Bytes::from_static(b"test data")));
1084 }
1085
1086 #[test]
1087 fn hrs_multiple_content_length() {
1088 expect_parse_err!(&mut BytesMut::from(
1089 "GET / HTTP/1.1\r\n\
1090 Host: example.com\r\n\
1091 Content-Length: 4\r\n\
1092 Content-Length: 2\r\n\
1093 \r\n\
1094 abcd",
1095 ));
1096
1097 expect_parse_err!(&mut BytesMut::from(
1098 "GET / HTTP/1.1\r\n\
1099 Host: example.com\r\n\
1100 Content-Length: 0\r\n\
1101 Content-Length: 2\r\n\
1102 \r\n\
1103 ab",
1104 ));
1105 }
1106
1107 #[test]
1108 fn hrs_content_length_plus() {
1109 expect_parse_err!(&mut BytesMut::from(
1110 "GET / HTTP/1.1\r\n\
1111 Host: example.com\r\n\
1112 Content-Length: +3\r\n\
1113 \r\n\
1114 000",
1115 ));
1116 }
1117
1118 #[test]
1119 fn hrs_te_http10() {
1120 expect_parse_err!(&mut BytesMut::from(
1123 "POST / HTTP/1.0\r\n\
1124 Host: example.com\r\n\
1125 Transfer-Encoding: chunked\r\n\
1126 \r\n\
1127 3\r\n\
1128 aaa\r\n\
1129 0\r\n\
1130 ",
1131 ));
1132 }
1133
1134 #[test]
1135 fn hrs_cl_and_te_http10() {
1136 expect_parse_err!(&mut BytesMut::from(
1137 "GET / HTTP/1.0\r\n\
1138 Host: example.com\r\n\
1139 Content-Length: 3\r\n\
1140 Transfer-Encoding: chunked\r\n\
1141 \r\n\
1142 000",
1143 ));
1144 }
1145
1146 #[test]
1147 fn hrs_cl_and_chunked_te_http11() {
1148 expect_parse_err!(&mut BytesMut::from(
1149 "POST / HTTP/1.1\r\n\
1150 Host: example.com\r\n\
1151 Content-Length: 3\r\n\
1152 Transfer-Encoding: chunked\r\n\
1153 \r\n\
1154 0\r\n\
1155 \r\n",
1156 ));
1157
1158 expect_parse_err!(&mut BytesMut::from(
1159 "POST / HTTP/1.1\r\n\
1160 Host: example.com\r\n\
1161 Transfer-Encoding: chunked\r\n\
1162 Content-Length: 3\r\n\
1163 \r\n\
1164 0\r\n\
1165 \r\n",
1166 ));
1167 }
1168
1169 #[test]
1170 fn hrs_identity_te_http11() {
1171 expect_parse_err!(&mut BytesMut::from(
1172 "POST / HTTP/1.1\r\n\
1173 Host: example.com\r\n\
1174 Transfer-Encoding: identity\r\n\
1175 \r\n\
1176 0\r\n",
1177 ));
1178
1179 expect_parse_err!(&mut BytesMut::from(
1180 "POST / HTTP/1.1\r\n\
1181 Host: example.com\r\n\
1182 Content-Length: 3\r\n\
1183 Transfer-Encoding: identity\r\n\
1184 \r\n\
1185 0\r\n",
1186 ));
1187 }
1188
1189 #[test]
1190 fn hrs_unknown_transfer_encoding() {
1191 let mut buf = BytesMut::from(
1192 "GET / HTTP/1.1\r\n\
1193 Host: example.com\r\n\
1194 Transfer-Encoding: JUNK\r\n\
1195 Transfer-Encoding: chunked\r\n\
1196 \r\n\
1197 5\r\n\
1198 hello\r\n\
1199 0",
1200 );
1201
1202 expect_parse_err!(&mut buf);
1203 }
1204
1205 #[test]
1206 fn hrs_multiple_transfer_encoding() {
1207 let mut buf = BytesMut::from(
1208 "GET / HTTP/1.1\r\n\
1209 Host: example.com\r\n\
1210 Content-Length: 51\r\n\
1211 Transfer-Encoding: identity\r\n\
1212 Transfer-Encoding: chunked\r\n\
1213 \r\n\
1214 0\r\n\
1215 \r\n\
1216 GET /forbidden HTTP/1.1\r\n\
1217 Host: example.com\r\n\r\n",
1218 );
1219
1220 expect_parse_err!(&mut buf);
1221 }
1222
1223 #[test]
1224 fn hrs_chunked_te_http11() {
1225 let mut buf = BytesMut::from(
1226 "GET /test HTTP/1.1\r\n\
1227 Host: example.com\r\n\
1228 Transfer-Encoding: chunked\r\n\
1229 \r\n\
1230 1\r\n\
1231 a\r\n\
1232 0\r\n\
1233 \r\n",
1234 );
1235
1236 let mut reader = MessageDecoder::<Request>::default();
1237 let (_msg, pl) = reader.decode(&mut buf).unwrap().unwrap();
1238 let mut pl = pl.unwrap();
1239
1240 let chunk = pl.decode(&mut buf).unwrap().unwrap();
1241 assert_eq!(chunk, PayloadItem::Chunk(Bytes::from_static(b"a")));
1242 }
1243}