aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2016-06-10 08:49:53 -0500
committerGitHub <noreply@github.com>2016-06-10 08:49:53 -0500
commit96f34049286076c20ff91b260eb6a9651c0eecd6 (patch)
tree72ff2e51851e293241d073961f9a4ba917795c5f
parent2ae8a70e2b929ac413c4bb09f00cc45d7433c05b (diff)
parent27b4ac61508877e6ded6f01a65bd02e01dc4e81b (diff)
downloadservo-96f34049286076c20ff91b260eb6a9651c0eecd6.tar.gz
servo-96f34049286076c20ff91b260eb6a9651c0eecd6.zip
Auto merge of #10382 - bobthekingofegypt:fix-websocket-close, r=metajack
stop client websocket close echoing server close Client initiated close requests should send a close message to the server that the server will echo back to complete the process. Servo should not then echo the servers close request back again to the server, this guard stops servo from echoing a server close request if the process was initiated by the client. Tracked in https://github.com/servo/servo/issues/9803#issuecomment-196424406 <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/10382) <!-- Reviewable:end -->
-rw-r--r--components/net/websocket_loader.rs20
1 files changed, 14 insertions, 6 deletions
diff --git a/components/net/websocket_loader.rs b/components/net/websocket_loader.rs
index f7819b96b7d..60d6c8932f6 100644
--- a/components/net/websocket_loader.rs
+++ b/components/net/websocket_loader.rs
@@ -10,6 +10,7 @@ use net_traits::hosts::replace_hosts;
use net_traits::unwrap_websocket_protocol;
use net_traits::{WebSocketCommunicate, WebSocketConnectData, WebSocketDomAction, WebSocketNetworkEvent};
use std::ascii::AsciiExt;
+use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex, RwLock};
use std::thread;
use util::thread::spawn_named;
@@ -98,8 +99,10 @@ pub fn init(connect: WebSocketCommunicate, connect_data: WebSocketConnectData, c
};
+ let initiated_close = Arc::new(AtomicBool::new(false));
let ws_sender = Arc::new(Mutex::new(ws_sender));
+ let initiated_close_incoming = initiated_close.clone();
let ws_sender_incoming = ws_sender.clone();
let resource_event_sender = connect.event_sender;
thread::spawn(move || {
@@ -122,7 +125,9 @@ pub fn init(connect: WebSocketCommunicate, connect_data: WebSocketConnectData, c
},
Type::Pong => continue,
Type::Close => {
- ws_sender_incoming.lock().unwrap().send_message(&message).unwrap();
+ if !initiated_close_incoming.fetch_or(true, Ordering::SeqCst) {
+ ws_sender_incoming.lock().unwrap().send_message(&message).unwrap();
+ }
let code = message.cd_status_code;
let reason = String::from_utf8_lossy(&message.payload).into_owned();
let _ = resource_event_sender.send(WebSocketNetworkEvent::Close(code, reason));
@@ -133,6 +138,7 @@ pub fn init(connect: WebSocketCommunicate, connect_data: WebSocketConnectData, c
}
});
+ let initiated_close_outgoing = initiated_close.clone();
let ws_sender_outgoing = ws_sender.clone();
let resource_action_receiver = connect.action_receiver;
thread::spawn(move || {
@@ -145,11 +151,13 @@ pub fn init(connect: WebSocketCommunicate, connect_data: WebSocketConnectData, c
ws_sender_outgoing.lock().unwrap().send_message(&Message::binary(data)).unwrap();
},
WebSocketDomAction::Close(code, reason) => {
- let message = match code {
- Some(code) => Message::close_because(code, reason.unwrap_or("".to_owned())),
- None => Message::close()
- };
- ws_sender_outgoing.lock().unwrap().send_message(&message).unwrap();
+ if !initiated_close_outgoing.fetch_or(true, Ordering::SeqCst) {
+ let message = match code {
+ Some(code) => Message::close_because(code, reason.unwrap_or("".to_owned())),
+ None => Message::close()
+ };
+ ws_sender_outgoing.lock().unwrap().send_message(&message).unwrap();
+ }
},
}
}