mirror of
https://github.com/servo/servo.git
synced 2025-06-12 10:24:43 +00:00
Only pass the protocol in use in to establish a WS connection
This commit is contained in:
parent
189b0d9094
commit
a6d22b1a35
6 changed files with 23 additions and 29 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2293,7 +2293,6 @@ dependencies = [
|
||||||
"selectors 0.18.0",
|
"selectors 0.18.0",
|
||||||
"serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde_json 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"servo-websocket 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"servo_atoms 0.0.1",
|
"servo_atoms 0.0.1",
|
||||||
"servo_config 0.0.1",
|
"servo_config 0.0.1",
|
||||||
"servo_geometry 0.0.1",
|
"servo_geometry 0.0.1",
|
||||||
|
|
|
@ -10,14 +10,13 @@ use hyper::header::{Host, SetCookie};
|
||||||
use net_traits::{CookieSource, MessageData, WebSocketCommunicate};
|
use net_traits::{CookieSource, MessageData, WebSocketCommunicate};
|
||||||
use net_traits::{WebSocketConnectData, WebSocketDomAction, WebSocketNetworkEvent};
|
use net_traits::{WebSocketConnectData, WebSocketDomAction, WebSocketNetworkEvent};
|
||||||
use net_traits::hosts::replace_hosts;
|
use net_traits::hosts::replace_hosts;
|
||||||
use net_traits::unwrap_websocket_protocol;
|
|
||||||
use servo_url::ServoUrl;
|
use servo_url::ServoUrl;
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::sync::{Arc, Mutex, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use websocket::{Client, Message};
|
use websocket::{Client, Message};
|
||||||
use websocket::header::{Headers, Origin, WebSocketProtocol};
|
use websocket::header::{Origin, WebSocketProtocol};
|
||||||
use websocket::message::Type;
|
use websocket::message::Type;
|
||||||
use websocket::receiver::Receiver;
|
use websocket::receiver::Receiver;
|
||||||
use websocket::result::{WebSocketError, WebSocketResult};
|
use websocket::result::{WebSocketError, WebSocketResult};
|
||||||
|
@ -31,7 +30,9 @@ fn establish_a_websocket_connection(resource_url: &ServoUrl,
|
||||||
origin: String,
|
origin: String,
|
||||||
protocols: Vec<String>,
|
protocols: Vec<String>,
|
||||||
cookie_jar: Arc<RwLock<CookieStorage>>)
|
cookie_jar: Arc<RwLock<CookieStorage>>)
|
||||||
-> WebSocketResult<(Headers, Sender<WebSocketStream>, Receiver<WebSocketStream>)> {
|
-> WebSocketResult<(Option<String>,
|
||||||
|
Sender<WebSocketStream>,
|
||||||
|
Receiver<WebSocketStream>)> {
|
||||||
// Steps 1-2 are not really applicable here, given we don't exactly go
|
// Steps 1-2 are not really applicable here, given we don't exactly go
|
||||||
// through the same infrastructure as the Fetch spec.
|
// through the same infrastructure as the Fetch spec.
|
||||||
|
|
||||||
|
@ -77,9 +78,13 @@ fn establish_a_websocket_connection(resource_url: &ServoUrl,
|
||||||
|
|
||||||
// Step 13 and transitive subset of step 14.
|
// Step 13 and transitive subset of step 14.
|
||||||
// See step 6 of http://tools.ietf.org/html/rfc6455#section-4.1.
|
// See step 6 of http://tools.ietf.org/html/rfc6455#section-4.1.
|
||||||
if let Some(protocol_name) = unwrap_websocket_protocol(response.protocol()) {
|
let protocol_in_use = response.protocol().and_then(|header| {
|
||||||
if !protocols.is_empty() && !protocols.iter().any(|p| (&**p).eq_ignore_ascii_case(protocol_name)) {
|
// https://github.com/whatwg/fetch/issues/515
|
||||||
return Err(WebSocketError::ProtocolError("Protocol in Use not in client-supplied protocol list"));
|
header.first().cloned()
|
||||||
|
});
|
||||||
|
if let Some(ref protocol_name) = protocol_in_use {
|
||||||
|
if !protocols.is_empty() && !protocols.iter().any(|p| (&**p).eq_ignore_ascii_case(protocol_name)) {
|
||||||
|
return Err(WebSocketError::ProtocolError("Protocol in Use not in client-supplied protocol list"));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -94,9 +99,8 @@ fn establish_a_websocket_connection(resource_url: &ServoUrl,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let headers = response.headers.clone();
|
|
||||||
let (sender, receiver) = response.begin().split();
|
let (sender, receiver) = response.begin().split();
|
||||||
Ok((headers, sender, receiver))
|
Ok((protocol_in_use, sender, receiver))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(connect: WebSocketCommunicate, connect_data: WebSocketConnectData, cookie_jar: Arc<RwLock<CookieStorage>>) {
|
pub fn init(connect: WebSocketCommunicate, connect_data: WebSocketConnectData, cookie_jar: Arc<RwLock<CookieStorage>>) {
|
||||||
|
@ -106,8 +110,8 @@ pub fn init(connect: WebSocketCommunicate, connect_data: WebSocketConnectData, c
|
||||||
connect_data.protocols,
|
connect_data.protocols,
|
||||||
cookie_jar);
|
cookie_jar);
|
||||||
let (ws_sender, mut receiver) = match channel {
|
let (ws_sender, mut receiver) = match channel {
|
||||||
Ok((headers, sender, receiver)) => {
|
Ok((protocol_in_use, sender, receiver)) => {
|
||||||
let _ = connect.event_sender.send(WebSocketNetworkEvent::ConnectionEstablished(headers));
|
let _ = connect.event_sender.send(WebSocketNetworkEvent::ConnectionEstablished { protocol_in_use });
|
||||||
(sender, receiver)
|
(sender, receiver)
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
|
@ -348,9 +348,9 @@ pub enum WebSocketDomAction {
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub enum WebSocketNetworkEvent {
|
pub enum WebSocketNetworkEvent {
|
||||||
ConnectionEstablished(#[serde(deserialize_with = "::hyper_serde::deserialize",
|
ConnectionEstablished {
|
||||||
serialize_with = "::hyper_serde::serialize")]
|
protocol_in_use: Option<String>,
|
||||||
header::Headers),
|
},
|
||||||
MessageReceived(MessageData),
|
MessageReceived(MessageData),
|
||||||
Close(Option<u16>, String),
|
Close(Option<u16>, String),
|
||||||
Fail,
|
Fail,
|
||||||
|
@ -514,11 +514,6 @@ pub fn load_whole_resource(request: RequestInit,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defensively unwraps the protocol string from the response object's protocol
|
|
||||||
pub fn unwrap_websocket_protocol(wsp: Option<&header::WebSocketProtocol>) -> Option<&str> {
|
|
||||||
wsp.and_then(|protocol_list| protocol_list.get(0).map(|protocol| protocol.as_ref()))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// An unique identifier to keep track of each load message in the resource handler
|
/// An unique identifier to keep track of each load message in the resource handler
|
||||||
#[derive(Clone, PartialEq, Eq, Copy, Hash, Debug, Deserialize, Serialize, HeapSizeOf)]
|
#[derive(Clone, PartialEq, Eq, Copy, Hash, Debug, Deserialize, Serialize, HeapSizeOf)]
|
||||||
pub struct ResourceId(pub u32);
|
pub struct ResourceId(pub u32);
|
||||||
|
|
|
@ -79,8 +79,7 @@ servo_atoms = {path = "../atoms"}
|
||||||
servo_config = {path = "../config", features = ["servo"] }
|
servo_config = {path = "../config", features = ["servo"] }
|
||||||
servo_geometry = {path = "../geometry" }
|
servo_geometry = {path = "../geometry" }
|
||||||
servo_rand = {path = "../rand"}
|
servo_rand = {path = "../rand"}
|
||||||
servo_url = {path = "../url", features = ["servo"] }
|
servo_url = {path = "../url", features = ["servo"]}
|
||||||
servo-websocket = "0.18"
|
|
||||||
smallvec = "0.3"
|
smallvec = "0.3"
|
||||||
style = {path = "../style"}
|
style = {path = "../style"}
|
||||||
style_traits = {path = "../style_traits"}
|
style_traits = {path = "../style_traits"}
|
||||||
|
|
|
@ -30,7 +30,6 @@ use js::typedarray::{ArrayBuffer, CreateWith};
|
||||||
use net_traits::{WebSocketCommunicate, WebSocketConnectData, WebSocketDomAction, WebSocketNetworkEvent};
|
use net_traits::{WebSocketCommunicate, WebSocketConnectData, WebSocketDomAction, WebSocketNetworkEvent};
|
||||||
use net_traits::CoreResourceMsg::WebsocketConnect;
|
use net_traits::CoreResourceMsg::WebsocketConnect;
|
||||||
use net_traits::MessageData;
|
use net_traits::MessageData;
|
||||||
use net_traits::unwrap_websocket_protocol;
|
|
||||||
use script_runtime::CommonScriptMsg;
|
use script_runtime::CommonScriptMsg;
|
||||||
use script_runtime::ScriptThreadEventCategory::WebSocketEvent;
|
use script_runtime::ScriptThreadEventCategory::WebSocketEvent;
|
||||||
use script_thread::{Runnable, RunnableWrapper};
|
use script_thread::{Runnable, RunnableWrapper};
|
||||||
|
@ -42,7 +41,6 @@ use std::ptr;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use task_source::TaskSource;
|
use task_source::TaskSource;
|
||||||
use task_source::networking::NetworkingTaskSource;
|
use task_source::networking::NetworkingTaskSource;
|
||||||
use websocket::header::{Headers, WebSocketProtocol};
|
|
||||||
|
|
||||||
#[derive(JSTraceable, PartialEq, Copy, Clone, Debug, HeapSizeOf)]
|
#[derive(JSTraceable, PartialEq, Copy, Clone, Debug, HeapSizeOf)]
|
||||||
enum WebSocketRequestState {
|
enum WebSocketRequestState {
|
||||||
|
@ -204,10 +202,10 @@ impl WebSocket {
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
while let Ok(event) = dom_event_receiver.recv() {
|
while let Ok(event) = dom_event_receiver.recv() {
|
||||||
match event {
|
match event {
|
||||||
WebSocketNetworkEvent::ConnectionEstablished(headers) => {
|
WebSocketNetworkEvent::ConnectionEstablished { protocol_in_use } => {
|
||||||
let open_thread = box ConnectionEstablishedTask {
|
let open_thread = box ConnectionEstablishedTask {
|
||||||
address: address.clone(),
|
address: address.clone(),
|
||||||
headers: headers,
|
protocol_in_use,
|
||||||
};
|
};
|
||||||
task_source.queue_with_wrapper(open_thread, &wrapper).unwrap();
|
task_source.queue_with_wrapper(open_thread, &wrapper).unwrap();
|
||||||
},
|
},
|
||||||
|
@ -393,7 +391,7 @@ impl WebSocketMethods for WebSocket {
|
||||||
/// https://html.spec.whatwg.org/multipage/#feedback-from-the-protocol:concept-websocket-established
|
/// https://html.spec.whatwg.org/multipage/#feedback-from-the-protocol:concept-websocket-established
|
||||||
struct ConnectionEstablishedTask {
|
struct ConnectionEstablishedTask {
|
||||||
address: Trusted<WebSocket>,
|
address: Trusted<WebSocket>,
|
||||||
headers: Headers,
|
protocol_in_use: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Runnable for ConnectionEstablishedTask {
|
impl Runnable for ConnectionEstablishedTask {
|
||||||
|
@ -410,8 +408,8 @@ impl Runnable for ConnectionEstablishedTask {
|
||||||
// TODO: Set extensions to extensions in use.
|
// TODO: Set extensions to extensions in use.
|
||||||
|
|
||||||
// Step 3.
|
// Step 3.
|
||||||
if let Some(protocol_name) = unwrap_websocket_protocol(self.headers.get::<WebSocketProtocol>()) {
|
if let Some(protocol_name) = self.protocol_in_use {
|
||||||
*ws.protocol.borrow_mut() = protocol_name.to_owned();
|
*ws.protocol.borrow_mut() = protocol_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Step 4.
|
// Step 4.
|
||||||
|
|
|
@ -98,7 +98,6 @@ extern crate tinyfiledialogs;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
extern crate uuid;
|
extern crate uuid;
|
||||||
extern crate webrender_traits;
|
extern crate webrender_traits;
|
||||||
extern crate websocket;
|
|
||||||
extern crate webvr_traits;
|
extern crate webvr_traits;
|
||||||
extern crate xml5ever;
|
extern crate xml5ever;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue