1use std::{
2 collections::VecDeque,
3 fmt,
4 future::Future,
5 io, mem, net,
6 pin::Pin,
7 rc::Rc,
8 task::{Context, Poll},
9};
10
11use actix_codec::{Framed, FramedParts};
12use actix_service::Service;
13use bitflags::bitflags;
14use bytes::{Buf, BytesMut};
15use futures_core::ready;
16use pin_project_lite::pin_project;
17use tokio::{
18 io::{AsyncRead, AsyncWrite},
19 time::sleep_until,
20};
21use tokio_util::codec::{Decoder as _, Encoder as _};
22use tracing::{error, trace};
23
24use super::{
25 codec::Codec,
26 decoder::MAX_BUFFER_SIZE,
27 payload::{Payload, PayloadSender, PayloadStatus},
28 timer::TimerState,
29 Message, MessageType,
30};
31use crate::{
32 body::{BodySize, BoxBody, MessageBody},
33 config::ServiceConfig,
34 error::{DispatchError, ParseError, PayloadError},
35 service::HttpFlow,
36 ConnectionType, Error, Extensions, HttpMessage, OnConnectData, Request, Response, StatusCode,
37};
38
39const LW_BUFFER_SIZE: usize = 1024;
40const HW_BUFFER_SIZE: usize = 1024 * 8;
41const MAX_PIPELINED_MESSAGES: usize = 16;
42
43const WRITE_BUFFER_RETENTION_LIMIT: usize = 1024 * 128;
45
46bitflags! {
47 #[derive(Debug, Clone, Copy)]
48 pub struct Flags: u8 {
49 const STARTED = 0b0000_0001;
51
52 const FINISHED = 0b0000_0010;
54
55 const KEEP_ALIVE = 0b0000_0100;
57
58 const SHUTDOWN = 0b0000_1000;
60
61 const READ_DISCONNECT = 0b0001_0000;
63
64 const WRITE_DISCONNECT = 0b0010_0000;
66
67 const LINGER = 0b0100_0000;
69
70 const DRAINING = 0b1000_0000;
77 }
78}
79
80#[cfg(not(test))]
86pin_project! {
87 pub struct Dispatcher<T, S, B, X, U>
89 where
90 S: Service<Request>,
91 S::Error: Into<Response<BoxBody>>,
92
93 B: MessageBody,
94
95 X: Service<Request, Response = Request>,
96 X::Error: Into<Response<BoxBody>>,
97
98 U: Service<(Request, Framed<T, Codec>), Response = ()>,
99 U::Error: fmt::Display,
100 {
101 #[pin]
102 inner: DispatcherState<T, S, B, X, U>,
103 }
104}
105
106#[cfg(test)]
107pin_project! {
108 pub struct Dispatcher<T, S, B, X, U>
110 where
111 S: Service<Request>,
112 S::Error: Into<Response<BoxBody>>,
113
114 B: MessageBody,
115
116 X: Service<Request, Response = Request>,
117 X::Error: Into<Response<BoxBody>>,
118
119 U: Service<(Request, Framed<T, Codec>), Response = ()>,
120 U::Error: fmt::Display,
121 {
122 #[pin]
123 pub(super) inner: DispatcherState<T, S, B, X, U>,
124
125 pub(super) poll_count: u64,
127 }
128}
129
130pin_project! {
131 #[project = DispatcherStateProj]
132 pub(super) enum DispatcherState<T, S, B, X, U>
133 where
134 S: Service<Request>,
135 S::Error: Into<Response<BoxBody>>,
136
137 B: MessageBody,
138
139 X: Service<Request, Response = Request>,
140 X::Error: Into<Response<BoxBody>>,
141
142 U: Service<(Request, Framed<T, Codec>), Response = ()>,
143 U::Error: fmt::Display,
144 {
145 Normal { #[pin] inner: InnerDispatcher<T, S, B, X, U> },
146 Upgrade { #[pin] fut: U::Future },
147 }
148}
149
150pin_project! {
151 #[project = InnerDispatcherProj]
152 pub(super) struct InnerDispatcher<T, S, B, X, U>
153 where
154 S: Service<Request>,
155 S::Error: Into<Response<BoxBody>>,
156
157 B: MessageBody,
158
159 X: Service<Request, Response = Request>,
160 X::Error: Into<Response<BoxBody>>,
161
162 U: Service<(Request, Framed<T, Codec>), Response = ()>,
163 U::Error: fmt::Display,
164 {
165 flow: Rc<HttpFlow<S, X, U>>,
166 pub(super) flags: Flags,
167 peer_addr: Option<net::SocketAddr>,
168 conn_data: Option<Rc<Extensions>>,
169 config: ServiceConfig,
170 error: Option<DispatchError>,
171
172 #[pin]
173 pub(super) state: State<S, B, X>,
174 payload: Option<PayloadSender>,
176 payload_drainable: bool,
178 messages: VecDeque<DispatcherMessage>,
179
180 head_timer: TimerState,
181 ka_timer: TimerState,
182 shutdown_timer: TimerState,
183 graceful_shutdown: Option<crate::config::GracefulShutdownFuture>,
184
185 pub(super) io: Option<T>,
186 read_buf: BytesMut,
187 write_buf: BytesMut,
188
189 h1_write_buffer_size: usize,
191
192 write_buf_needs_reset: bool,
194
195 codec: Codec,
196 }
197}
198
199enum DispatcherMessage {
200 Item(Request),
201 Upgrade(Request),
202 Error(Response<()>),
203}
204
205pin_project! {
206 #[project = StateProj]
207 pub(super) enum State<S, B, X>
208 where
209 S: Service<Request>,
210 X: Service<Request, Response = Request>,
211 B: MessageBody,
212 {
213 None,
214 ExpectCall { #[pin] fut: X::Future },
215 ServiceCall { #[pin] fut: S::Future },
216 SendPayload { #[pin] body: B },
217 SendErrorPayload { #[pin] body: BoxBody },
218 }
219}
220
221impl<S, B, X> State<S, B, X>
222where
223 S: Service<Request>,
224 X: Service<Request, Response = Request>,
225 B: MessageBody,
226{
227 pub(super) fn is_none(&self) -> bool {
228 matches!(self, State::None)
229 }
230}
231
232impl<S, B, X> fmt::Debug for State<S, B, X>
233where
234 S: Service<Request>,
235 X: Service<Request, Response = Request>,
236 B: MessageBody,
237{
238 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
239 match self {
240 Self::None => write!(f, "State::None"),
241 Self::ExpectCall { .. } => f.debug_struct("State::ExpectCall").finish_non_exhaustive(),
242 Self::ServiceCall { .. } => {
243 f.debug_struct("State::ServiceCall").finish_non_exhaustive()
244 }
245 Self::SendPayload { .. } => {
246 f.debug_struct("State::SendPayload").finish_non_exhaustive()
247 }
248 Self::SendErrorPayload { .. } => f
249 .debug_struct("State::SendErrorPayload")
250 .finish_non_exhaustive(),
251 }
252 }
253}
254
255#[derive(Debug)]
256enum PollResponse {
257 Upgrade(Request),
258 DoNothing,
259 DrainWriteBuf,
260}
261
262impl<T, S, B, X, U> Dispatcher<T, S, B, X, U>
263where
264 T: AsyncRead + AsyncWrite + Unpin,
265
266 S: Service<Request>,
267 S::Error: Into<Response<BoxBody>>,
268 S::Response: Into<Response<B>>,
269
270 B: MessageBody,
271
272 X: Service<Request, Response = Request>,
273 X::Error: Into<Response<BoxBody>>,
274
275 U: Service<(Request, Framed<T, Codec>), Response = ()>,
276 U::Error: fmt::Display,
277{
278 pub(crate) fn new(
280 io: T,
281 flow: Rc<HttpFlow<S, X, U>>,
282 config: ServiceConfig,
283 peer_addr: Option<net::SocketAddr>,
284 conn_data: OnConnectData,
285 ) -> Self {
286 Dispatcher {
287 inner: DispatcherState::Normal {
288 inner: InnerDispatcher {
289 flow,
290 flags: Flags::empty(),
291 peer_addr,
292 conn_data: conn_data.0.map(Rc::new),
293 config: config.clone(),
294 error: None,
295
296 state: State::None,
297 payload: None,
298 payload_drainable: false,
299 messages: VecDeque::new(),
300
301 head_timer: TimerState::new(config.client_request_deadline().is_some()),
302 ka_timer: TimerState::new(config.keep_alive().enabled()),
303 shutdown_timer: TimerState::new(config.client_disconnect_deadline().is_some()),
304 graceful_shutdown: config.graceful_shutdown(),
305
306 io: Some(io),
307 read_buf: BytesMut::with_capacity(HW_BUFFER_SIZE),
308 write_buf: BytesMut::with_capacity(HW_BUFFER_SIZE),
309 h1_write_buffer_size: config.h1_write_buffer_size(),
310 write_buf_needs_reset: false,
311 codec: Codec::new(config),
312 },
313 },
314
315 #[cfg(test)]
316 poll_count: 0,
317 }
318 }
319}
320
321impl<T, S, B, X, U> InnerDispatcher<T, S, B, X, U>
322where
323 T: AsyncRead + AsyncWrite + Unpin,
324
325 S: Service<Request>,
326 S::Error: Into<Response<BoxBody>>,
327 S::Response: Into<Response<B>>,
328
329 B: MessageBody,
330
331 X: Service<Request, Response = Request>,
332 X::Error: Into<Response<BoxBody>>,
333
334 U: Service<(Request, Framed<T, Codec>), Response = ()>,
335 U::Error: fmt::Display,
336{
337 fn can_read(&self, cx: &mut Context<'_>) -> bool {
338 if self.flags.contains(Flags::READ_DISCONNECT) {
339 false
340 } else if let Some(ref info) = self.payload {
341 matches!(
342 info.need_read(cx),
343 PayloadStatus::Read | PayloadStatus::Dropped
344 )
345 } else {
346 true
347 }
348 }
349
350 fn client_disconnected(self: Pin<&mut Self>) {
351 let this = self.project();
352
353 this.flags
354 .insert(Flags::READ_DISCONNECT | Flags::WRITE_DISCONNECT);
355
356 if let Some(mut payload) = this.payload.take() {
357 payload.set_error(PayloadError::Incomplete(None));
358 }
359 }
360
361 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
362 let InnerDispatcherProj {
363 io,
364 write_buf,
365 h1_write_buffer_size,
366 write_buf_needs_reset,
367 ..
368 } = self.project();
369 let mut io = Pin::new(io.as_mut().unwrap());
370
371 let retention_limit = (*h1_write_buffer_size).max(WRITE_BUFFER_RETENTION_LIMIT);
374
375 if write_buf.capacity() > retention_limit {
376 *write_buf_needs_reset = true;
379 }
380
381 let len = write_buf.len();
382 let mut written = 0;
383
384 while written < len {
385 match io.as_mut().poll_write(cx, &write_buf[written..])? {
386 Poll::Ready(0) => {
387 error!("write zero; closing");
388 return Poll::Ready(Err(io::Error::new(io::ErrorKind::WriteZero, "")));
389 }
390
391 Poll::Ready(n) => written += n,
392
393 Poll::Pending => {
394 write_buf.advance(written);
395 return Poll::Pending;
396 }
397 }
398 }
399
400 if *write_buf_needs_reset {
402 *write_buf = BytesMut::with_capacity(HW_BUFFER_SIZE);
403 *write_buf_needs_reset = false;
404 } else {
405 write_buf.clear();
406 }
407
408 io.poll_flush(cx)
410 }
411
412 fn enter_linger(flags: &mut Flags) {
413 flags.remove(Flags::KEEP_ALIVE);
414 flags.insert(Flags::LINGER | Flags::FINISHED);
415 }
416
417 fn ensure_linger_timer(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> bool {
418 let this = self.as_mut().project();
419
420 if matches!(this.shutdown_timer, TimerState::Active { .. }) {
421 return true;
422 }
423
424 if let Some(deadline) = this.config.client_disconnect_deadline() {
425 this.shutdown_timer
426 .set_and_init(cx, sleep_until(deadline.into()), line!());
427 true
428 } else {
429 false
430 }
431 }
432
433 fn poll_linger(
434 mut self: Pin<&mut Self>,
435 cx: &mut Context<'_>,
436 ) -> Result<Poll<()>, DispatchError> {
437 if self.as_mut().poll_flush(cx)?.is_pending() {
438 return Ok(Poll::Pending);
439 }
440
441 if !self.as_mut().ensure_linger_timer(cx) {
442 let this = self.as_mut().project();
443 this.flags.remove(Flags::LINGER);
444 this.flags.insert(Flags::SHUTDOWN);
445 return Ok(Poll::Ready(()));
446 }
447
448 loop {
449 let should_disconnect = self.as_mut().read_available(cx)?;
450 let this = self.as_mut().project();
451 let mut progressed = false;
452
453 if !this.read_buf.is_empty() {
454 this.read_buf.clear();
455 progressed = true;
456 }
457
458 if should_disconnect {
459 this.flags.remove(Flags::LINGER);
460 this.flags.insert(Flags::READ_DISCONNECT | Flags::SHUTDOWN);
461 return Ok(Poll::Ready(()));
462 }
463
464 if !progressed {
465 return Ok(Poll::Pending);
466 }
467 }
468 }
469
470 fn send_response_inner(
471 self: Pin<&mut Self>,
472 res: Response<()>,
473 body: &impl MessageBody,
474 ) -> Result<BodySize, DispatchError> {
475 let this = self.project();
476
477 let size = body.size();
478
479 this.codec
480 .encode(Message::Item((res, size)), this.write_buf)
481 .map_err(|err| {
482 if let Some(mut payload) = this.payload.take() {
483 payload.set_error(PayloadError::Incomplete(None));
484 }
485
486 DispatchError::Io(err)
487 })?;
488
489 Ok(size)
490 }
491
492 fn send_response(
493 mut self: Pin<&mut Self>,
494 mut res: Response<()>,
495 body: B,
496 ) -> Result<(), DispatchError> {
497 let is_upgrade = res.upgrade();
498 let (draining, close_for_unread_payload) = {
499 let this = self.as_mut().project();
500 (
501 this.flags.contains(Flags::DRAINING),
502 !is_upgrade
503 && should_close_for_unread_payload(
504 this.payload.as_ref(),
505 *this.payload_drainable,
506 ),
507 )
508 };
509 let close_after_response = (!is_upgrade && draining) || close_for_unread_payload;
510
511 if close_after_response {
512 res.head_mut().set_connection_type(ConnectionType::Close);
513 }
514
515 let size = self.as_mut().send_response_inner(res, &body)?;
516 match size {
517 BodySize::None | BodySize::Sized(0) => {
518 let mut this = self.as_mut().project();
519
520 if close_for_unread_payload {
521 if this.config.client_disconnect_deadline().is_some() {
522 Self::enter_linger(this.flags);
523 } else {
524 this.flags.insert(Flags::SHUTDOWN | Flags::FINISHED);
525 }
526 } else {
527 this.flags.insert(Flags::FINISHED);
528 }
529
530 this.state.set(State::None);
531 }
532 _ => self
533 .as_mut()
534 .project()
535 .state
536 .set(State::SendPayload { body }),
537 }
538
539 Ok(())
540 }
541
542 fn send_error_response(
543 mut self: Pin<&mut Self>,
544 mut res: Response<()>,
545 body: BoxBody,
546 ) -> Result<(), DispatchError> {
547 let is_upgrade = res.upgrade();
548 let (draining, close_for_unread_payload) = {
549 let this = self.as_mut().project();
550 (
551 this.flags.contains(Flags::DRAINING),
552 !is_upgrade
553 && should_close_for_unread_payload(
554 this.payload.as_ref(),
555 *this.payload_drainable,
556 ),
557 )
558 };
559 let close_after_response = (!is_upgrade && draining) || close_for_unread_payload;
560
561 if close_after_response {
562 res.head_mut().set_connection_type(ConnectionType::Close);
563 }
564
565 let size = self.as_mut().send_response_inner(res, &body)?;
566 match size {
567 BodySize::None | BodySize::Sized(0) => {
568 let mut this = self.as_mut().project();
569
570 if close_for_unread_payload {
571 if this.config.client_disconnect_deadline().is_some() {
572 Self::enter_linger(this.flags);
573 } else {
574 this.flags.insert(Flags::SHUTDOWN | Flags::FINISHED);
575 }
576 } else {
577 this.flags.insert(Flags::FINISHED);
578 }
579
580 this.state.set(State::None);
581 }
582 _ => self
583 .as_mut()
584 .project()
585 .state
586 .set(State::SendErrorPayload { body }),
587 }
588
589 Ok(())
590 }
591
592 fn send_continue(self: Pin<&mut Self>) {
593 self.project()
594 .write_buf
595 .extend_from_slice(b"HTTP/1.1 100 Continue\r\n\r\n");
596 }
597
598 fn poll_response(
599 mut self: Pin<&mut Self>,
600 cx: &mut Context<'_>,
601 ) -> Result<PollResponse, DispatchError> {
602 'res: loop {
603 let mut this = self.as_mut().project();
604 match this.state.as_mut().project() {
605 StateProj::None if this.flags.contains(Flags::DRAINING) => {
606 this.messages.clear();
607 this.flags.remove(Flags::KEEP_ALIVE);
608
609 if !this.flags.contains(Flags::LINGER) {
610 this.flags.insert(Flags::SHUTDOWN);
611 }
612
613 return Ok(PollResponse::DoNothing);
614 }
615
616 StateProj::None => match this.messages.pop_front() {
618 Some(DispatcherMessage::Item(req)) => {
620 if req.head().expect() {
622 let fut = this.flow.expect.call(req);
624 this.state.set(State::ExpectCall { fut });
625 } else {
626 let fut = this.flow.service.call(req);
628 this.state.set(State::ServiceCall { fut });
629 };
630 }
631
632 Some(DispatcherMessage::Error(res)) => {
634 self.as_mut().send_error_response(res, BoxBody::new(()))?;
638 }
639
640 Some(DispatcherMessage::Upgrade(req)) => return Ok(PollResponse::Upgrade(req)),
642
643 None => {
645 this.flags.set(
647 Flags::KEEP_ALIVE,
648 this.payload.is_none() && this.codec.keep_alive(),
649 );
650
651 return Ok(PollResponse::DoNothing);
652 }
653 },
654
655 StateProj::ServiceCall { fut } => {
656 match fut.poll(cx) {
657 Poll::Ready(Ok(res)) => {
659 let (res, body) = res.into().replace_body(());
660 self.as_mut().send_response(res, body)?;
661 }
662
663 Poll::Ready(Err(err)) => {
665 let res: Response<BoxBody> = err.into();
666 let (res, body) = res.replace_body(());
667 self.as_mut().send_error_response(res, body)?;
668 }
669
670 Poll::Pending => {
673 if !self.as_mut().poll_request(cx)? {
676 return Ok(PollResponse::DoNothing);
677 }
678 }
680 }
681 }
682
683 StateProj::SendPayload { mut body } => {
684 while this.write_buf.len() < *this.h1_write_buffer_size {
687 match body.as_mut().poll_next(cx) {
688 Poll::Ready(Some(Ok(item))) => {
689 this.codec
690 .encode(Message::Chunk(Some(item)), this.write_buf)?;
691 }
692
693 Poll::Ready(None) => {
694 this.codec.encode(Message::Chunk(None), this.write_buf)?;
695
696 let close_for_unread_payload = should_close_for_unread_payload(
701 this.payload.as_ref(),
702 *this.payload_drainable,
703 );
704 let not_pipelined = this.messages.is_empty();
705
706 this.state.set(State::None);
709
710 if not_pipelined && close_for_unread_payload {
711 if this.config.client_disconnect_deadline().is_some() {
712 Self::enter_linger(this.flags);
713 } else {
714 this.flags.insert(Flags::SHUTDOWN | Flags::FINISHED);
715 }
716 } else {
717 this.flags.insert(Flags::FINISHED);
718 }
719
720 continue 'res;
721 }
722
723 Poll::Ready(Some(Err(err))) => {
724 let err = err.into();
725 tracing::error!("Response payload stream error: {err:?}");
726 this.flags.insert(Flags::FINISHED);
727 return Err(DispatchError::Body(err));
728 }
729
730 Poll::Pending => return Ok(PollResponse::DoNothing),
731 }
732 }
733
734 return Ok(PollResponse::DrainWriteBuf);
737 }
738
739 StateProj::SendErrorPayload { mut body } => {
740 while this.write_buf.len() < *this.h1_write_buffer_size {
745 match body.as_mut().poll_next(cx) {
746 Poll::Ready(Some(Ok(item))) => {
747 this.codec
748 .encode(Message::Chunk(Some(item)), this.write_buf)?;
749 }
750
751 Poll::Ready(None) => {
752 this.codec.encode(Message::Chunk(None), this.write_buf)?;
753
754 let close_for_unread_payload = should_close_for_unread_payload(
759 this.payload.as_ref(),
760 *this.payload_drainable,
761 );
762 let not_pipelined = this.messages.is_empty();
763
764 this.state.set(State::None);
767
768 if not_pipelined && close_for_unread_payload {
769 if this.config.client_disconnect_deadline().is_some() {
770 Self::enter_linger(this.flags);
771 } else {
772 this.flags.insert(Flags::SHUTDOWN | Flags::FINISHED);
773 }
774 } else {
775 this.flags.insert(Flags::FINISHED);
776 }
777
778 continue 'res;
779 }
780
781 Poll::Ready(Some(Err(err))) => {
782 tracing::error!("Response payload stream error: {err:?}");
783 this.flags.insert(Flags::FINISHED);
784 return Err(DispatchError::Body(
785 Error::new_body().with_cause(err).into(),
786 ));
787 }
788
789 Poll::Pending => return Ok(PollResponse::DoNothing),
790 }
791 }
792
793 return Ok(PollResponse::DrainWriteBuf);
796 }
797
798 StateProj::ExpectCall { fut } => {
799 trace!(" calling expect service");
800
801 match fut.poll(cx) {
802 Poll::Ready(Ok(req)) => {
805 this.write_buf
806 .extend_from_slice(b"HTTP/1.1 100 Continue\r\n\r\n");
807 let fut = this.flow.service.call(req);
808 this.state.set(State::ServiceCall { fut });
809 }
810
811 Poll::Ready(Err(err)) => {
813 let res: Response<BoxBody> = err.into();
814 let (res, body) = res.replace_body(());
815 self.as_mut().send_error_response(res, body)?;
816 }
817
818 Poll::Pending => return Ok(PollResponse::DoNothing),
820 }
821 }
822 }
823 }
824 }
825
826 fn handle_request(
827 mut self: Pin<&mut Self>,
828 req: Request,
829 cx: &mut Context<'_>,
830 ) -> Result<(), DispatchError> {
831 {
833 let mut this = self.as_mut().project();
834
835 if req.head().expect() {
837 let fut = this.flow.expect.call(req);
839 this.state.set(State::ExpectCall { fut });
840 } else {
841 let fut = this.flow.service.call(req);
843 this.state.set(State::ServiceCall { fut });
844 };
845 };
846
847 loop {
849 match self.as_mut().project().state.project() {
850 StateProj::ExpectCall { fut } => {
851 match fut.poll(cx) {
852 Poll::Ready(Ok(req)) => {
854 self.as_mut().send_continue();
855
856 let mut this = self.as_mut().project();
857 let fut = this.flow.service.call(req);
858 this.state.set(State::ServiceCall { fut });
859
860 continue;
861 }
862
863 Poll::Ready(Err(err)) => {
867 let res: Response<BoxBody> = err.into();
868 let (res, body) = res.replace_body(());
869 return self.send_error_response(res, body);
870 }
871
872 Poll::Pending => return Ok(()),
875 }
876 }
877
878 StateProj::ServiceCall { fut } => {
879 return match fut.poll(cx) {
881 Poll::Ready(Ok(res)) => {
885 let (res, body) = res.into().replace_body(());
886 self.as_mut().send_response(res, body)
887 }
888
889 Poll::Pending => Ok(()),
891
892 Poll::Ready(Err(err)) => {
894 let res: Response<BoxBody> = err.into();
895 let (res, body) = res.replace_body(());
896 self.as_mut().send_error_response(res, body)
897 }
898 };
899 }
900
901 _ => {
902 unreachable!("State must be set to ServiceCall or ExceptCall in handle_request")
903 }
904 }
905 }
906 }
907
908 fn poll_request(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Result<bool, DispatchError> {
912 if self.flags.contains(Flags::DRAINING) && self.state.is_none() {
913 return Ok(false);
914 }
915
916 let pipeline_queue_full = self.messages.len() >= MAX_PIPELINED_MESSAGES;
917 let can_not_read = !self.can_read(cx);
918
919 if pipeline_queue_full || can_not_read {
921 return Ok(false);
922 }
923
924 let mut this = self.as_mut().project();
925
926 let mut updated = false;
927
928 loop {
930 match this.codec.decode(this.read_buf) {
931 Ok(Some(msg)) => {
932 updated = true;
933
934 match msg {
935 Message::Item(mut req) => {
936 this.head_timer.clear(line!());
938
939 req.head_mut().peer_addr = *this.peer_addr;
940
941 req.conn_data.clone_from(this.conn_data);
942
943 match this.codec.message_type() {
944 MessageType::None => *this.payload_drainable = false,
946
947 MessageType::Stream if this.flow.upgrade.is_some() => {
951 *this.payload_drainable = false;
952 this.messages.push_back(DispatcherMessage::Upgrade(req));
953 break;
954 }
955
956 MessageType::Payload | MessageType::Stream => {
958 let (sender, payload) = Payload::create(false);
964 *req.payload() = crate::Payload::H1 { payload };
965 *this.payload = Some(sender);
966 *this.payload_drainable = req.chunked().unwrap_or(false);
967 }
968 }
969
970 if this.state.is_none() {
972 self.as_mut().handle_request(req, cx)?;
973 this = self.as_mut().project();
974 } else {
975 this.messages.push_back(DispatcherMessage::Item(req));
976 }
977 }
978
979 Message::Chunk(Some(chunk)) => {
980 if let Some(ref mut payload) = this.payload {
981 payload.feed_data(chunk);
982 } else {
983 error!("Internal server error: unexpected payload chunk");
984 this.flags.insert(Flags::READ_DISCONNECT);
985 this.messages.push_back(DispatcherMessage::Error(
986 Response::internal_server_error().drop_body(),
987 ));
988 *this.error = Some(DispatchError::InternalError);
989 break;
990 }
991 }
992
993 Message::Chunk(None) => {
994 if let Some(mut payload) = this.payload.take() {
995 payload.feed_eof();
996 *this.payload_drainable = false;
997 } else {
998 error!("Internal server error: unexpected eof");
999 this.flags.insert(Flags::READ_DISCONNECT);
1000 this.messages.push_back(DispatcherMessage::Error(
1001 Response::internal_server_error().drop_body(),
1002 ));
1003 *this.error = Some(DispatchError::InternalError);
1004 break;
1005 }
1006 }
1007 }
1008 }
1009
1010 Ok(None) => break,
1013
1014 Err(ParseError::Io(err)) => {
1015 trace!("I/O error: {}", &err);
1016 self.as_mut().client_disconnected();
1017 this = self.as_mut().project();
1018 *this.error = Some(DispatchError::Io(err));
1019 break;
1020 }
1021
1022 Err(ParseError::TooLarge) => {
1023 trace!("request head was too big; returning 431 response");
1024
1025 if let Some(mut payload) = this.payload.take() {
1026 payload.set_error(PayloadError::Overflow);
1027 }
1028
1029 this.messages
1031 .push_back(DispatcherMessage::Error(Response::with_body(
1032 StatusCode::REQUEST_HEADER_FIELDS_TOO_LARGE,
1033 (),
1034 )));
1035
1036 this.flags.insert(Flags::READ_DISCONNECT);
1037 *this.error = Some(ParseError::TooLarge.into());
1038
1039 break;
1040 }
1041
1042 Err(err) => {
1043 trace!("parse error {}", &err);
1044
1045 if let Some(mut payload) = this.payload.take() {
1046 payload.set_error(PayloadError::EncodingCorrupted);
1047 }
1048
1049 this.messages.push_back(DispatcherMessage::Error(
1051 Response::bad_request().drop_body(),
1052 ));
1053
1054 this.flags.insert(Flags::READ_DISCONNECT);
1055 *this.error = Some(err.into());
1056 break;
1057 }
1058 }
1059 }
1060
1061 Ok(updated)
1062 }
1063
1064 fn poll_head_timer(
1065 mut self: Pin<&mut Self>,
1066 cx: &mut Context<'_>,
1067 ) -> Result<(), DispatchError> {
1068 let this = self.as_mut().project();
1069
1070 if let TimerState::Active { timer } = this.head_timer {
1071 if timer.as_mut().poll(cx).is_ready() {
1072 trace!("timed out on slow request; replying with 408 and closing connection");
1075
1076 let _ = self.as_mut().send_error_response(
1077 Response::with_body(StatusCode::REQUEST_TIMEOUT, ()),
1078 BoxBody::new(()),
1079 );
1080
1081 self.project().flags.insert(Flags::SHUTDOWN);
1082 }
1083 };
1084
1085 Ok(())
1086 }
1087
1088 fn poll_ka_timer(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Result<(), DispatchError> {
1089 let this = self.as_mut().project();
1090 if let TimerState::Active { timer } = this.ka_timer {
1091 debug_assert!(
1092 this.flags.contains(Flags::KEEP_ALIVE),
1093 "keep-alive flag should be set when timer is active",
1094 );
1095 debug_assert!(
1096 this.state.is_none(),
1097 "dispatcher should not be in keep-alive phase if state is not none: {:?}",
1098 this.state,
1099 );
1100
1101 if timer.as_mut().poll(cx).is_ready() {
1113 trace!("timer timed out; closing connection");
1115 this.flags.insert(Flags::SHUTDOWN);
1116
1117 if let Some(deadline) = this.config.client_disconnect_deadline() {
1118 this.shutdown_timer
1120 .set_and_init(cx, sleep_until(deadline.into()), line!());
1121 } else {
1122 this.flags.insert(Flags::WRITE_DISCONNECT);
1124 }
1125 }
1126 }
1127
1128 Ok(())
1129 }
1130
1131 fn poll_shutdown_timer(
1132 mut self: Pin<&mut Self>,
1133 cx: &mut Context<'_>,
1134 ) -> Result<(), DispatchError> {
1135 let this = self.as_mut().project();
1136 if let TimerState::Active { timer } = this.shutdown_timer {
1137 debug_assert!(
1138 this.flags.intersects(Flags::LINGER | Flags::SHUTDOWN),
1139 "shutdown or linger flag should be set when timer is active",
1140 );
1141
1142 if timer.as_mut().poll(cx).is_ready() {
1143 if this.flags.contains(Flags::LINGER) {
1144 trace!("timed-out during linger; shutting down connection");
1145 this.flags.remove(Flags::LINGER);
1146 this.flags.insert(Flags::SHUTDOWN);
1147 this.shutdown_timer.clear(line!());
1148 } else {
1149 trace!("timed-out during shutdown");
1150 return Err(DispatchError::DisconnectTimeout);
1151 }
1152 }
1153 }
1154
1155 Ok(())
1156 }
1157
1158 fn poll_graceful_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) {
1159 let this = self.as_mut().project();
1160
1161 let notified = this
1162 .graceful_shutdown
1163 .as_mut()
1164 .is_some_and(|signal| signal.as_mut().poll(cx).is_ready());
1165
1166 if notified {
1167 *this.graceful_shutdown = None;
1168 this.flags.remove(Flags::KEEP_ALIVE);
1169 this.flags.insert(Flags::DRAINING);
1170
1171 if this.ka_timer.is_enabled() {
1172 this.ka_timer.clear(line!());
1173 }
1174 }
1175 }
1176
1177 fn poll_timers(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Result<(), DispatchError> {
1179 self.as_mut().poll_head_timer(cx)?;
1180 self.as_mut().poll_ka_timer(cx)?;
1181 self.as_mut().poll_shutdown_timer(cx)?;
1182
1183 Ok(())
1184 }
1185
1186 #[inline(always)] fn read_available(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Result<bool, DispatchError> {
1193 let this = self.project();
1194
1195 if this.flags.contains(Flags::READ_DISCONNECT) {
1196 return Ok(false);
1197 };
1198
1199 let mut io = Pin::new(this.io.as_mut().unwrap());
1200
1201 let mut read_some = false;
1202
1203 loop {
1204 if this.read_buf.len() >= MAX_BUFFER_SIZE {
1206 match this.payload.as_ref().map(|p| p.need_read(cx)) {
1225 Some(PayloadStatus::Pause) => {}
1227
1228 Some(PayloadStatus::Dropped) | Some(PayloadStatus::Read) | None => {
1230 cx.waker().wake_by_ref()
1231 }
1232 }
1233
1234 return Ok(false);
1235 }
1236
1237 let remaining = this.read_buf.capacity() - this.read_buf.len();
1239 if remaining < LW_BUFFER_SIZE {
1240 this.read_buf.reserve(HW_BUFFER_SIZE - remaining);
1241 }
1242
1243 match tokio_util::io::poll_read_buf(io.as_mut(), cx, this.read_buf) {
1244 Poll::Ready(Ok(n)) => {
1245 if !this.payload.as_ref().is_some_and(|pl| pl.is_dropped()) {
1248 this.flags.remove(Flags::FINISHED);
1249 }
1250
1251 if n == 0 {
1252 return Ok(true);
1253 }
1254
1255 read_some = true;
1256 }
1257
1258 Poll::Pending => {
1259 return Ok(false);
1260 }
1261
1262 Poll::Ready(Err(err)) => {
1263 return match err.kind() {
1264 io::ErrorKind::WouldBlock => Ok(false),
1266
1267 io::ErrorKind::ConnectionReset if read_some => Ok(true),
1269
1270 _ => Err(DispatchError::Io(err)),
1271 };
1272 }
1273 }
1274 }
1275 }
1276
1277 fn upgrade(self: Pin<&mut Self>, req: Request) -> U::Future {
1279 let this = self.project();
1280 let mut parts = FramedParts::with_read_buf(
1281 this.io.take().unwrap(),
1282 mem::take(this.codec),
1283 mem::take(this.read_buf),
1284 );
1285 parts.write_buf = mem::take(this.write_buf);
1286 let framed = Framed::from_parts(parts);
1287 this.flow.upgrade.as_ref().unwrap().call((req, framed))
1288 }
1289}
1290
1291impl<T, S, B, X, U> Future for Dispatcher<T, S, B, X, U>
1292where
1293 T: AsyncRead + AsyncWrite + Unpin,
1294
1295 S: Service<Request>,
1296 S::Error: Into<Response<BoxBody>>,
1297 S::Response: Into<Response<B>>,
1298
1299 B: MessageBody,
1300
1301 X: Service<Request, Response = Request>,
1302 X::Error: Into<Response<BoxBody>>,
1303
1304 U: Service<(Request, Framed<T, Codec>), Response = ()>,
1305 U::Error: fmt::Display,
1306{
1307 type Output = Result<(), DispatchError>;
1308
1309 #[inline]
1310 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
1311 let this = self.as_mut().project();
1312
1313 #[cfg(test)]
1314 {
1315 *this.poll_count += 1;
1316 }
1317
1318 match this.inner.project() {
1319 DispatcherStateProj::Upgrade { fut: upgrade } => upgrade.poll(cx).map_err(|err| {
1320 error!("Upgrade handler error: {}", err);
1321 DispatchError::Upgrade
1322 }),
1323
1324 DispatcherStateProj::Normal { mut inner } => {
1325 trace!("start flags: {:?}", &inner.flags);
1326
1327 trace_timer_states(
1328 "start",
1329 &inner.head_timer,
1330 &inner.ka_timer,
1331 &inner.shutdown_timer,
1332 );
1333
1334 inner.as_mut().poll_graceful_shutdown(cx);
1335 inner.as_mut().poll_timers(cx)?;
1336
1337 let poll = if inner.flags.contains(Flags::LINGER) {
1338 match inner.as_mut().poll_linger(cx)? {
1339 Poll::Ready(()) => {
1340 cx.waker().wake_by_ref();
1341 Poll::Pending
1342 }
1343 Poll::Pending => Poll::Pending,
1344 }
1345 } else if inner.flags.contains(Flags::SHUTDOWN) {
1346 if inner.flags.contains(Flags::WRITE_DISCONNECT) {
1347 Poll::Ready(Ok(()))
1348 } else {
1349 ready!(inner.as_mut().poll_flush(cx))?;
1351 Pin::new(inner.as_mut().project().io.as_mut().unwrap())
1352 .poll_shutdown(cx)
1353 .map_err(DispatchError::from)
1354 }
1355 } else {
1356 let should_disconnect = inner.as_mut().read_available(cx)?;
1358
1359 if !inner.read_buf.is_empty() && inner.flags.contains(Flags::KEEP_ALIVE) {
1361 let inner = inner.as_mut().project();
1362 inner.flags.remove(Flags::KEEP_ALIVE);
1363 inner.ka_timer.clear(line!());
1364 }
1365
1366 if !inner.flags.contains(Flags::STARTED) {
1367 inner.as_mut().project().flags.insert(Flags::STARTED);
1368
1369 if let Some(deadline) = inner.config.client_request_deadline() {
1370 inner.as_mut().project().head_timer.set_and_init(
1371 cx,
1372 sleep_until(deadline.into()),
1373 line!(),
1374 );
1375 }
1376 }
1377
1378 inner.as_mut().poll_request(cx)?;
1379
1380 if should_disconnect {
1381 let inner = inner.as_mut().project();
1383 inner.flags.insert(Flags::READ_DISCONNECT);
1384 if let Some(mut payload) = inner.payload.take() {
1385 payload.set_error(PayloadError::Incomplete(None));
1386 payload.feed_eof();
1387 }
1388 };
1389
1390 loop {
1391 let drain = match inner.as_mut().poll_response(cx)? {
1394 PollResponse::DrainWriteBuf => true,
1395
1396 PollResponse::DoNothing => {
1397 if inner.flags.contains(Flags::KEEP_ALIVE | Flags::FINISHED) {
1400 if let Some(timer) = inner.config.keep_alive_deadline() {
1401 inner.as_mut().project().ka_timer.set_and_init(
1402 cx,
1403 sleep_until(timer.into()),
1404 line!(),
1405 );
1406 }
1407 }
1408
1409 false
1410 }
1411
1412 PollResponse::Upgrade(req) => {
1414 let upgrade = inner.upgrade(req);
1415 self.as_mut()
1416 .project()
1417 .inner
1418 .set(DispatcherState::Upgrade { fut: upgrade });
1419 return self.poll(cx);
1420 }
1421 };
1422
1423 let flush_was_ready = inner.as_mut().poll_flush(cx)?.is_ready();
1430
1431 if !flush_was_ready || !drain {
1436 break;
1437 }
1438 }
1439
1440 if inner.flags.contains(Flags::WRITE_DISCONNECT) {
1442 trace!("client is gone; disconnecting");
1443 return Poll::Ready(Ok(()));
1444 }
1445
1446 let inner_p = inner.as_mut().project();
1447 let state_is_none = inner_p.state.is_none();
1448
1449 if inner_p.flags.contains(Flags::READ_DISCONNECT)
1457 && (!inner_p.config.h1_allow_half_closed() || state_is_none)
1458 {
1459 trace!("read half closed; start shutdown");
1460 inner_p.flags.insert(Flags::SHUTDOWN);
1461 }
1462
1463 if state_is_none && inner_p.write_buf.is_empty() {
1465 if let Some(err) = inner_p.error.take() {
1466 error!("stream error: {}", &err);
1467 return Poll::Ready(Err(err));
1468 }
1469
1470 if inner_p.flags.contains(Flags::FINISHED)
1472 && !inner_p.flags.contains(Flags::KEEP_ALIVE)
1473 && inner_p.payload.is_none()
1474 {
1475 inner_p.flags.remove(Flags::FINISHED);
1476 inner_p.flags.insert(Flags::SHUTDOWN);
1477 return self.poll(cx);
1478 }
1479
1480 if inner_p.flags.contains(Flags::SHUTDOWN) {
1482 return self.poll(cx);
1483 }
1484 }
1485
1486 trace_timer_states(
1487 "end",
1488 inner_p.head_timer,
1489 inner_p.ka_timer,
1490 inner_p.shutdown_timer,
1491 );
1492
1493 if inner_p.flags.intersects(Flags::LINGER | Flags::SHUTDOWN) {
1494 cx.waker().wake_by_ref();
1495 }
1496 Poll::Pending
1497 };
1498
1499 trace!("end flags: {:?}", &inner.flags);
1500
1501 poll
1502 }
1503 }
1504 }
1505}
1506
1507fn should_close_for_unread_payload(
1508 payload: Option<&PayloadSender>,
1509 payload_drainable: bool,
1510) -> bool {
1511 let payload_unfinished = payload.is_some();
1512 let drain_payload = payload.is_some_and(|pl| pl.is_dropped()) && payload_drainable;
1513
1514 payload_unfinished && !drain_payload
1515}
1516
1517#[allow(dead_code)]
1518fn trace_timer_states(
1519 label: &str,
1520 head_timer: &TimerState,
1521 ka_timer: &TimerState,
1522 shutdown_timer: &TimerState,
1523) {
1524 trace!("{} timers:", label);
1525
1526 if head_timer.is_enabled() {
1527 trace!(" head {}", &head_timer);
1528 }
1529
1530 if ka_timer.is_enabled() {
1531 trace!(" keep-alive {}", &ka_timer);
1532 }
1533
1534 if shutdown_timer.is_enabled() {
1535 trace!(" shutdown {}", &shutdown_timer);
1536 }
1537}
1538
1539#[cfg(test)]
1540#[path = "dispatcher_tests.rs"]
1541mod dispatcher_tests;
1542
1543#[cfg(test)]
1544#[path = "dispatcher_buffer_tests.rs"]
1545mod buffer_tests;