aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
authorNikki <nikkicubed@gmail.com>2015-10-26 21:22:27 -0600
committerNikki <nikkicubed@gmail.com>2015-11-04 21:42:10 -0700
commit1d280289f10f950e60d41527739d344cd74d8283 (patch)
tree219dde5289be59b3d6dd74d9c206ece20ddf4805 /components/script
parent6c051ce8286873e47fd33ec438142ddffbb84ca2 (diff)
downloadservo-1d280289f10f950e60d41527739d344cd74d8283.tar.gz
servo-1d280289f10f950e60d41527739d344cd74d8283.zip
Fixes #8213: Implement Blob variant of WebSocket.send()
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/blob.rs5
-rw-r--r--components/script/dom/webidls/WebSocket.webidl3
-rw-r--r--components/script/dom/websocket.rs100
3 files changed, 78 insertions, 30 deletions
diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs
index efbf1abbc15..9c3769a216e 100644
--- a/components/script/dom/blob.rs
+++ b/components/script/dom/blob.rs
@@ -72,6 +72,11 @@ impl Blob {
pub fn read_out_buffer(&self, send: Sender<Vec<u8>>) {
send.send(self.bytes.clone().unwrap_or(vec![])).unwrap();
}
+
+ // simpler to use version of read_out_buffer
+ pub fn clone_bytes(&self) -> Vec<u8> {
+ self.bytes.clone().unwrap_or(vec![])
+ }
}
impl BlobMethods for Blob {
diff --git a/components/script/dom/webidls/WebSocket.webidl b/components/script/dom/webidls/WebSocket.webidl
index bf19ff6e78f..e18b2536743 100644
--- a/components/script/dom/webidls/WebSocket.webidl
+++ b/components/script/dom/webidls/WebSocket.webidl
@@ -29,8 +29,7 @@ interface WebSocket : EventTarget {
attribute EventHandler onmessage;
attribute BinaryType binaryType;
[Throws] void send(USVString data);
- //void send(Blob data);
+ [Throws] void send(Blob data);
//void send(ArrayBuffer data);
//void send(ArrayBufferView data);
-
};
diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs
index 88f3c6a2f8e..4049bce0d26 100644
--- a/components/script/dom/websocket.rs
+++ b/components/script/dom/websocket.rs
@@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use dom::bindings::cell::DOMRefCell;
+use dom::bindings::codegen::Bindings::BlobBinding::BlobMethods;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::Bindings::WebSocketBinding;
use dom::bindings::codegen::Bindings::WebSocketBinding::{BinaryType, WebSocketMethods};
@@ -291,6 +292,56 @@ impl WebSocket {
// Step 7.
Ok(ws)
}
+
+ // https://html.spec.whatwg.org/multipage/#dom-websocket-send
+ fn Send_Impl(&self, data_byte_len: u64) -> Fallible<bool> {
+
+ let mut return_after_buffer = false;
+
+ match self.ready_state.get() {
+ WebSocketRequestState::Connecting => {
+ return Err(Error::InvalidState);
+ },
+ WebSocketRequestState::Open => (),
+ WebSocketRequestState::Closing | WebSocketRequestState::Closed => {
+ return_after_buffer = true;
+ }
+ }
+
+ let global = self.global.root();
+ let chan = global.r().script_chan();
+ let address = Trusted::new(global.r().get_cx(), self, chan.clone());
+
+ let new_buffer_amount = (self.buffered_amount.get() as u64) + data_byte_len;
+ if new_buffer_amount > (u32::max_value() as u64) {
+
+ self.buffered_amount.set(u32::max_value());
+ self.full.set(true);
+
+ let _ = self.Close(None, None);
+ return Ok(false);
+
+ } else {
+ self.buffered_amount.set(new_buffer_amount as u32);
+ }
+
+ if return_after_buffer {
+ return Ok(false);
+ }
+
+ if !self.clearing_buffer.get() &&
+ self.ready_state.get() == WebSocketRequestState::Open {
+ self.clearing_buffer.set(true);
+
+ let task = box BufferedAmountTask {
+ addr: address,
+ };
+
+ chan.send(CommonScriptMsg::RunnableMsg(WebSocketEvent, task)).unwrap();
+ }
+
+ Ok(true)
+ }
}
impl WebSocketMethods for WebSocket {
@@ -333,40 +384,33 @@ impl WebSocketMethods for WebSocket {
// https://html.spec.whatwg.org/multipage/#dom-websocket-send
fn Send(&self, data: USVString) -> Fallible<()> {
- match self.ready_state.get() {
- WebSocketRequestState::Connecting => {
- return Err(Error::InvalidState);
- },
- WebSocketRequestState::Open => (),
- WebSocketRequestState::Closing | WebSocketRequestState::Closed => {
- // TODO: Update bufferedAmount.
- return Ok(());
- }
- }
- /*TODO: This is not up to spec see http://html.spec.whatwg.org/multipage/comms.html search for
- "If argument is a string"
- TODO: Need to buffer data
- TODO: The send function needs to flag when full by using the following
- self.full.set(true). This needs to be done when the buffer is full
- */
- let mut other_sender = self.sender.borrow_mut();
- let my_sender = other_sender.as_mut().unwrap();
+ let data_byte_len = data.0.as_bytes().len() as u64;
+ let send_data = try!(self.Send_Impl(data_byte_len));
- self.buffered_amount.set(self.buffered_amount.get() + (data.0.as_bytes().len() as u32));
+ if send_data {
+ let mut other_sender = self.sender.borrow_mut();
+ let my_sender = other_sender.as_mut().unwrap();
+ let _ = my_sender.lock().unwrap().send_message(Message::Text(data.0));
+ }
- let _ = my_sender.lock().unwrap().send_message(Message::Text(data.0));
+ Ok(())
+ }
- if !self.clearing_buffer.get() && self.ready_state.get() == WebSocketRequestState::Open {
- self.clearing_buffer.set(true);
+ // https://html.spec.whatwg.org/multipage/#dom-websocket-send
+ fn Send_(&self, data: &Blob) -> Fallible<()> {
- let global = self.global.root();
- let task = box BufferedAmountTask {
- addr: Trusted::new(global.r().get_cx(), self, global.r().script_chan()),
- };
- let chan = global.r().script_chan();
+ /* As per https://html.spec.whatwg.org/multipage/#websocket
+ the buffered amount needs to be clamped to u32, even though Blob.Size() is u64
+ If the buffer limit is reached in the first place, there are likely other major problems
+ */
+ let data_byte_len = data.Size();
+ let send_data = try!(self.Send_Impl(data_byte_len));
- chan.send(CommonScriptMsg::RunnableMsg(WebSocketEvent, task)).unwrap();
+ if send_data {
+ let mut other_sender = self.sender.borrow_mut();
+ let my_sender = other_sender.as_mut().unwrap();
+ let _ = my_sender.lock().unwrap().send_message(Message::Binary(data.clone_bytes()));
}
Ok(())