Update tungstenite

This commit is contained in:
Fabrice Desré 2023-02-25 13:22:47 -08:00 committed by The Capyloon Team
parent bc8cea2495
commit 0d0540fc95
5 changed files with 98 additions and 264 deletions

247
Cargo.lock generated
View file

@ -197,7 +197,7 @@ checksum = "ad445822218ce64be7a341abfb0b1ea43b5c23aa83902542a4542e78309d8e5e"
dependencies = [
"async-stream-impl",
"futures-core",
"pin-project-lite 0.2.8",
"pin-project-lite",
]
[[package]]
@ -213,17 +213,17 @@ dependencies = [
[[package]]
name = "async-tungstenite"
version = "0.9.3"
version = "0.22.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce503a5cb1e7450af7d211b86b84807791b251f335b2f43f1e26b85a416f315"
checksum = "ce01ac37fdc85f10a43c43bc582cbd566720357011578a935761075f898baf58"
dependencies = [
"futures-io",
"futures-util",
"log",
"openssl",
"pin-project",
"tokio 0.2.24",
"tokio-openssl 0.4.0",
"pin-project-lite",
"tokio",
"tokio-openssl",
"tungstenite",
]
@ -392,15 +392,6 @@ dependencies = [
"generic-array 0.12.4",
]
[[package]]
name = "block-buffer"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
dependencies = [
"generic-array 0.14.4",
]
[[package]]
name = "block-buffer"
version = "0.10.2"
@ -575,12 +566,6 @@ dependencies = [
"iovec",
]
[[package]]
name = "bytes"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
[[package]]
name = "bytes"
version = "1.1.0"
@ -1066,12 +1051,6 @@ dependencies = [
"libc",
]
[[package]]
name = "cpuid-bool"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634"
[[package]]
name = "crc32fast"
version = "1.3.2"
@ -1262,6 +1241,12 @@ dependencies = [
"syn",
]
[[package]]
name = "data-encoding"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23d8666cb01533c39dde32bcbab8e227b4ed6679b2c925eba05feabea39508fb"
[[package]]
name = "data-url"
version = "0.1.1"
@ -1386,15 +1371,6 @@ dependencies = [
"generic-array 0.12.4",
]
[[package]]
name = "digest"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
dependencies = [
"generic-array 0.14.4",
]
[[package]]
name = "digest"
version = "0.10.6"
@ -1897,7 +1873,7 @@ dependencies = [
"futures-sink",
"futures-task",
"memchr",
"pin-project-lite 0.2.8",
"pin-project-lite",
"pin-utils",
"slab",
]
@ -2587,7 +2563,7 @@ dependencies = [
"http",
"indexmap",
"slab",
"tokio 1.25.0",
"tokio",
"tokio-util",
"tracing",
]
@ -2648,7 +2624,7 @@ dependencies = [
"http",
"httpdate",
"mime",
"sha-1 0.10.0",
"sha-1 0.10.1",
]
[[package]]
@ -2723,7 +2699,7 @@ checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6"
dependencies = [
"bytes 1.1.0",
"http",
"pin-project-lite 0.2.8",
"pin-project-lite",
]
[[package]]
@ -2760,9 +2736,9 @@ dependencies = [
"httparse",
"httpdate",
"itoa 1.0.1",
"pin-project-lite 0.2.8",
"pin-project-lite",
"socket2",
"tokio 1.25.0",
"tokio",
"tower-service",
"tracing",
"want",
@ -2781,8 +2757,8 @@ dependencies = [
"openssl",
"openssl-sys",
"parking_lot 0.12.0",
"tokio 1.25.0",
"tokio-openssl 0.6.3",
"tokio",
"tokio-openssl",
"tower-layer",
]
@ -2877,15 +2853,6 @@ version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67f0347836f3f6362c1e7efdadde2b1c4b4556d211310b70631bae7eb692070b"
[[package]]
name = "input_buffer"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19a8a95243d5a0398cae618ec29477c6e3cb631152be5c19481f80bc71559754"
dependencies = [
"bytes 0.5.6",
]
[[package]]
name = "instant"
version = "0.1.12"
@ -3526,7 +3493,7 @@ dependencies = [
"string_cache",
"thin-slice",
"time 0.1.45",
"tokio 1.25.0",
"tokio",
"url",
"uuid",
"void",
@ -3881,24 +3848,6 @@ dependencies = [
"getrandom 0.2.8",
]
[[package]]
name = "native-tls"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd7e2f3618557f980e0b17e8856252eee3c97fa12c54dff0ca290fb6266ca4a9"
dependencies = [
"lazy_static",
"libc",
"log",
"openssl",
"openssl-probe",
"openssl-sys",
"schannel",
"security-framework",
"security-framework-sys",
"tempfile",
]
[[package]]
name = "ndk"
version = "0.7.0"
@ -3978,9 +3927,8 @@ dependencies = [
"sha2",
"std_test_override",
"time 0.1.45",
"tokio 0.2.24",
"tokio 1.25.0",
"tokio-openssl 0.6.3",
"tokio",
"tokio-openssl",
"tokio-stream",
"tokio-test",
"tungstenite",
@ -4295,12 +4243,6 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
[[package]]
name = "opaque-debug"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "openssl"
version = "0.10.50"
@ -4327,12 +4269,6 @@ dependencies = [
"syn",
]
[[package]]
name = "openssl-probe"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
[[package]]
name = "openssl-sys"
version = "0.9.85"
@ -4662,12 +4598,6 @@ dependencies = [
"syn",
]
[[package]]
name = "pin-project-lite"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b"
[[package]]
name = "pin-project-lite"
version = "0.2.8"
@ -5159,15 +5089,6 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "schannel"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3"
dependencies = [
"windows-sys 0.42.0",
]
[[package]]
name = "scoped-tls"
version = "1.0.1"
@ -5386,29 +5307,6 @@ dependencies = [
"tiny-skia",
]
[[package]]
name = "security-framework"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1759c2e3c8580017a484a7ac56d3abc5a6c1feadf88db2f3633f12ae4268c69"
dependencies = [
"bitflags",
"core-foundation 0.9.3",
"core-foundation-sys 0.8.3",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f99b9d5e26d2a71633cc4f2ebae7cc9f874044e0c351a27e17892d76dce5678b"
dependencies = [
"core-foundation-sys 0.8.3",
"libc",
]
[[package]]
name = "selectors"
version = "0.24.0"
@ -5847,27 +5745,25 @@ dependencies = [
"block-buffer 0.7.3",
"digest 0.8.1",
"fake-simd",
"opaque-debug 0.2.3",
"opaque-debug",
]
[[package]]
name = "sha-1"
version = "0.9.1"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "170a36ea86c864a3f16dd2687712dd6646f7019f301e57537c7f4dc9f5916770"
checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c"
dependencies = [
"block-buffer 0.9.0",
"cfg-if 0.1.10",
"cpuid-bool",
"digest 0.9.0",
"opaque-debug 0.3.0",
"cfg-if 1.0.0",
"cpufeatures",
"digest 0.10.6",
]
[[package]]
name = "sha-1"
version = "0.10.0"
name = "sha1"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3"
dependencies = [
"cfg-if 1.0.0",
"cpufeatures",
@ -6576,23 +6472,6 @@ dependencies = [
"synstructure",
]
[[package]]
name = "tokio"
version = "0.2.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "099837d3464c16a808060bb3f02263b412f6fafcb5d01c533d309985fbeebe48"
dependencies = [
"bytes 0.5.6",
"fnv",
"iovec",
"lazy_static",
"mio 0.6.22",
"num_cpus",
"pin-project-lite 0.1.11",
"slab",
"tokio-macros 0.2.6",
]
[[package]]
name = "tokio"
version = "1.25.0"
@ -6605,44 +6484,23 @@ dependencies = [
"memchr",
"mio 0.8.6",
"num_cpus",
"pin-project-lite 0.2.8",
"pin-project-lite",
"socket2",
"tokio-macros 1.7.0",
"tokio-macros",
"windows-sys 0.42.0",
]
[[package]]
name = "tokio-macros"
version = "0.2.6"
version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e44da00bfc73a25f814cd8d7e57a68a5c31b74b3152a0a1d1f590c97ed06265a"
checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio-macros"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio-openssl"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c4b08c5f4208e699ede3df2520aca2e82401b2de33f45e96696a074480be594"
dependencies = [
"openssl",
"tokio 0.2.24",
]
[[package]]
name = "tokio-openssl"
version = "0.6.3"
@ -6652,7 +6510,7 @@ dependencies = [
"futures-util",
"openssl",
"openssl-sys",
"tokio 1.25.0",
"tokio",
]
[[package]]
@ -6662,8 +6520,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6edf2d6bc038a43d31353570e27270603f4648d18f5ed10c0e179abe43255af"
dependencies = [
"futures-core",
"pin-project-lite 0.2.8",
"tokio 1.25.0",
"pin-project-lite",
"tokio",
]
[[package]]
@ -6675,7 +6533,7 @@ dependencies = [
"async-stream",
"bytes 1.1.0",
"futures-core",
"tokio 1.25.0",
"tokio",
"tokio-stream",
]
@ -6688,8 +6546,8 @@ dependencies = [
"bytes 1.1.0",
"futures-core",
"futures-sink",
"pin-project-lite 0.2.8",
"tokio 1.25.0",
"pin-project-lite",
"tokio",
"tracing",
]
@ -6722,7 +6580,7 @@ checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105"
dependencies = [
"cfg-if 1.0.0",
"log",
"pin-project-lite 0.2.8",
"pin-project-lite",
"tracing-core",
]
@ -6764,20 +6622,19 @@ checksum = "0609f771ad9c6155384897e1df4d948e692667cc0588548b68eb44d052b27633"
[[package]]
name = "tungstenite"
version = "0.11.1"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0308d80d86700c5878b9ef6321f020f29b1bb9d5ff3cab25e75e23f3a492a23"
checksum = "15fba1a6d6bb030745759a9a2a588bfe8490fc8b4751a277db3a0be1c9ebbf67"
dependencies = [
"base64 0.12.0",
"byteorder",
"bytes 0.5.6",
"bytes 1.1.0",
"data-encoding",
"http",
"httparse",
"input_buffer",
"log",
"native-tls",
"rand 0.7.3",
"sha-1 0.9.1",
"rand 0.8.5",
"sha1",
"thiserror",
"url",
"utf-8",
]
@ -6984,7 +6841,7 @@ dependencies = [
"serde",
"serde_json",
"serde_urlencoded",
"tokio 1.25.0",
"tokio",
"tokio-stream",
"tokio-util",
"tower-service",
@ -7173,7 +7030,7 @@ dependencies = [
"serde_derive",
"serde_json",
"time 0.3.21",
"tokio 1.25.0",
"tokio",
"tokio-stream",
"unicode-segmentation",
"url",

View file

@ -73,7 +73,6 @@ surfman-chains-api = "0.2"
thin-slice = "0.1.0"
time = "0.1.41"
tokio = "1"
tokio2 = "0.2"
unicode-bidi = "0.3.4"
unicode-script = "0.5"
url = "2.0"

View file

@ -16,7 +16,7 @@ doctest = false
[dependencies]
async-recursion = "0.3.2"
async-tungstenite = { version = "0.9", features = ["tokio-openssl"] }
async-tungstenite = { version = "0.22", features = ["tokio-openssl"] }
base64 = { workspace = true }
brotli = "3"
bytes = "1"
@ -60,10 +60,9 @@ servo_config = { path = "../config" }
servo_url = { path = "../url" }
sha2 = "0.10"
time = { workspace = true }
tokio = { version = "1", package = "tokio", features = ["sync", "macros", "rt-multi-thread"] }
tokio2 = { version = "0.2", package = "tokio", features = ["sync", "macros", "rt-threaded", "tcp"] }
tokio = { workspace = true, features = ["sync", "macros", "rt-multi-thread"] }
tokio-stream = "0.1"
tungstenite = "0.11"
tungstenite = "0.19"
url = { workspace = true }
uuid = { workspace = true }
webrender_api = { git = "https://github.com/servo/webrender" }

View file

@ -22,7 +22,7 @@ use embedder_traits::resources::{self, Resource};
use futures::future::TryFutureExt;
use futures::sink::SinkExt;
use futures::stream::StreamExt;
use http::header::{HeaderMap, HeaderName, HeaderValue};
use http::header::{self, HeaderName, HeaderValue};
use ipc_channel::ipc::{IpcReceiver, IpcSender};
use ipc_channel::router::ROUTER;
use net_traits::request::{RequestBuilder, RequestMode};
@ -33,14 +33,13 @@ use servo_url::ServoUrl;
use std::fs;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};
use tokio2::net::TcpStream;
use tokio2::runtime::Runtime;
use tokio2::select;
use tokio2::sync::mpsc::{unbounded_channel, UnboundedReceiver};
use tungstenite::error::Error;
use tokio::net::TcpStream;
use tokio::runtime::Runtime;
use tokio::select;
use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver};
use tungstenite::error::Result as WebSocketResult;
use tungstenite::error::{Error, ProtocolError, UrlError};
use tungstenite::handshake::client::{Request, Response};
use tungstenite::http::header::{self as WSHeader, HeaderValue as WSHeaderValue};
use tungstenite::protocol::CloseFrame;
use tungstenite::Message;
use url::Url;
@ -65,20 +64,32 @@ fn create_request(
) -> WebSocketResult<Request> {
let mut builder = Request::get(resource_url.as_str());
let headers = builder.headers_mut().unwrap();
headers.insert("Origin", WSHeaderValue::from_str(origin)?);
headers.insert("Origin", HeaderValue::from_str(origin)?);
let origin = resource_url.origin();
let host = format!(
"{}",
origin
.host()
.ok_or_else(|| Error::Url(UrlError::NoHostName))?
);
headers.insert("Host", HeaderValue::from_str(&host)?);
headers.insert("Connection", HeaderValue::from_static("upgrade"));
headers.insert("Upgrade", HeaderValue::from_static("websocket"));
headers.insert("Sec-Websocket-Version", HeaderValue::from_static("13"));
let key = HeaderValue::from_str(&tungstenite::handshake::client::generate_key()).unwrap();
headers.insert("Sec-WebSocket-Key", key);
if !protocols.is_empty() {
let protocols = protocols.join(",");
headers.insert(
"Sec-WebSocket-Protocol",
WSHeaderValue::from_str(&protocols)?,
);
headers.insert("Sec-WebSocket-Protocol", HeaderValue::from_str(&protocols)?);
}
let mut cookie_jar = http_state.cookie_jar.write().unwrap();
cookie_jar.remove_expired_cookies_for_url(resource_url);
if let Some(cookie_list) = cookie_jar.cookies_for_url(resource_url, CookieSource::HTTP) {
headers.insert("Cookie", WSHeaderValue::from_str(&cookie_list)?);
headers.insert("Cookie", HeaderValue::from_str(&cookie_list)?);
}
if resource_url.password().is_some() || resource_url.username() != "" {
@ -89,7 +100,7 @@ fn create_request(
));
headers.insert(
"Authorization",
WSHeaderValue::from_str(&format!("Basic {}", basic))?,
HeaderValue::from_str(&format!("Basic {}", basic))?,
);
}
@ -110,18 +121,18 @@ fn process_ws_response(
trace!("processing websocket http response for {}", resource_url);
let mut protocol_in_use = None;
if let Some(protocol_name) = response.headers().get("Sec-WebSocket-Protocol") {
let protocol_name = protocol_name.to_str().unwrap();
let protocol_name = protocol_name.to_str().unwrap_or("");
if !protocols.is_empty() && !protocols.iter().any(|p| protocol_name == (*p)) {
return Err(Error::Protocol(
"Protocol in use not in client-supplied protocol list".into(),
));
return Err(Error::Protocol(ProtocolError::InvalidHeader(
HeaderName::from_static("sec-websocket-protocol"),
)));
}
protocol_in_use = Some(protocol_name.to_string());
}
let mut jar = http_state.cookie_jar.write().unwrap();
// TODO(eijebong): Replace thise once typed headers settled on a cookie impl
for cookie in response.headers().get_all(WSHeader::SET_COOKIE) {
for cookie in response.headers().get_all(header::SET_COOKIE) {
if let Ok(s) = std::str::from_utf8(cookie.as_bytes()) {
if let Some(cookie) =
Cookie::from_cookie_string(s.into(), resource_url, CookieSource::HTTP)
@ -131,23 +142,11 @@ fn process_ws_response(
}
}
// We need to make a new header map here because tungstenite depends on
// a more recent version of http than the rest of the network stack, so the
// HeaderMap types are incompatible.
let mut headers = HeaderMap::new();
for (key, value) in response.headers().iter() {
if let (Ok(key), Ok(value)) = (
HeaderName::from_bytes(key.as_ref()),
HeaderValue::from_bytes(value.as_ref()),
) {
headers.insert(key, value);
}
}
http_state
.hsts_list
.write()
.unwrap()
.update_hsts_list_from_response(resource_url, &headers);
.update_hsts_list_from_response(resource_url, &response.headers());
Ok(protocol_in_use)
}
@ -283,6 +282,10 @@ async fn run_ws_loop(
));
break;
}
Message::Frame(_) => {
warn!("Unexpected websocket frame message");
}
}
}
}
@ -309,20 +312,20 @@ async fn start_websocket(
let host_str = client
.uri()
.host()
.ok_or_else(|| Error::Url("No host string".into()))?;
.ok_or_else(|| Error::Url(UrlError::NoHostName))?;
let host = replace_host(host_str);
let mut net_url =
Url::parse(&client.uri().to_string()).map_err(|e| Error::Url(e.to_string().into()))?;
let mut net_url = Url::parse(&client.uri().to_string())
.map_err(|e| Error::Url(UrlError::UnableToConnect(e.to_string())))?;
net_url
.set_host(Some(&host))
.map_err(|e| Error::Url(e.to_string().into()))?;
.map_err(|e| Error::Url(UrlError::UnableToConnect(e.to_string())))?;
let domain = net_url
.host()
.ok_or_else(|| Error::Url("No host string".into()))?;
.ok_or_else(|| Error::Url(UrlError::NoHostName))?;
let port = net_url
.port_or_known_default()
.ok_or_else(|| Error::Url("Unknown port".into()))?;
.ok_or_else(|| Error::Url(UrlError::UnableToConnect("Unknown port".into())))?;
let try_socket = TcpStream::connect((&*domain.to_string(), port)).await;
let socket = try_socket.map_err(Error::Io)?;
@ -366,32 +369,13 @@ fn connect(
};
// https://fetch.spec.whatwg.org/#websocket-opening-handshake
// By standard, we should work with an http(s):// URL (req_url),
// but as ws-rs expects to be called with a ws(s):// URL (net_url)
// we upgrade ws to wss, so we don't have to convert http(s) back to ws(s).
http_state
.hsts_list
.read()
.unwrap()
.apply_hsts_rules(&mut req_builder.url);
let scheme = req_builder.url.scheme();
let mut req_url = req_builder.url.clone();
match scheme {
"ws" => {
req_url
.as_mut_url()
.set_scheme("http")
.map_err(|()| "couldn't replace scheme".to_string())?;
},
"wss" => {
req_url
.as_mut_url()
.set_scheme("https")
.map_err(|()| "couldn't replace scheme".to_string())?;
},
_ => {},
}
let req_url = req_builder.url.clone();
if should_be_blocked_due_to_bad_port(&req_url) {
return Err("Port blocked".to_string());
@ -403,7 +387,7 @@ fn connect(
};
let client = match create_request(
&req_builder.url,
&req_url,
&req_builder.origin.ascii_serialization(),
&protocols,
&*http_state,

View file

@ -59,10 +59,6 @@ packages = [
"bytes",
"futures",
"mio",
"pin-project-lite",
"tokio",
"tokio-macros",
"tokio-openssl",
# https://github.com/servo/servo/pull/23288#issuecomment-494687746
"gl_generator",
@ -79,7 +75,6 @@ packages = [
"block-buffer",
"digest",
"generic-array",
"opaque-debug",
"sha-1",
# Duplicated by winit/surfman update.