Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ws client]: add wss test + refactor WebSocketTransport builder #209

Merged
merged 10 commits into from
Feb 18, 2021

Conversation

niklasad1
Copy link
Member

No description provided.

ws-client/src/transport.rs Outdated Show resolved Hide resolved
ws-client/src/transport.rs Outdated Show resolved Hide resolved
@@ -207,3 +207,10 @@ async fn ws_more_request_than_buffer_should_not_deadlock() {
req.await.unwrap();
}
}

#[tokio::test]
async fn wss_works() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be good to be complete here:

  • assert that ws:// works
  • assert that omitting the port works (and uses the default)
  • assert that providing a wacky port fails, bigger than u16::MAX, negative number, 0 etc
  • assert that host name must be ascii (does it?)

ws-client/src/transport.rs Outdated Show resolved Hide resolved
@@ -37,6 +37,15 @@ use thiserror::Error;

type TlsOrPlain = crate::stream::EitherStream<TcpStream, TlsStream<TcpStream>>;

#[derive(Clone)]
pub struct Host(String);
Copy link
Member Author

@niklasad1 niklasad1 Feb 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Introduced a new type to avoid nasty bugs when several params has the same type.

It could be a pub struct Host<'a>(&'a str)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think String is fine.

@niklasad1
Copy link
Member Author

@dvdplm I think this is ready for another round of review :)


#[tokio::test]
async fn http_with_non_ascii_url_doesnt_hang_or_panic() {
let client = HttpClient::new("http://♥♥♥♥♥♥∀∂", HttpConfig::default()).unwrap();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://docs.rs/url/2.2.0/url/enum.Host.html#variant.Domain is the reason why it's doesn't fail parsing the URL in the constructor.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and in the WebSocket case the host is resolved to a SockAddr because an actual connection is established in the constructor.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL!

_ => return Err(WsHandshakeError::Url("URL scheme not supported, expects 'ws' or 'wss'".into())),
};
let host = url.host_str().ok_or_else(|| WsHandshakeError::Url("No host in URL".into()))?.into();
let sockaddrs: Vec<SocketAddr> = url.socket_addrs(|| None).map_err(WsHandshakeError::ResolutionFailed)?;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

switched to https://docs.rs/url/2.2.0/url/struct.Url.html#method.socket_addrs instead which provides the default port number if it's missing such that we don't have to do it manually anymore

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think we should add a comment stating this and what the default port is?

Copy link
Member Author

@niklasad1 niklasad1 Feb 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the best option is the document this on WsConfig i.e, default ports is ws - 80, wss - 433 ^^

Here we could add a comment that sock_addrs() uses https://docs.rs/url/2.2.0/url/struct.Url.html#method.port_or_known_default if the port is missing

@@ -146,43 +159,8 @@ pub enum WsConnectError {

/// Creates a new WebSocket connection based on [`WsConfig`](crate::WsConfig) represented as a Sender and Receiver pair.
pub async fn websocket_connection(config: WsConfig<'_>) -> Result<(Sender, Receiver), WsHandshakeError> {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you like the change i.e, provide TryFrom<WsConfig> for WebSocketTransportClient { ... } then I think we could remove this function.

Copy link
Contributor

@insipx insipx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@niklasad1 niklasad1 changed the title [ws client]: add wss test [ws client]: add wss test + refactor WebSocketTransport builder Feb 17, 2021
Copy link
Contributor

@dvdplm dvdplm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few minor nits.


#[tokio::test]
async fn http_with_non_ascii_url_doesnt_hang_or_panic() {
let client = HttpClient::new("http://♥♥♥♥♥♥∀∂", HttpConfig::default()).unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL!

@@ -37,6 +37,15 @@ use thiserror::Error;

type TlsOrPlain = crate::stream::EitherStream<TcpStream, TlsStream<TcpStream>>;

#[derive(Clone)]
pub struct Host(String);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think String is fine.

_ => return Err(WsHandshakeError::Url("URL scheme not supported, expects 'ws' or 'wss'".into())),
};
let host = url.host_str().ok_or_else(|| WsHandshakeError::Url("No host in URL".into()))?.into();
let sockaddrs: Vec<SocketAddr> = url.socket_addrs(|| None).map_err(WsHandshakeError::ResolutionFailed)?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think we should add a comment stating this and what the default port is?

"wss" => Mode::Tls,
_ => return Err(WsHandshakeError::Url("URL scheme not supported, expects 'ws' or 'wss'".into())),
};
let host = url.host_str().ok_or_else(|| WsHandshakeError::Url("No host in URL".into()))?.into();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the error case taken care of by the url::Url::parse() call on line 276? Oh, I see, it is None for unix sockets... Ok, fine then.

The error is bit funny though, it's not really a handshaking error. Can we use a more appropriate error?

Copy link
Member Author

@niklasad1 niklasad1 Feb 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error is bit funny though, it's not really a handshaking error. Can we use a more appropriate error?

indeed, let's fix that in another PR.

#217

impl<'a> TryFrom<WsConfig<'a>> for WsTransportClientBuilder<'a> {
type Error = WsHandshakeError;

fn try_from(config: WsConfig<'a>) -> Result<Self, Self::Error> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I quite like this pattern of converting a config into a builder.

@niklasad1 niklasad1 merged commit 1cdd138 into master Feb 18, 2021
@niklasad1 niklasad1 deleted the ws-client-add-wss-test branch February 18, 2021 11:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants