mirror of
https://github.com/servo/servo.git
synced 2025-07-31 11:10:22 +01:00
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:
commit
021f441d24
7 changed files with 86 additions and 52 deletions
|
@ -72,6 +72,11 @@ impl Blob {
|
||||||
pub fn read_out_buffer(&self, send: Sender<Vec<u8>>) {
|
pub fn read_out_buffer(&self, send: Sender<Vec<u8>>) {
|
||||||
send.send(self.bytes.clone().unwrap_or(vec![])).unwrap();
|
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 {
|
impl BlobMethods for Blob {
|
||||||
|
|
|
@ -29,8 +29,7 @@ interface WebSocket : EventTarget {
|
||||||
attribute EventHandler onmessage;
|
attribute EventHandler onmessage;
|
||||||
attribute BinaryType binaryType;
|
attribute BinaryType binaryType;
|
||||||
[Throws] void send(USVString data);
|
[Throws] void send(USVString data);
|
||||||
//void send(Blob data);
|
[Throws] void send(Blob data);
|
||||||
//void send(ArrayBuffer data);
|
//void send(ArrayBuffer data);
|
||||||
//void send(ArrayBufferView data);
|
//void send(ArrayBufferView data);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use dom::bindings::cell::DOMRefCell;
|
use dom::bindings::cell::DOMRefCell;
|
||||||
|
use dom::bindings::codegen::Bindings::BlobBinding::BlobMethods;
|
||||||
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
|
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
|
||||||
use dom::bindings::codegen::Bindings::WebSocketBinding;
|
use dom::bindings::codegen::Bindings::WebSocketBinding;
|
||||||
use dom::bindings::codegen::Bindings::WebSocketBinding::{BinaryType, WebSocketMethods};
|
use dom::bindings::codegen::Bindings::WebSocketBinding::{BinaryType, WebSocketMethods};
|
||||||
|
@ -292,6 +293,56 @@ impl WebSocket {
|
||||||
// Step 7.
|
// Step 7.
|
||||||
Ok(ws)
|
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 {
|
impl WebSocketMethods for WebSocket {
|
||||||
|
@ -334,40 +385,33 @@ impl WebSocketMethods for WebSocket {
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-websocket-send
|
// https://html.spec.whatwg.org/multipage/#dom-websocket-send
|
||||||
fn Send(&self, data: USVString) -> Fallible<()> {
|
fn Send(&self, data: USVString) -> Fallible<()> {
|
||||||
match self.ready_state.get() {
|
|
||||||
WebSocketRequestState::Connecting => {
|
let data_byte_len = data.0.as_bytes().len() as u64;
|
||||||
return Err(Error::InvalidState);
|
let send_data = try!(self.Send_Impl(data_byte_len));
|
||||||
},
|
|
||||||
WebSocketRequestState::Open => (),
|
if send_data {
|
||||||
WebSocketRequestState::Closing | WebSocketRequestState::Closed => {
|
let mut other_sender = self.sender.borrow_mut();
|
||||||
// TODO: Update bufferedAmount.
|
let my_sender = other_sender.as_mut().unwrap();
|
||||||
return Ok(());
|
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
|
Ok(())
|
||||||
"If argument is a string"
|
}
|
||||||
TODO: Need to buffer data
|
|
||||||
TODO: The send function needs to flag when full by using the following
|
// https://html.spec.whatwg.org/multipage/#dom-websocket-send
|
||||||
self.full.set(true). This needs to be done when the buffer is full
|
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 data_byte_len = data.Size();
|
||||||
let my_sender = other_sender.as_mut().unwrap();
|
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.lock().unwrap().send_message(Message::Text(data.0));
|
let my_sender = other_sender.as_mut().unwrap();
|
||||||
|
let _ = my_sender.lock().unwrap().send_message(Message::Binary(data.clone_bytes()));
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -22,7 +22,9 @@
|
||||||
|
|
||||||
wsocket.addEventListener('open', testOpen.step_func(function (evt) {
|
wsocket.addEventListener('open', testOpen.step_func(function (evt) {
|
||||||
wsocket.binaryType = "blob";
|
wsocket.binaryType = "blob";
|
||||||
data = new ArrayBuffer(datasize);
|
for (var i = 0; i < datasize; i++)
|
||||||
|
data += String.fromCharCode(0);
|
||||||
|
data = new Blob([data]);
|
||||||
isOpenCalled = true;
|
isOpenCalled = true;
|
||||||
wsocket.send(data);
|
wsocket.send(data);
|
||||||
testOpen.done();
|
testOpen.done();
|
||||||
|
|
|
@ -22,7 +22,9 @@
|
||||||
|
|
||||||
wsocket.addEventListener('open', testOpen.step_func(function (evt) {
|
wsocket.addEventListener('open', testOpen.step_func(function (evt) {
|
||||||
wsocket.binaryType = "blob";
|
wsocket.binaryType = "blob";
|
||||||
data = new ArrayBuffer(datasize);
|
for (var i = 0; i < datasize; i++)
|
||||||
|
data += String.fromCharCode(0);
|
||||||
|
data = new Blob([data]);
|
||||||
isOpenCalled = true;
|
isOpenCalled = true;
|
||||||
wsocket.send(data);
|
wsocket.send(data);
|
||||||
testOpen.done();
|
testOpen.done();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue