mirror of
https://github.com/tlsnotary/ws_stream_wasm.git
synced 2026-01-08 20:47:57 -05:00
Support close code and reason
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -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
|
||||
|
||||
2
TODO.md
2
TODO.md
@@ -2,8 +2,6 @@
|
||||
|
||||
## Features
|
||||
- include events (pharos)
|
||||
|
||||
- close reason
|
||||
- reconnect?
|
||||
|
||||
## Testing
|
||||
|
||||
14
src/error.rs
14
src/error.rs
@@ -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,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
//
|
||||
|
||||
@@ -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(());
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user