Auto merge of #8218 - nikkisquared:master, r=eefriedman

I'm working on resolving https://github.com/servo/servo/issues/8213 as per the spec online and feedback in the servo channel. Note that currently I cannot build (and thus test) my code, so this is a bit of a rough first draft. I'd still like feedback on my progress, and I hope that there is another way for my code to be tested.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/8218)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2015-11-05 10:24:27 +05:30
commit 021f441d24
7 changed files with 86 additions and 52 deletions

View file

@ -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 {

View file

@ -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);
};

View file

@ -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};
@ -292,6 +293,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 {
@ -334,40 +385,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(());
}
let data_byte_len = data.0.as_bytes().len() as u64;
let send_data = try!(self.Send_Impl(data_byte_len));
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));
}
/*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
Ok(())
}
// https://html.spec.whatwg.org/multipage/#dom-websocket-send
fn Send_(&self, data: &Blob) -> Fallible<()> {
/* 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 mut other_sender = self.sender.borrow_mut();
let my_sender = other_sender.as_mut().unwrap();
let data_byte_len = data.Size();
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));
let _ = my_sender.lock().unwrap().send_message(Message::Text(data.0));
if !self.clearing_buffer.get() && self.ready_state.get() == WebSocketRequestState::Open {
self.clearing_buffer.set(true);
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();
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(())

View file

@ -1,9 +0,0 @@
[Secure-Send-binary-blob.htm]
type: testharness
expected: TIMEOUT
[W3C WebSocket API - Send binary data on a Secure WebSocket - Blob - Message should be received]
expected: FAIL
[W3C WebSocket API - Send binary data on a Secure WebSocket - Blob - Connection should be closed]
expected: NOTRUN

View file

@ -1,9 +0,0 @@
[Send-binary-blob.htm]
type: testharness
expected: TIMEOUT
[W3C WebSocket API - Send binary data on a WebSocket - Blob - Message should be received]
expected: FAIL
[W3C WebSocket API - Send binary data on a WebSocket - Blob - Connection should be closed]
expected: NOTRUN

View file

@ -22,7 +22,9 @@
wsocket.addEventListener('open', testOpen.step_func(function (evt) {
wsocket.binaryType = "blob";
data = new ArrayBuffer(datasize);
for (var i = 0; i < datasize; i++)
data += String.fromCharCode(0);
data = new Blob([data]);
isOpenCalled = true;
wsocket.send(data);
testOpen.done();

View file

@ -22,7 +22,9 @@
wsocket.addEventListener('open', testOpen.step_func(function (evt) {
wsocket.binaryType = "blob";
data = new ArrayBuffer(datasize);
for (var i = 0; i < datasize; i++)
data += String.fromCharCode(0);
data = new Blob([data]);
isOpenCalled = true;
wsocket.send(data);
testOpen.done();