Support close code and reason

This commit is contained in:
Naja Melan
2019-07-17 22:52:00 +02:00
parent 18dfd3cfb6
commit 60d178906e
8 changed files with 225 additions and 23 deletions

1
.gitignore vendored
View File

@@ -1,6 +1,7 @@
# Generated by Cargo
# will have compiled files and executables
/target
examples/**/target
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html

View File

@@ -2,8 +2,6 @@
## Features
- include events (pharos)
- close reason
- reconnect?
## Testing

View File

@@ -80,6 +80,20 @@ pub enum WsErrKind
#[ fail( display = "The port to which the connection is being attempted is being blocked." ) ]
//
SecurityError,
/// An invalid close code was given to a close method. For valid close codes, please see:
/// [MDN Documentation](https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes)
///
#[ fail( display = "An invalid close code was given to a close method: {}", _0 ) ]
//
InvalidCloseCode(u16),
/// The reason string given to a close method is to long, please see:
/// [MDN Documentation](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close)
///
#[ fail( display = "The reason string given to a close method is to long." ) ]
//
ReasonStringToLong,
}

View File

@@ -84,10 +84,6 @@ impl WsIo
{
trace!( "WsStream: message received!" );
#[ cfg( debug_assertions )]
//
dbg( &msg_evt );
q2.borrow_mut().push_back( JsMsgEvent{ msg_evt } );
if let Some( w ) = w2.borrow_mut().take()

View File

@@ -80,7 +80,7 @@ impl WsStream
/// Close the socket. The future will resolve once the socket's state has become `WsReadyState::CLOSED`.
/// TODO: allow setting reason and code.
/// See: [MDN Documentation](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close)
//
pub async fn close( &self )
{
@@ -97,6 +97,69 @@ impl WsStream
/// Close the socket. The future will resolve once the socket's state has become `WsReadyState::CLOSED`.
/// See: [MDN Documentation](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close)
//
pub async fn close_code( &self, code: u16 ) -> Result<(), WsErr>
{
match self.ws.close_with_code( code )
{
Ok(_) =>
{
future_event( |cb| self.ws.set_onclose( cb ) ).await;
trace!( "WebSocket connection closed!" );
Ok(())
}
Err( _e ) =>
{
// TODO: figure out how to print the original error
//
// error!( "{}", e.as_string().expect( "JsValue to string" ) );
//
Err( WsErrKind::InvalidCloseCode( code ).into() )
}
}
}
/// Close the socket. The future will resolve once the socket's state has become `WsReadyState::CLOSED`.
/// See: [MDN Documentation](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close)
//
pub async fn close_reason( &self, code: u16, reason: impl AsRef<str> ) -> Result<(), WsErr>
{
if reason.as_ref().len() > 123
{
return Err( WsErrKind::ReasonStringToLong.into() )
}
match self.ws.close_with_code_and_reason( code, reason.as_ref() )
{
Ok(_) =>
{
future_event( |cb| self.ws.set_onclose( cb ) ).await;
trace!( "WebSocket connection closed!" );
Ok(())
}
Err( _e ) =>
{
// TODO: figure out how to print the original error
//
// error!( "{}", e.as_string().expect( "JsValue to string" ) );
//
Err( WsErrKind::InvalidCloseCode(code).into() )
}
}
}
/// Verify the [WsReadyState] of the connection.
/// TODO: verify error handling
//

View File

@@ -42,7 +42,7 @@ pub fn data_integrity() -> impl Future01<Item = (), Error = JsValue>
{
let _ = console_log::init_with_level( Level::Trace );
console_log!( "starting test: data_integrity" );
info!( "starting test: data_integrity" );
let big_size = 10240;
let mut random = vec![ 0; big_size ];
@@ -85,7 +85,7 @@ pub fn data_integrity() -> impl Future01<Item = (), Error = JsValue>
//
async fn echo( name: &str, size: usize, data: Bytes )
{
console_log!( " Enter echo: {}", name );
info!( " Enter echo: {}", name );
let (_ws , wsio) = connect().await;
@@ -132,7 +132,7 @@ pub fn lines_integrity() -> impl Future01<Item = (), Error = JsValue>
{
let _ = console_log::init_with_level( Level::Trace );
console_log!( "starting test: lines_integrity" );
info!( "starting test: lines_integrity" );
async move
@@ -140,25 +140,25 @@ pub fn lines_integrity() -> impl Future01<Item = (), Error = JsValue>
let (_ws , wsio ) = connect().await;
let mut framed = Framed::new( wsio, LinesCodec {} );
console_log!( "lines_integrity: start sending" );
info!( "lines_integrity: start sending" );
framed.send( "A line\n" .to_string() ).await.expect_throw( "Send a line" );
framed.send( "A second line\n".to_string() ).await.expect_throw( "Send a second line" );
framed.send( "A third line\n" .to_string() ).await.expect_throw( "Send a third line" );
console_log!( "lines_integrity: start receiving" );
info!( "lines_integrity: start receiving" );
let one = framed.next().await.expect_throw( "Some" ).expect_throw( "Receive a line" );
let two = framed.next().await.expect_throw( "Some" ).expect_throw( "Receive a second line" );
let three = framed.next().await.expect_throw( "Some" ).expect_throw( "Receive a third line" );
console_log!( "lines_integrity: start asserting" );
info!( "lines_integrity: start asserting" );
assert_eq!( "A line\n" , &one );
assert_eq!( "A second line\n", &two );
assert_eq!( "A third line\n" , &three );
console_log!( "lines_integrity: done" );
info!( "lines_integrity: done" );
let r: Result<(), wasm_bindgen::JsValue> = Ok(());

View File

@@ -52,7 +52,7 @@ pub fn data_integrity() -> impl Future01<Item = (), Error = JsValue>
//
let _ = console_log::init_with_level( Level::Trace );
console_log!( "starting test: data_integrity" );
info!( "starting test: data_integrity" );
let big_size = 10240;
let mut random = vec![ 0u8; big_size ];
@@ -93,7 +93,7 @@ pub fn data_integrity() -> impl Future01<Item = (), Error = JsValue>
//
async fn echo( name: &str, size: usize, data: Bytes )
{
console_log!( " Enter echo: {}", name );
info!( " Enter echo: {}", name );
let (_ws, wsio) = connect().await;
let (tx, rx) = BytesCodec::new().framed( wsio ).split();
@@ -147,7 +147,7 @@ pub fn data_integrity_cbor() -> impl Future01<Item = (), Error = JsValue>
//
let _ = console_log::init_with_level( Level::Trace );
console_log!( "starting test: data_integrity_cbor" );
info!( "starting test: data_integrity_cbor" );
let dataset: Vec<Data> = vec!
[
@@ -177,7 +177,7 @@ pub fn data_integrity_cbor() -> impl Future01<Item = (), Error = JsValue>
//
async fn echo_cbor( data: Data )
{
console_log!( " Enter echo_cbor: {}", &data.hello );
info!( " Enter echo_cbor: {}", &data.hello );
let (_ws, wsio) = connect().await;

View File

@@ -26,7 +26,7 @@ pub fn state() -> impl Future01<Item = (), Error = JsValue>
{
let _ = console_log::init_with_level( Level::Trace );
console_log!( "starting test: state" );
info!( "starting test: state" );
async
{
@@ -56,7 +56,7 @@ pub fn close_from_wsio() -> impl Future01<Item = (), Error = JsValue>
{
let _ = console_log::init_with_level( Level::Trace );
console_log!( "starting test: close_from_wsio" );
info!( "starting test: close_from_wsio" );
async
{
@@ -87,7 +87,7 @@ pub fn url() -> impl Future01<Item = (), Error = JsValue>
{
let _ = console_log::init_with_level( Level::Trace );
console_log!( "starting test: url" );
info!( "starting test: url" );
async
{
@@ -113,7 +113,7 @@ pub fn no_protocols() -> impl Future01<Item = (), Error = JsValue>
{
let _ = console_log::init_with_level( Level::Trace );
console_log!( "starting test: no_protocols" );
info!( "starting test: no_protocols" );
async
{
@@ -129,6 +129,136 @@ pub fn no_protocols() -> impl Future01<Item = (), Error = JsValue>
}
// Verify close_code method.
//
#[ wasm_bindgen_test(async) ]
//
pub fn close_code_valid() -> impl Future01<Item = (), Error = JsValue>
{
let _ = console_log::init_with_level( Level::Trace );
info!( "starting test: close_code_valid" );
async
{
let (ws, _wsio) = WsStream::connect( URL, None ).await.expect_throw( "Could not create websocket" );
let res = ws.close_code( 1000 ).await;
assert!( res.is_ok() );
let r: Result<(), wasm_bindgen::JsValue> = Ok(());
r
}.boxed_local().compat()
}
// Verify close_code method.
//
#[ wasm_bindgen_test(async) ]
//
pub fn close_code_invalid() -> impl Future01<Item = (), Error = JsValue>
{
let _ = console_log::init_with_level( Level::Trace );
info!( "starting test: close_code_invalid" );
async
{
let (ws, _wsio) = WsStream::connect( URL, None ).await.expect_throw( "Could not create websocket" );
let res = ws.close_code( 500 ).await;
assert_eq!( &WsErrKind::InvalidCloseCode(500), res.unwrap_err().kind() );
let r: Result<(), wasm_bindgen::JsValue> = Ok(());
r
}.boxed_local().compat()
}
// Verify close_code method.
//
#[ wasm_bindgen_test(async) ]
//
pub fn close_reason_valid() -> impl Future01<Item = (), Error = JsValue>
{
let _ = console_log::init_with_level( Level::Trace );
info!( "starting test: close_reason_valid" );
async
{
let (ws, _wsio) = WsStream::connect( URL, None ).await.expect_throw( "Could not create websocket" );
let res = ws.close_reason( 1000, "Normal shutdown" ).await;
assert!( res.is_ok() );
let r: Result<(), wasm_bindgen::JsValue> = Ok(());
r
}.boxed_local().compat()
}
// Verify close_code method.
//
#[ wasm_bindgen_test(async) ]
//
pub fn close_reason_invalid_code() -> impl Future01<Item = (), Error = JsValue>
{
let _ = console_log::init_with_level( Level::Trace );
info!( "starting test: close_reason_invalid_code" );
async
{
let (ws, _wsio) = WsStream::connect( URL, None ).await.expect_throw( "Could not create websocket" );
let res = ws.close_reason( 500, "Normal Shutdown" ).await;
assert_eq!( &WsErrKind::InvalidCloseCode(500), res.unwrap_err().kind() );
let r: Result<(), wasm_bindgen::JsValue> = Ok(());
r
}.boxed_local().compat()
}
// Verify close_code method.
//
#[ wasm_bindgen_test(async) ]
//
pub fn close_reason_invalid() -> impl Future01<Item = (), Error = JsValue>
{
let _ = console_log::init_with_level( Level::Trace );
info!( "starting test: close_reason_invalid" );
async
{
let (ws, _wsio) = WsStream::connect( URL, None ).await.expect_throw( "Could not create websocket" );
let res = ws.close_reason( 1000, vec![ "a"; 124 ].join( "" ) ).await;
assert_eq!( &WsErrKind::ReasonStringToLong, res.unwrap_err().kind() );
let r: Result<(), wasm_bindgen::JsValue> = Ok(());
r
}.boxed_local().compat()
}
/*
// Verify protocols.
@@ -140,7 +270,7 @@ pub fn protocols_server_accept_none() -> impl Future01<Item = (), Error = JsValu
{
let _ = console_log::init_with_level( Level::Trace );
console_log!( "starting test: protocols_server_accept_none" );
info!( "starting test: protocols_server_accept_none" );
async
{