can't upgrade request that came in with `Connection: close, Upgrade`
Maintainer thường phản hồi trong vòng 1 ngày
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 62/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- rust
- Lĩnh vực
- networking
Hướng nghiên cứu
Start with the linked src/proto/h1/conn.rs code that rewrites the response Connection header, then run the issue's gist or add a focused test that exercises a request with Connection: close, Upgrade. Trace how requested connection options are merged into the 101 response and make the upgrade response emit only upgrade for both request forms. Done means the sample prints Connection: ["upgrade"] for both Upgrade and close, Upgrade requests.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Version
hyper 1.12.0
Platform
Linux 6.16.3+deb13-amd64
Summary
I'm trying to support a particular WebSocket client (UniFi G6 camera), and the sequence goes as follows:
- Client request comes in with the header
Connection: close, Upgrade. Apparently this means either upgrade or close the connection. (RFC 9110 section 7.6.1 says it's a list of options.) - my hyper application (using axum) attempts to do the upgrade with 101
Connection: Upgrade - hyper replaces the
Connection: UpgradewithConnection: upgrade, close(hyper 1.12.0) orConnection: close(hyper 1.8.1). My AI buddy and I think that because 101 is not a final response, saying close doesn't make sense. https://github.com/hyperium/hyper/blob/7f67699ce32d717081deb7018b4da7d679277ac0/src/proto/h1/conn.rs#L715 - the client logs
2026-10-26T05:34:17+0000 P4 19156,969 avclient[1561]: Internal transfer error occurred: HS: UPGRADE malformed [ubnt_avclient:connection.cpp:SecureTransferProtocolHandler:308]and gives up rather than establishing the websocket. It might be using this code: https://github.com/warmcat/libwebsockets/blob/v3.0.1/lib/roles/ws/client-ws.c#L271 . Apparently newer versions are less picky https://github.com/warmcat/libwebsockets/blob/v3.1.0/lib/roles/ws/client-ws.c#L276 but, you know, the client's running the version it's running.
If I use tokio-tungstenite directly, it sends Connection: Upgrade in response, and the websocket gets set up correctly.
Code Sample
Here's a sample that just shows the request -> response headers with a hyper client and server (removing the camera, axum, and tungstenite). https://gist.github.com/scottlamb/b83ee082af86c306320efb9ae90491b3
use hyper::header::{CONNECTION, HeaderValue, UPGRADE};
use hyper::{Request, Response, StatusCode};
use hyper_util::rt::TokioIo;
async fn upgrade(mut req: Request<hyper::body::Incoming>) -> Result<Response<String>, hyper::Error> {
let on_upgrade = hyper::upgrade::on(&mut req);
tokio::spawn(async move {
let _ = on_upgrade.await;
});
let mut resp = Response::new(String::new());
*resp.status_mut() = StatusCode::SWITCHING_PROTOCOLS;
resp.headers_mut().insert(CONNECTION, HeaderValue::from_static("upgrade"));
resp.headers_mut().insert(UPGRADE, HeaderValue::from_static("foo"));
Ok(resp)
}
async fn try_upgrade(connection: &'static str) -> Vec<HeaderValue> {
let (client_io, server_io) = tokio::io::duplex(4096);
tokio::spawn(
hyper::server::conn::http1::Builder::new()
.serve_connection(TokioIo::new(server_io), hyper::service::service_fn(upgrade))
.with_upgrades(),
);
let (mut sender, conn) = hyper::client::conn::http1::handshake(TokioIo::new(client_io))
.await
.unwrap();
tokio::spawn(conn.with_upgrades());
let req = Request::builder()
.uri("/")
.header("Host", "example.com")
.header(CONNECTION, connection)
.header(UPGRADE, "foo")
.body(String::new())
.unwrap();
let resp = sender.send_request(req).await.unwrap();
assert_eq!(resp.status(), StatusCode::SWITCHING_PROTOCOLS);
resp.headers().get_all(CONNECTION).iter().cloned().collect()
}
#[tokio::main(flavor = "current_thread")]
async fn main() {
for connection in ["Upgrade", "close, Upgrade"] {
println!(
"request Connection: {connection:?} -> response Connection: {:?}",
try_upgrade(connection).await
);
}
}
Expected Behavior
request Connection: "Upgrade" -> response Connection: ["upgrade"]
request Connection: "close, Upgrade" -> response Connection: ["upgrade"]
Actual Behavior
request Connection: "Upgrade" -> response Connection: ["upgrade"]
request Connection: "close, Upgrade" -> response Connection: ["upgrade, close"]
Additional Context
No response
- Ngôn ngữ chính
- Rust
- Star
- 16.4k
- Fork
- 1.8k
- Merge trung bình
- 1 ngày 13 giờ
- Pull request đã merge (30 ngày)
- 12
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của hyperium/hyper
-
Publicly reexport the http crateĐang mởC-feature
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 65/100
hyperium/hyper#2652 · 4 reaction ·
Maintainer thường phản hồi trong vòng 1 ngày
-
C-feature
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
Maintainer thường phản hồi trong vòng 1 ngày
-
False `SendRequest` readiness for HTTP/1 connectionsCó thể đã có người làm @akasakariko đã nhận 3 ngày trước. Đang mởC-bug
Độ khó 4/5 1-2 ngày Mức phù hợp với người mới 55/100
hyperium/hyper#4246 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 48/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 52/100
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của hyperium/hyper
Issue tương tự
-
spurctld: a user with no usage gets a lower fair-share factor than a user with a little usageĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
Maintainer thường phản hồi trong vòng 1 ngày
-
area:ci kind:bug priority:p3 ready
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
Maintainer thường phản hồi trong vòng 1 ngày
-
tech-debt
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
srikanth235/centraid#1155 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
dotfiles: failed batch untrack removes earlier tracking declarationsCó thể đã có người làm @jdx đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 2 ngày