From 8ff489aa90d70cdf8cecee0873f736c3e38f3521 Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 24 Jul 2022 16:35:00 +0100 Subject: [PATCH] apply fix from #2369 --- actix-http/CHANGES.md | 12 ++++++++---- actix-http/src/h1/dispatcher.rs | 11 +++++++---- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index 7e6604046..785a1b13f 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -1,6 +1,10 @@ # Changes ## Unreleased - 2022-xx-xx +### Fixed +- Avoid possibility of dispatcher getting stuck while back-pressuring I/O. [#2369] + +[#2369]: https://github.com/actix/actix-web/pull/2369 ## 3.2.1 - 2022-07-02 @@ -29,9 +33,9 @@ ### Fixed - Revert broken fix in [#2624] that caused erroneous 500 error responses. Temporarily re-introduces [#2357] bug. [#2779] +[#2624]: https://github.com/actix/actix-web/pull/2624 [#2357]: https://github.com/actix/actix-web/issues/2357 -[#2624]: https://github.com/actix/actix-web/issues/2624 -[#2779]: https://github.com/actix/actix-web/issues/2779 +[#2779]: https://github.com/actix/actix-web/pull/2779 ## 3.0.4 - 2022-03-09 @@ -43,14 +47,14 @@ ### Fixed - Allow spaces between header name and colon when parsing responses. [#2684] -[#2684]: https://github.com/actix/actix-web/issues/2684 +[#2684]: https://github.com/actix/actix-web/pull/2684 ## 3.0.2 - 2022-03-05 ### Fixed - Fix encoding camel-case header names with more than one hyphen. [#2683] -[#2683]: https://github.com/actix/actix-web/issues/2683 +[#2683]: https://github.com/actix/actix-web/pull/2683 ## 3.0.1 - 2022-03-04 diff --git a/actix-http/src/h1/dispatcher.rs b/actix-http/src/h1/dispatcher.rs index c2ddc06ba..81090667d 100644 --- a/actix-http/src/h1/dispatcher.rs +++ b/actix-http/src/h1/dispatcher.rs @@ -976,9 +976,11 @@ where // // A Request head too large to parse is only checked on `httparse::Status::Partial`. - if this.payload.is_none() { - // When dispatcher has a payload the responsibility of wake up it would be shift - // to h1::payload::Payload. + match this.payload { + // When dispatcher has a payload the responsibility of wake ups is shifted to + // `h1::payload::Payload` unless the payload is needing a read, in which case it + // might not have access to the waker and could result in the dispatcher + // getting stuck until timeout. // // Reason: // Self wake up when there is payload would waste poll and/or result in @@ -989,7 +991,8 @@ where // read anymore. At this case read_buf could always remain beyond // MAX_BUFFER_SIZE and self wake up would be busy poll dispatcher and // waste resources. - cx.waker().wake_by_ref(); + Some(ref p) if p.need_read(cx) != PayloadStatus::Read => {} + _ => cx.waker().wake_by_ref(), } return Ok(false);