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 ver == Version::HTTP_10 && method == Method::POST && length.is_none() {
281 debug!("no Content-Length specified for HTTP/1.0 POST request");
282 return Err(ParseError::Header);
283 }
284
285 if length.is_zero() {
289 length = PayloadLength::None;
290 }
291
292 let decoder = match length {
294 PayloadLength::Payload(pl) => pl,
295 PayloadLength::UpgradeWebSocket => {
296 PayloadType::Stream(PayloadDecoder::eof())
298 }
299 PayloadLength::None => {
300 if method == Method::CONNECT {
301 PayloadType::Stream(PayloadDecoder::eof())
302 } else {
303 PayloadType::None
304 }
305 }
306 };
307
308 let head = msg.head_mut();
309 head.uri = uri;
310 head.method = method;
311 head.version = ver;
312
313 Ok(Some((msg, decoder)))
314 }
315}
316
317impl MessageType for ResponseHead {
318 fn set_connection_type(&mut self, conn_type: Option<ConnectionType>) {
319 if let Some(ctype) = conn_type {
320 ResponseHead::set_connection_type(self, ctype);
321 }
322 }
323
324 fn set_expect(&mut self) {}
325
326 fn headers_mut(&mut self) -> &mut HeaderMap {
327 &mut self.headers
328 }
329
330 fn decode(src: &mut BytesMut) -> Result<Option<(Self, PayloadType)>, ParseError> {
331 let mut headers: [HeaderIndex; MAX_HEADERS] = EMPTY_HEADER_INDEX_ARRAY;
332
333 let (len, ver, status, h_len) = {
334 let mut parsed = unsafe {
339 MaybeUninit::<[MaybeUninit<httparse::Header<'_>>; MAX_HEADERS]>::uninit()
340 .assume_init()
341 };
342
343 let mut res = httparse::Response::new(&mut []);
344
345 let mut config = httparse::ParserConfig::default();
346 config.allow_spaces_after_header_name_in_responses(true);
347
348 match config.parse_response_with_uninit_headers(&mut res, src, &mut parsed)? {
349 httparse::Status::Complete(len) => {
350 let version = if res.version.unwrap() == 1 {
351 Version::HTTP_11
352 } else {
353 Version::HTTP_10
354 };
355
356 let status =
357 StatusCode::from_u16(res.code.unwrap()).map_err(|_| ParseError::Status)?;
358 HeaderIndex::record(src, res.headers, &mut headers);
359
360 (len, version, status, res.headers.len())
361 }
362
363 httparse::Status::Partial => {
364 return if src.len() >= MAX_BUFFER_SIZE {
365 error!("MAX_BUFFER_SIZE unprocessed data reached, closing");
366 Err(ParseError::TooLarge)
367 } else {
368 Ok(None)
369 }
370 }
371 }
372 };
373
374 let mut msg = ResponseHead::new(status);
375 msg.version = ver;
376
377 let mut length = msg.set_headers(&src.split_to(len).freeze(), &headers[..h_len], ver)?;
379
380 if length.is_zero() {
384 length = PayloadLength::None;
385 }
386
387 let decoder = if let PayloadLength::Payload(pl) = length {
389 pl
390 } else if status == StatusCode::SWITCHING_PROTOCOLS {
391 PayloadType::Stream(PayloadDecoder::eof())
393 } else {
394 if msg.version == Version::HTTP_10 {
396 msg.set_connection_type(ConnectionType::Close);
397 PayloadType::Payload(PayloadDecoder::eof())
398 } else {
399 PayloadType::None
400 }
401 };
402
403 Ok(Some((msg, decoder)))
404 }
405}
406
407#[derive(Clone, Copy)]
408pub(crate) struct HeaderIndex {
409 pub(crate) name: (usize, usize),
410 pub(crate) value: (usize, usize),
411}
412
413pub(crate) const EMPTY_HEADER_INDEX: HeaderIndex = HeaderIndex {
414 name: (0, 0),
415 value: (0, 0),
416};
417
418pub(crate) const EMPTY_HEADER_INDEX_ARRAY: [HeaderIndex; MAX_HEADERS] =
419 [EMPTY_HEADER_INDEX; MAX_HEADERS];
420
421impl HeaderIndex {
422 pub(crate) fn record(
423 bytes: &[u8],
424 headers: &[httparse::Header<'_>],
425 indices: &mut [HeaderIndex],
426 ) {
427 let bytes_ptr = bytes.as_ptr() as usize;
428 for (header, indices) in headers.iter().zip(indices.iter_mut()) {
429 let name_start = header.name.as_ptr() as usize - bytes_ptr;
430 let name_end = name_start + header.name.len();
431 indices.name = (name_start, name_end);
432 let value_start = header.value.as_ptr() as usize - bytes_ptr;
433 let value_end = value_start + header.value.len();
434 indices.value = (value_start, value_end);
435 }
436 }
437}
438
439#[derive(Debug, Clone, PartialEq, Eq)]
440pub enum PayloadItem {
442 Chunk(Bytes),
443 Eof,
444}
445
446#[derive(Debug, Clone, PartialEq, Eq)]
450pub struct PayloadDecoder {
451 kind: Kind,
452}
453
454impl PayloadDecoder {
455 pub fn length(x: u64) -> PayloadDecoder {
457 PayloadDecoder {
458 kind: Kind::Length(x),
459 }
460 }
461
462 pub fn chunked() -> PayloadDecoder {
464 PayloadDecoder {
465 kind: Kind::Chunked(ChunkedState::Size, 0),
466 }
467 }
468
469 pub fn eof() -> PayloadDecoder {
471 PayloadDecoder { kind: Kind::Eof }
472 }
473}
474
475#[derive(Debug, Clone, PartialEq, Eq)]
476enum Kind {
477 Length(u64),
479
480 Chunked(ChunkedState, u64),
482
483 Eof,
498}
499
500impl Decoder for PayloadDecoder {
501 type Item = PayloadItem;
502 type Error = io::Error;
503
504 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
505 match self.kind {
506 Kind::Length(ref mut remaining) => {
507 if *remaining == 0 {
508 Ok(Some(PayloadItem::Eof))
509 } else {
510 if src.is_empty() {
511 return Ok(None);
512 }
513 let len = src.len() as u64;
514 let buf;
515 if *remaining > len {
516 buf = src.split().freeze();
517 *remaining -= len;
518 } else {
519 buf = src.split_to(*remaining as usize).freeze();
520 *remaining = 0;
521 };
522 trace!("Length read: {}", buf.len());
523 Ok(Some(PayloadItem::Chunk(buf)))
524 }
525 }
526
527 Kind::Chunked(ref mut state, ref mut size) => {
528 loop {
529 let mut buf = None;
530
531 *state = match state.step(src, size, &mut buf) {
533 Poll::Pending => return Ok(None),
534 Poll::Ready(Ok(state)) => state,
535 Poll::Ready(Err(err)) => return Err(err),
536 };
537
538 if *state == ChunkedState::End {
539 trace!("End of chunked stream");
540 return Ok(Some(PayloadItem::Eof));
541 }
542
543 if let Some(buf) = buf {
544 return Ok(Some(PayloadItem::Chunk(buf)));
545 }
546
547 if src.is_empty() {
548 return Ok(None);
549 }
550 }
551 }
552
553 Kind::Eof => {
554 if src.is_empty() {
555 Ok(None)
556 } else {
557 Ok(Some(PayloadItem::Chunk(src.split().freeze())))
558 }
559 }
560 }
561 }
562}
563
564#[cfg(test)]
565mod tests {
566 use super::*;
567 use crate::{header::SET_COOKIE, HttpMessage as _};
568
569 impl PayloadType {
570 pub(crate) fn unwrap(self) -> PayloadDecoder {
571 match self {
572 PayloadType::Payload(pl) => pl,
573 _ => panic!(),
574 }
575 }
576
577 pub(crate) fn is_unhandled(&self) -> bool {
578 matches!(self, PayloadType::Stream(_))
579 }
580 }
581
582 impl PayloadItem {
583 pub(crate) fn chunk(self) -> Bytes {
584 match self {
585 PayloadItem::Chunk(chunk) => chunk,
586 _ => panic!("error"),
587 }
588 }
589
590 pub(crate) fn eof(&self) -> bool {
591 matches!(*self, PayloadItem::Eof)
592 }
593 }
594
595 macro_rules! parse_ready {
596 ($e:expr) => {{
597 match MessageDecoder::<Request>::default().decode($e) {
598 Ok(Some((msg, _))) => msg,
599 Ok(_) => unreachable!("Eof during parsing http request"),
600 Err(err) => unreachable!("Error during parsing http request: {:?}", err),
601 }
602 }};
603 }
604
605 macro_rules! expect_parse_err {
606 ($e:expr) => {{
607 match MessageDecoder::<Request>::default().decode($e) {
608 Err(err) => match err {
609 ParseError::Io(_) => unreachable!("Parse error expected"),
610 _ => {}
611 },
612 _ => unreachable!("Error expected"),
613 }
614 }};
615 }
616
617 #[test]
618 fn test_parse() {
619 let mut buf = BytesMut::from("GET /test HTTP/1.1\r\n\r\n");
620
621 let mut reader = MessageDecoder::<Request>::default();
622 match reader.decode(&mut buf) {
623 Ok(Some((req, _))) => {
624 assert_eq!(req.version(), Version::HTTP_11);
625 assert_eq!(*req.method(), Method::GET);
626 assert_eq!(req.path(), "/test");
627 }
628 Ok(_) | Err(_) => unreachable!("Error during parsing http request"),
629 }
630 }
631
632 #[test]
633 fn test_parse_partial() {
634 let mut buf = BytesMut::from("PUT /test HTTP/1");
635
636 let mut reader = MessageDecoder::<Request>::default();
637 assert!(reader.decode(&mut buf).unwrap().is_none());
638
639 buf.extend(b".1\r\n\r\n");
640 let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
641 assert_eq!(req.version(), Version::HTTP_11);
642 assert_eq!(*req.method(), Method::PUT);
643 assert_eq!(req.path(), "/test");
644 }
645
646 #[test]
647 fn parse_h09_reject() {
648 let mut buf = BytesMut::from(
649 "GET /test1 HTTP/0.9\r\n\
650 \r\n",
651 );
652
653 let mut reader = MessageDecoder::<Request>::default();
654 reader.decode(&mut buf).unwrap_err();
655
656 let mut buf = BytesMut::from(
657 "POST /test2 HTTP/0.9\r\n\
658 Content-Length: 3\r\n\
659 \r\n
660 abc",
661 );
662
663 let mut reader = MessageDecoder::<Request>::default();
664 reader.decode(&mut buf).unwrap_err();
665 }
666
667 #[test]
668 fn parse_h10_get() {
669 let mut buf = BytesMut::from(
670 "GET /test1 HTTP/1.0\r\n\
671 \r\n",
672 );
673
674 let mut reader = MessageDecoder::<Request>::default();
675 let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
676 assert_eq!(req.version(), Version::HTTP_10);
677 assert_eq!(*req.method(), Method::GET);
678 assert_eq!(req.path(), "/test1");
679
680 let mut buf = BytesMut::from(
681 "GET /test2 HTTP/1.0\r\n\
682 Content-Length: 0\r\n\
683 \r\n",
684 );
685
686 let mut reader = MessageDecoder::<Request>::default();
687 let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
688 assert_eq!(req.version(), Version::HTTP_10);
689 assert_eq!(*req.method(), Method::GET);
690 assert_eq!(req.path(), "/test2");
691
692 let mut buf = BytesMut::from(
693 "GET /test3 HTTP/1.0\r\n\
694 Content-Length: 3\r\n\
695 \r\n
696 abc",
697 );
698
699 let mut reader = MessageDecoder::<Request>::default();
700 let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
701 assert_eq!(req.version(), Version::HTTP_10);
702 assert_eq!(*req.method(), Method::GET);
703 assert_eq!(req.path(), "/test3");
704 }
705
706 #[test]
707 fn parse_h10_post() {
708 let mut buf = BytesMut::from(
709 "POST /test1 HTTP/1.0\r\n\
710 Content-Length: 3\r\n\
711 \r\n\
712 abc",
713 );
714
715 let mut reader = MessageDecoder::<Request>::default();
716 let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
717 assert_eq!(req.version(), Version::HTTP_10);
718 assert_eq!(*req.method(), Method::POST);
719 assert_eq!(req.path(), "/test1");
720
721 let mut buf = BytesMut::from(
722 "POST /test2 HTTP/1.0\r\n\
723 Content-Length: 0\r\n\
724 \r\n",
725 );
726
727 let mut reader = MessageDecoder::<Request>::default();
728 let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
729 assert_eq!(req.version(), Version::HTTP_10);
730 assert_eq!(*req.method(), Method::POST);
731 assert_eq!(req.path(), "/test2");
732
733 let mut buf = BytesMut::from(
734 "POST /test3 HTTP/1.0\r\n\
735 \r\n",
736 );
737
738 let mut reader = MessageDecoder::<Request>::default();
739 let err = reader.decode(&mut buf).unwrap_err();
740 assert!(err.to_string().contains("Header"))
741 }
742
743 #[test]
744 fn test_parse_body() {
745 let mut buf = BytesMut::from("GET /test HTTP/1.1\r\nContent-Length: 4\r\n\r\nbody");
746
747 let mut reader = MessageDecoder::<Request>::default();
748 let (req, pl) = reader.decode(&mut buf).unwrap().unwrap();
749 let mut pl = pl.unwrap();
750 assert_eq!(req.version(), Version::HTTP_11);
751 assert_eq!(*req.method(), Method::GET);
752 assert_eq!(req.path(), "/test");
753 assert_eq!(
754 pl.decode(&mut buf).unwrap().unwrap().chunk().as_ref(),
755 b"body"
756 );
757 }
758
759 #[test]
760 fn test_parse_body_crlf() {
761 let mut buf = BytesMut::from("\r\nGET /test HTTP/1.1\r\nContent-Length: 4\r\n\r\nbody");
762
763 let mut reader = MessageDecoder::<Request>::default();
764 let (req, pl) = reader.decode(&mut buf).unwrap().unwrap();
765 let mut pl = pl.unwrap();
766 assert_eq!(req.version(), Version::HTTP_11);
767 assert_eq!(*req.method(), Method::GET);
768 assert_eq!(req.path(), "/test");
769 assert_eq!(
770 pl.decode(&mut buf).unwrap().unwrap().chunk().as_ref(),
771 b"body"
772 );
773 }
774
775 #[test]
776 fn test_parse_partial_eof() {
777 let mut buf = BytesMut::from("GET /test HTTP/1.1\r\n");
778 let mut reader = MessageDecoder::<Request>::default();
779 assert!(reader.decode(&mut buf).unwrap().is_none());
780
781 buf.extend(b"\r\n");
782 let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
783 assert_eq!(req.version(), Version::HTTP_11);
784 assert_eq!(*req.method(), Method::GET);
785 assert_eq!(req.path(), "/test");
786 }
787
788 #[test]
789 fn test_headers_split_field() {
790 let mut buf = BytesMut::from("GET /test HTTP/1.1\r\n");
791
792 let mut reader = MessageDecoder::<Request>::default();
793 assert! { reader.decode(&mut buf).unwrap().is_none() }
794
795 buf.extend(b"t");
796 assert! { reader.decode(&mut buf).unwrap().is_none() }
797
798 buf.extend(b"es");
799 assert! { reader.decode(&mut buf).unwrap().is_none() }
800
801 buf.extend(b"t: value\r\n\r\n");
802 let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
803 assert_eq!(req.version(), Version::HTTP_11);
804 assert_eq!(*req.method(), Method::GET);
805 assert_eq!(req.path(), "/test");
806 assert_eq!(
807 req.headers()
808 .get(HeaderName::try_from("test").unwrap())
809 .unwrap()
810 .as_bytes(),
811 b"value"
812 );
813 }
814
815 #[test]
816 fn test_headers_multi_value() {
817 let mut buf = BytesMut::from(
818 "GET /test HTTP/1.1\r\n\
819 Set-Cookie: c1=cookie1\r\n\
820 Set-Cookie: c2=cookie2\r\n\r\n",
821 );
822 let mut reader = MessageDecoder::<Request>::default();
823 let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
824
825 let val: Vec<_> = req
826 .headers()
827 .get_all(SET_COOKIE)
828 .map(|v| v.to_str().unwrap().to_owned())
829 .collect();
830 assert_eq!(val[0], "c1=cookie1");
831 assert_eq!(val[1], "c2=cookie2");
832 }
833
834 #[test]
835 fn test_conn_default_1_0() {
836 let req = parse_ready!(&mut BytesMut::from("GET /test HTTP/1.0\r\n\r\n"));
837 assert_eq!(req.head().connection_type(), ConnectionType::Close);
838 }
839
840 #[test]
841 fn test_conn_default_1_1() {
842 let req = parse_ready!(&mut BytesMut::from("GET /test HTTP/1.1\r\n\r\n"));
843 assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
844 }
845
846 #[test]
847 fn test_conn_close() {
848 let req = parse_ready!(&mut BytesMut::from(
849 "GET /test HTTP/1.1\r\n\
850 connection: close\r\n\r\n",
851 ));
852 assert_eq!(req.head().connection_type(), ConnectionType::Close);
853
854 let req = parse_ready!(&mut BytesMut::from(
855 "GET /test HTTP/1.1\r\n\
856 connection: Close\r\n\r\n",
857 ));
858 assert_eq!(req.head().connection_type(), ConnectionType::Close);
859 }
860
861 #[test]
862 fn test_conn_close_1_0() {
863 let req = parse_ready!(&mut BytesMut::from(
864 "GET /test HTTP/1.0\r\n\
865 connection: close\r\n\r\n",
866 ));
867 assert_eq!(req.head().connection_type(), ConnectionType::Close);
868 }
869
870 #[test]
871 fn test_conn_keep_alive_1_0() {
872 let req = parse_ready!(&mut BytesMut::from(
873 "GET /test HTTP/1.0\r\n\
874 connection: keep-alive\r\n\r\n",
875 ));
876 assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
877
878 let req = parse_ready!(&mut BytesMut::from(
879 "GET /test HTTP/1.0\r\n\
880 connection: Keep-Alive\r\n\r\n",
881 ));
882 assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
883 }
884
885 #[test]
886 fn test_conn_keep_alive_1_1() {
887 let req = parse_ready!(&mut BytesMut::from(
888 "GET /test HTTP/1.1\r\n\
889 connection: keep-alive\r\n\r\n",
890 ));
891 assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
892 }
893
894 #[test]
895 fn test_conn_other_1_0() {
896 let req = parse_ready!(&mut BytesMut::from(
897 "GET /test HTTP/1.0\r\n\
898 connection: other\r\n\r\n",
899 ));
900 assert_eq!(req.head().connection_type(), ConnectionType::Close);
901 }
902
903 #[test]
904 fn test_conn_other_1_1() {
905 let req = parse_ready!(&mut BytesMut::from(
906 "GET /test HTTP/1.1\r\n\
907 connection: other\r\n\r\n",
908 ));
909 assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
910 }
911
912 #[test]
913 fn test_conn_upgrade() {
914 let req = parse_ready!(&mut BytesMut::from(
915 "GET /test HTTP/1.1\r\n\
916 upgrade: websockets\r\n\
917 connection: upgrade\r\n\r\n",
918 ));
919
920 assert!(req.upgrade());
921 assert_eq!(req.head().connection_type(), ConnectionType::Upgrade);
922
923 let req = parse_ready!(&mut BytesMut::from(
924 "GET /test HTTP/1.1\r\n\
925 upgrade: Websockets\r\n\
926 connection: Upgrade\r\n\r\n",
927 ));
928
929 assert!(req.upgrade());
930 assert_eq!(req.head().connection_type(), ConnectionType::Upgrade);
931 }
932
933 #[test]
934 fn test_conn_upgrade_connect_method() {
935 let req = parse_ready!(&mut BytesMut::from(
936 "CONNECT /test HTTP/1.1\r\n\
937 content-type: text/plain\r\n\r\n",
938 ));
939
940 assert!(req.upgrade());
941 }
942
943 #[test]
944 fn test_headers_bad_content_length() {
945 expect_parse_err!(&mut BytesMut::from(
947 "GET /test HTTP/1.1\r\n\
948 content-length: line\r\n\r\n",
949 ));
950
951 expect_parse_err!(&mut BytesMut::from(
953 "GET /test HTTP/1.1\r\n\
954 content-length: -1\r\n\r\n",
955 ));
956 }
957
958 #[test]
959 fn octal_ish_cl_parsed_as_decimal() {
960 let mut buf = BytesMut::from(
961 "POST /test HTTP/1.1\r\n\
962 content-length: 011\r\n\r\n",
963 );
964 let mut reader = MessageDecoder::<Request>::default();
965 let (_req, pl) = reader.decode(&mut buf).unwrap().unwrap();
966 assert!(matches!(
967 pl,
968 PayloadType::Payload(pl) if pl == PayloadDecoder::length(11)
969 ));
970 }
971
972 #[test]
973 fn test_invalid_header() {
974 expect_parse_err!(&mut BytesMut::from(
975 "GET /test HTTP/1.1\r\n\
976 test line\r\n\r\n",
977 ));
978 }
979
980 #[test]
981 fn test_invalid_name() {
982 expect_parse_err!(&mut BytesMut::from(
983 "GET /test HTTP/1.1\r\n\
984 test[]: line\r\n\r\n",
985 ));
986 }
987
988 #[test]
989 fn test_http_request_bad_status_line() {
990 expect_parse_err!(&mut BytesMut::from("getpath \r\n\r\n"));
991 }
992
993 #[test]
994 fn test_http_request_upgrade_websocket() {
995 let mut buf = BytesMut::from(
996 "GET /test HTTP/1.1\r\n\
997 connection: upgrade\r\n\
998 upgrade: websocket\r\n\r\n\
999 some raw data",
1000 );
1001 let mut reader = MessageDecoder::<Request>::default();
1002 let (req, pl) = reader.decode(&mut buf).unwrap().unwrap();
1003 assert_eq!(req.head().connection_type(), ConnectionType::Upgrade);
1004 assert!(req.upgrade());
1005 assert!(pl.is_unhandled());
1006 }
1007
1008 #[test]
1009 fn test_http_request_upgrade_h2c() {
1010 let mut buf = BytesMut::from(
1011 "GET /test HTTP/1.1\r\n\
1012 connection: upgrade, http2-settings\r\n\
1013 upgrade: h2c\r\n\
1014 http2-settings: dummy\r\n\r\n",
1015 );
1016 let mut reader = MessageDecoder::<Request>::default();
1017 let (req, pl) = reader.decode(&mut buf).unwrap().unwrap();
1018 assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
1024 assert!(req.upgrade());
1025 assert!(!pl.is_unhandled());
1026 }
1027
1028 #[test]
1029 fn test_http_request_parser_utf8() {
1030 let req = parse_ready!(&mut BytesMut::from(
1031 "GET /test HTTP/1.1\r\n\
1032 x-test: тест\r\n\r\n",
1033 ));
1034
1035 assert_eq!(
1036 req.headers().get("x-test").unwrap().as_bytes(),
1037 "тест".as_bytes()
1038 );
1039 }
1040
1041 #[test]
1042 fn test_http_request_parser_two_slashes() {
1043 let req = parse_ready!(&mut BytesMut::from("GET //path HTTP/1.1\r\n\r\n"));
1044 assert_eq!(req.path(), "//path");
1045 }
1046
1047 #[test]
1048 fn test_http_request_parser_bad_method() {
1049 expect_parse_err!(&mut BytesMut::from("!12%()+=~$ /get HTTP/1.1\r\n\r\n"));
1050 }
1051
1052 #[test]
1053 fn test_http_request_parser_bad_version() {
1054 expect_parse_err!(&mut BytesMut::from("GET //get HT/11\r\n\r\n"));
1055 }
1056
1057 #[test]
1058 fn test_response_http10_read_until_eof() {
1059 let mut buf = BytesMut::from("HTTP/1.0 200 Ok\r\n\r\ntest data");
1060
1061 let mut reader = MessageDecoder::<ResponseHead>::default();
1062 let (_msg, pl) = reader.decode(&mut buf).unwrap().unwrap();
1063 let mut pl = pl.unwrap();
1064
1065 let chunk = pl.decode(&mut buf).unwrap().unwrap();
1066 assert_eq!(chunk, PayloadItem::Chunk(Bytes::from_static(b"test data")));
1067 }
1068
1069 #[test]
1070 fn hrs_multiple_content_length() {
1071 expect_parse_err!(&mut BytesMut::from(
1072 "GET / HTTP/1.1\r\n\
1073 Host: example.com\r\n\
1074 Content-Length: 4\r\n\
1075 Content-Length: 2\r\n\
1076 \r\n\
1077 abcd",
1078 ));
1079
1080 expect_parse_err!(&mut BytesMut::from(
1081 "GET / HTTP/1.1\r\n\
1082 Host: example.com\r\n\
1083 Content-Length: 0\r\n\
1084 Content-Length: 2\r\n\
1085 \r\n\
1086 ab",
1087 ));
1088 }
1089
1090 #[test]
1091 fn hrs_content_length_plus() {
1092 expect_parse_err!(&mut BytesMut::from(
1093 "GET / HTTP/1.1\r\n\
1094 Host: example.com\r\n\
1095 Content-Length: +3\r\n\
1096 \r\n\
1097 000",
1098 ));
1099 }
1100
1101 #[test]
1102 fn hrs_te_http10() {
1103 expect_parse_err!(&mut BytesMut::from(
1106 "POST / HTTP/1.0\r\n\
1107 Host: example.com\r\n\
1108 Transfer-Encoding: chunked\r\n\
1109 \r\n\
1110 3\r\n\
1111 aaa\r\n\
1112 0\r\n\
1113 ",
1114 ));
1115 }
1116
1117 #[test]
1118 fn hrs_cl_and_te_http10() {
1119 let mut buf = BytesMut::from(
1122 "GET / HTTP/1.0\r\n\
1123 Host: example.com\r\n\
1124 Content-Length: 3\r\n\
1125 Transfer-Encoding: chunked\r\n\
1126 \r\n\
1127 000",
1128 );
1129
1130 parse_ready!(&mut buf);
1131 }
1132
1133 #[test]
1134 fn hrs_unknown_transfer_encoding() {
1135 let mut buf = BytesMut::from(
1136 "GET / HTTP/1.1\r\n\
1137 Host: example.com\r\n\
1138 Transfer-Encoding: JUNK\r\n\
1139 Transfer-Encoding: chunked\r\n\
1140 \r\n\
1141 5\r\n\
1142 hello\r\n\
1143 0",
1144 );
1145
1146 expect_parse_err!(&mut buf);
1147 }
1148
1149 #[test]
1150 fn hrs_multiple_transfer_encoding() {
1151 let mut buf = BytesMut::from(
1152 "GET / HTTP/1.1\r\n\
1153 Host: example.com\r\n\
1154 Content-Length: 51\r\n\
1155 Transfer-Encoding: identity\r\n\
1156 Transfer-Encoding: chunked\r\n\
1157 \r\n\
1158 0\r\n\
1159 \r\n\
1160 GET /forbidden HTTP/1.1\r\n\
1161 Host: example.com\r\n\r\n",
1162 );
1163
1164 expect_parse_err!(&mut buf);
1165 }
1166
1167 #[test]
1168 fn transfer_encoding_agrees() {
1169 let mut buf = BytesMut::from(
1170 "GET /test HTTP/1.1\r\n\
1171 Host: example.com\r\n\
1172 Content-Length: 3\r\n\
1173 Transfer-Encoding: identity\r\n\
1174 \r\n\
1175 0\r\n",
1176 );
1177
1178 let mut reader = MessageDecoder::<Request>::default();
1179 let (_msg, pl) = reader.decode(&mut buf).unwrap().unwrap();
1180 let mut pl = pl.unwrap();
1181
1182 let chunk = pl.decode(&mut buf).unwrap().unwrap();
1183 assert_eq!(chunk, PayloadItem::Chunk(Bytes::from_static(b"0\r\n")));
1184 }
1185}