summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/tests/integration/mod.rs35
-rw-r--r--cli/tests/testdata/websocket_server_multi_field_connection_header_test.ts17
-rw-r--r--ext/http/lib.rs22
3 files changed, 65 insertions, 9 deletions
diff --git a/cli/tests/integration/mod.rs b/cli/tests/integration/mod.rs
index 8448e77e1..7d13c7831 100644
--- a/cli/tests/integration/mod.rs
+++ b/cli/tests/integration/mod.rs
@@ -684,6 +684,41 @@ fn websocketstream() {
assert!(status.success());
}
+#[test]
+fn websocket_server_multi_field_connection_header() {
+ let script = util::testdata_path()
+ .join("websocket_server_multi_field_connection_header_test.ts");
+ let root_ca = util::testdata_path().join("tls/RootCA.pem");
+ let mut child = util::deno_cmd()
+ .arg("run")
+ .arg("--unstable")
+ .arg("--allow-net")
+ .arg("--cert")
+ .arg(root_ca)
+ .arg(script)
+ .stdout(std::process::Stdio::piped())
+ .spawn()
+ .unwrap();
+
+ let stdout = child.stdout.as_mut().unwrap();
+ let mut buffer = [0; 5];
+ let read = stdout.read(&mut buffer).unwrap();
+ assert_eq!(read, 5);
+ let msg = std::str::from_utf8(&buffer).unwrap();
+ assert_eq!(msg, "READY");
+
+ let req = http::request::Builder::new()
+ .header(http::header::CONNECTION, "keep-alive, Upgrade")
+ .uri("ws://localhost:4319")
+ .body(())
+ .unwrap();
+ assert!(
+ deno_runtime::deno_websocket::tokio_tungstenite::tungstenite::connect(req)
+ .is_ok()
+ );
+ assert!(child.wait().unwrap().success());
+}
+
#[cfg(not(windows))]
#[test]
fn set_raw_should_not_panic_on_no_tty() {
diff --git a/cli/tests/testdata/websocket_server_multi_field_connection_header_test.ts b/cli/tests/testdata/websocket_server_multi_field_connection_header_test.ts
new file mode 100644
index 000000000..a662ce9ef
--- /dev/null
+++ b/cli/tests/testdata/websocket_server_multi_field_connection_header_test.ts
@@ -0,0 +1,17 @@
+import { deferred } from "../unit/test_util.ts";
+
+const promise = deferred();
+const listener = Deno.listen({ port: 4319 });
+console.log("READY");
+const conn = await listener.accept();
+const httpConn = Deno.serveHttp(conn);
+const { request, respondWith } = (await httpConn.nextRequest())!;
+const {
+ response,
+ socket,
+} = Deno.upgradeWebSocket(request);
+socket.onerror = () => Deno.exit(1);
+socket.onopen = () => socket.close();
+socket.onclose = () => promise.resolve();
+await respondWith(response);
+await promise;
diff --git a/ext/http/lib.rs b/ext/http/lib.rs
index db55ca53d..38c14409c 100644
--- a/ext/http/lib.rs
+++ b/ext/http/lib.rs
@@ -268,18 +268,22 @@ async fn op_http_request_next(
let is_websocket_request = req
.headers()
- .get(hyper::header::CONNECTION)
- .and_then(|v| {
- v.to_str().ok().map(|s| "Upgrade".eq_ignore_ascii_case(s))
+ .get_all(hyper::header::CONNECTION)
+ .iter()
+ .any(|v| {
+ v.to_str()
+ .map(|s| s.to_lowercase().contains("upgrade"))
+ .unwrap_or(false)
})
- .unwrap_or(false)
&& req
.headers()
- .get(hyper::header::UPGRADE)
- .and_then(|v| {
- v.to_str().ok().map(|s| "websocket".eq_ignore_ascii_case(s))
- })
- .unwrap_or(false);
+ .get_all(hyper::header::UPGRADE)
+ .iter()
+ .any(|v| {
+ v.to_str()
+ .map(|s| s.to_lowercase().contains("websocket"))
+ .unwrap_or(false)
+ });
let has_body = if let Some(exact_size) = req.size_hint().exact() {
exact_size > 0