summaryrefslogtreecommitdiff
path: root/ext/http/response_body.rs
diff options
context:
space:
mode:
authorMatt Mastracci <matthew@mastracci.com>2023-05-18 20:10:25 -0600
committerGitHub <noreply@github.com>2023-05-18 20:10:25 -0600
commit2b92efa64501320955979a92de39c70b6734f835 (patch)
tree699473092934d5f221a440c235e9858cce17d5a3 /ext/http/response_body.rs
parent5b0752234993ee69e47c32db478d2a296f73f396 (diff)
feat(ext/http): Add support for trailers w/internal API (HTTP/2 only) (#19182)
Necessary for #3326. Requested in #10214 as well.
Diffstat (limited to 'ext/http/response_body.rs')
-rw-r--r--ext/http/response_body.rs17
1 files changed, 16 insertions, 1 deletions
diff --git a/ext/http/response_body.rs b/ext/http/response_body.rs
index e30c917c3..ea6cc5ab8 100644
--- a/ext/http/response_body.rs
+++ b/ext/http/response_body.rs
@@ -158,7 +158,11 @@ impl std::fmt::Debug for ResponseBytesInner {
/// required by hyper. As the API requires information about request completion (including a success/fail
/// flag), we include a very lightweight [`CompletionHandle`] for interested parties to listen on.
#[derive(Debug, Default)]
-pub struct ResponseBytes(ResponseBytesInner, CompletionHandle);
+pub struct ResponseBytes(
+ ResponseBytesInner,
+ CompletionHandle,
+ Rc<RefCell<Option<HeaderMap>>>,
+);
impl ResponseBytes {
pub fn initialize(&mut self, inner: ResponseBytesInner) {
@@ -170,6 +174,10 @@ impl ResponseBytes {
self.1.clone()
}
+ pub fn trailers(&self) -> Rc<RefCell<Option<HeaderMap>>> {
+ self.2.clone()
+ }
+
fn complete(&mut self, success: bool) -> ResponseBytesInner {
if matches!(self.0, ResponseBytesInner::Done) {
return ResponseBytesInner::Done;
@@ -250,6 +258,9 @@ impl Body for ResponseBytes {
let res = loop {
let res = match &mut self.0 {
ResponseBytesInner::Done | ResponseBytesInner::Empty => {
+ if let Some(trailers) = self.2.borrow_mut().take() {
+ return std::task::Poll::Ready(Some(Ok(Frame::trailers(trailers))));
+ }
unreachable!()
}
ResponseBytesInner::Bytes(..) => {
@@ -271,6 +282,9 @@ impl Body for ResponseBytes {
};
if matches!(res, ResponseStreamResult::EndOfStream) {
+ if let Some(trailers) = self.2.borrow_mut().take() {
+ return std::task::Poll::Ready(Some(Ok(Frame::trailers(trailers))));
+ }
self.complete(true);
}
std::task::Poll::Ready(res.into())
@@ -278,6 +292,7 @@ impl Body for ResponseBytes {
fn is_end_stream(&self) -> bool {
matches!(self.0, ResponseBytesInner::Done | ResponseBytesInner::Empty)
+ && self.2.borrow_mut().is_none()
}
fn size_hint(&self) -> SizeHint {