From d08cf602cc3d70d0c75cee1cea49325b7a595acd Mon Sep 17 00:00:00 2001
From: Sean McArthur <sean@seanmonstar.com>
Date: Wed, 15 Nov 2023 08:51:41 -0500
Subject: [PATCH] feat(lib): update to `http` 1.0

Updates dependencies `http` and `http-body` to 1.0.

To do so, implements `Clone` for `OnUpgrade`.

BREAKING CHANGE: Upgrade to `http` 1.0.
---
 Cargo.toml            | 10 +++++-----
 src/ffi/http_types.rs |  1 +
 src/upgrade.rs        | 27 +++++++++++++++++++--------
 3 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 1de8e682b8..ebd92d7780 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -23,15 +23,15 @@ include = [
 bytes = "1"
 futures-channel = "0.3"
 futures-util = { version = "0.3", default-features = false }
-http = "0.2.7"
-http-body = "=1.0.0-rc.2"
+http = "1"
+http-body = "1"
 pin-project-lite = "0.2.4"
 tokio = { version = "1.13", features = ["sync"] }
 
 # Optional
 
-h2 = { version = "0.3.9", optional = true }
-http-body-util = { version = "=0.1.0-rc.3", optional = true }
+h2 = { version = "0.4", optional = true }
+http-body-util = { version = "0.1", optional = true }
 httparse = { version = "1.8", optional = true }
 httpdate = { version = "1.0", optional = true }
 itoa = { version = "1", optional = true }
@@ -41,7 +41,7 @@ want = { version = "0.3", optional = true }
 
 [dev-dependencies]
 form_urlencoded = "1"
-http-body-util = "=0.1.0-rc.3"
+http-body-util = "0.1"
 pretty_env_logger = "0.5"
 spmc = "0.3"
 serde = { version = "1.0", features = ["derive"] }
diff --git a/src/ffi/http_types.rs b/src/ffi/http_types.rs
index 565ab095ce..beeba608d7 100644
--- a/src/ffi/http_types.rs
+++ b/src/ffi/http_types.rs
@@ -20,6 +20,7 @@ pub struct hyper_response(pub(super) Response<IncomingBody>);
 /// An HTTP header map.
 ///
 /// These can be part of a request or response.
+#[derive(Clone)]
 pub struct hyper_headers {
     pub(super) headers: HeaderMap,
     orig_casing: HeaderCaseMap,
diff --git a/src/upgrade.rs b/src/upgrade.rs
index 6b7039f076..3b7735c56d 100644
--- a/src/upgrade.rs
+++ b/src/upgrade.rs
@@ -46,6 +46,7 @@ use std::future::Future;
 use std::io;
 use std::marker::Unpin;
 use std::pin::Pin;
+use std::sync::{Arc, Mutex};
 use std::task::{Context, Poll};
 
 use crate::rt::{Read, ReadBufCursor, Write};
@@ -69,8 +70,9 @@ pub struct Upgraded {
 /// A future for a possible HTTP upgrade.
 ///
 /// If no upgrade was available, or it doesn't succeed, yields an `Error`.
+#[derive(Clone)]
 pub struct OnUpgrade {
-    rx: Option<oneshot::Receiver<crate::Result<Upgraded>>>,
+    rx: Option<Arc<Mutex<oneshot::Receiver<crate::Result<Upgraded>>>>>,
 }
 
 /// The deconstructed parts of an [`Upgraded`] type.
@@ -119,7 +121,12 @@ pub(super) struct Pending {
 ))]
 pub(super) fn pending() -> (Pending, OnUpgrade) {
     let (tx, rx) = oneshot::channel();
-    (Pending { tx }, OnUpgrade { rx: Some(rx) })
+    (
+        Pending { tx },
+        OnUpgrade {
+            rx: Some(Arc::new(Mutex::new(rx))),
+        },
+    )
 }
 
 // ===== impl Upgraded =====
@@ -219,13 +226,17 @@ impl OnUpgrade {
 impl Future for OnUpgrade {
     type Output = Result<Upgraded, crate::Error>;
 
-    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         match self.rx {
-            Some(ref mut rx) => Pin::new(rx).poll(cx).map(|res| match res {
-                Ok(Ok(upgraded)) => Ok(upgraded),
-                Ok(Err(err)) => Err(err),
-                Err(_oneshot_canceled) => Err(crate::Error::new_canceled().with(UpgradeExpected)),
-            }),
+            Some(ref rx) => Pin::new(&mut *rx.lock().unwrap())
+                .poll(cx)
+                .map(|res| match res {
+                    Ok(Ok(upgraded)) => Ok(upgraded),
+                    Ok(Err(err)) => Err(err),
+                    Err(_oneshot_canceled) => {
+                        Err(crate::Error::new_canceled().with(UpgradeExpected))
+                    }
+                }),
             None => Poll::Ready(Err(crate::Error::new_user_no_upgrade())),
         }
     }