Create helpers for config-like functions

As suggested by @agalakhov
pull/27/head
Daniel Abramov 6 years ago
parent 715f9b0241
commit 3a58069db2
  1. 4
      examples/autobahn-client.rs
  2. 2
      examples/autobahn-server.rs
  3. 2
      examples/client.rs
  4. 2
      examples/server.rs
  5. 49
      src/client.rs
  6. 35
      src/server.rs

@ -12,7 +12,6 @@ const AGENT: &'static str = "Tungstenite";
fn get_case_count() -> Result<u32> { fn get_case_count() -> Result<u32> {
let (mut socket, _) = connect( let (mut socket, _) = connect(
Url::parse("ws://localhost:9001/getCaseCount").unwrap(), Url::parse("ws://localhost:9001/getCaseCount").unwrap(),
None,
)?; )?;
let msg = socket.read_message()?; let msg = socket.read_message()?;
socket.close(None)?; socket.close(None)?;
@ -22,7 +21,6 @@ fn get_case_count() -> Result<u32> {
fn update_reports() -> Result<()> { fn update_reports() -> Result<()> {
let (mut socket, _) = connect( let (mut socket, _) = connect(
Url::parse(&format!("ws://localhost:9001/updateReports?agent={}", AGENT)).unwrap(), Url::parse(&format!("ws://localhost:9001/updateReports?agent={}", AGENT)).unwrap(),
None,
)?; )?;
socket.close(None)?; socket.close(None)?;
Ok(()) Ok(())
@ -33,7 +31,7 @@ fn run_test(case: u32) -> Result<()> {
let case_url = Url::parse( let case_url = Url::parse(
&format!("ws://localhost:9001/runCase?case={}&agent={}", case, AGENT) &format!("ws://localhost:9001/runCase?case={}&agent={}", case, AGENT)
).unwrap(); ).unwrap();
let (mut socket, _) = connect(case_url, None)?; let (mut socket, _) = connect(case_url)?;
loop { loop {
match socket.read_message()? { match socket.read_message()? {
msg @ Message::Text(_) | msg @ Message::Text(_) |

@ -16,7 +16,7 @@ fn must_not_block<Role: HandshakeRole>(err: HandshakeError<Role>) -> Error {
} }
fn handle_client(stream: TcpStream) -> Result<()> { fn handle_client(stream: TcpStream) -> Result<()> {
let mut socket = accept(stream, None).map_err(must_not_block)?; let mut socket = accept(stream).map_err(must_not_block)?;
loop { loop {
match socket.read_message()? { match socket.read_message()? {
msg @ Message::Text(_) | msg @ Message::Text(_) |

@ -8,7 +8,7 @@ use tungstenite::{Message, connect};
fn main() { fn main() {
env_logger::init(); env_logger::init();
let (mut socket, response) = connect(Url::parse("ws://localhost:3012/socket").unwrap(), None) let (mut socket, response) = connect(Url::parse("ws://localhost:3012/socket").unwrap())
.expect("Can't connect"); .expect("Can't connect");
println!("Connected to the server"); println!("Connected to the server");

@ -25,7 +25,7 @@ fn main() {
]; ];
Ok(Some(extra_headers)) Ok(Some(extra_headers))
}; };
let mut websocket = accept_hdr(stream.unwrap(), callback, None).unwrap(); let mut websocket = accept_hdr(stream.unwrap(), callback).unwrap();
loop { loop {
let msg = websocket.read_message().unwrap(); let msg = websocket.read_message().unwrap();

@ -68,6 +68,9 @@ use error::{Error, Result};
/// Connect to the given WebSocket in blocking mode. /// Connect to the given WebSocket in blocking mode.
/// ///
/// Uses a websocket configuration passed as an argument to the function. Calling it with `None` is
/// equal to calling `connect()` function.
///
/// The URL may be either ws:// or wss://. /// The URL may be either ws:// or wss://.
/// To support wss:// URLs, feature "tls" must be turned on. /// To support wss:// URLs, feature "tls" must be turned on.
/// ///
@ -78,21 +81,40 @@ use error::{Error, Result};
/// This function uses `native_tls` to do TLS. If you want to use other TLS libraries, /// This function uses `native_tls` to do TLS. If you want to use other TLS libraries,
/// use `client` instead. There is no need to enable the "tls" feature if you don't call /// use `client` instead. There is no need to enable the "tls" feature if you don't call
/// `connect` since it's the only function that uses native_tls. /// `connect` since it's the only function that uses native_tls.
pub fn connect<'t, Req: Into<Request<'t>>>(request: Req, config: Option<WebSocketConfig>) pub fn connect_with_config<'t, Req: Into<Request<'t>>>(
-> Result<(WebSocket<AutoStream>, Response)> request: Req,
{ config: Option<WebSocketConfig>
) -> Result<(WebSocket<AutoStream>, Response)> {
let request: Request = request.into(); let request: Request = request.into();
let mode = url_mode(&request.url)?; let mode = url_mode(&request.url)?;
let addrs = request.url.to_socket_addrs()?; let addrs = request.url.to_socket_addrs()?;
let mut stream = connect_to_some(addrs, &request.url, mode)?; let mut stream = connect_to_some(addrs, &request.url, mode)?;
NoDelay::set_nodelay(&mut stream, true)?; NoDelay::set_nodelay(&mut stream, true)?;
client(request, stream, config) client_with_config(request, stream, config)
.map_err(|e| match e { .map_err(|e| match e {
HandshakeError::Failure(f) => f, HandshakeError::Failure(f) => f,
HandshakeError::Interrupted(_) => panic!("Bug: blocking handshake not blocked"), HandshakeError::Interrupted(_) => panic!("Bug: blocking handshake not blocked"),
}) })
} }
/// Connect to the given WebSocket in blocking mode.
///
/// The URL may be either ws:// or wss://.
/// To support wss:// URLs, feature "tls" must be turned on.
///
/// This function "just works" for those who wants a simple blocking solution
/// similar to `std::net::TcpStream`. If you want a non-blocking or other
/// custom stream, call `client` instead.
///
/// This function uses `native_tls` to do TLS. If you want to use other TLS libraries,
/// use `client` instead. There is no need to enable the "tls" feature if you don't call
/// `connect` since it's the only function that uses native_tls.
pub fn connect<'t, Req: Into<Request<'t>>>(request: Req)
-> Result<(WebSocket<AutoStream>, Response)>
{
connect_with_config(request, None)
}
fn connect_to_some<A>(addrs: A, url: &Url, mode: Mode) -> Result<AutoStream> fn connect_to_some<A>(addrs: A, url: &Url, mode: Mode) -> Result<AutoStream>
where A: Iterator<Item=SocketAddr> where A: Iterator<Item=SocketAddr>
{ {
@ -120,12 +142,13 @@ pub fn url_mode(url: &Url) -> Result<Mode> {
} }
} }
/// Do the client handshake over the given stream. /// Do the client handshake over the given stream given a web socket configuration. Passing `None`
/// as configuration is equal to calling `client()` function.
/// ///
/// Use this function if you need a nonblocking handshake support or if you /// Use this function if you need a nonblocking handshake support or if you
/// want to use a custom stream like `mio::tcp::TcpStream` or `openssl::ssl::SslStream`. /// want to use a custom stream like `mio::tcp::TcpStream` or `openssl::ssl::SslStream`.
/// Any stream supporting `Read + Write` will do. /// Any stream supporting `Read + Write` will do.
pub fn client<'t, Stream, Req>( pub fn client_with_config<'t, Stream, Req>(
request: Req, request: Req,
stream: Stream, stream: Stream,
config: Option<WebSocketConfig>, config: Option<WebSocketConfig>,
@ -136,3 +159,17 @@ where
{ {
ClientHandshake::start(stream, request.into(), config).handshake() ClientHandshake::start(stream, request.into(), config).handshake()
} }
/// Do the client handshake over the given stream.
///
/// Use this function if you need a nonblocking handshake support or if you
/// want to use a custom stream like `mio::tcp::TcpStream` or `openssl::ssl::SslStream`.
/// Any stream supporting `Read + Write` will do.
pub fn client<'t, Stream, Req>(request: Req, stream: Stream)
-> StdResult<(WebSocket<Stream>, Response), HandshakeError<ClientHandshake<Stream>>>
where
Stream: Read + Write,
Req: Into<Request<'t>>,
{
client_with_config(request, stream, None)
}

@ -9,27 +9,56 @@ use protocol::{WebSocket, WebSocketConfig};
use std::io::{Read, Write}; use std::io::{Read, Write};
/// Accept the given Stream as a WebSocket.
///
/// Uses a configuration provided as an argument. Calling it with `None` will use the default one
/// used by `accept()`.
///
/// This function starts a server WebSocket handshake over the given stream.
/// If you want TLS support, use `native_tls::TlsStream` or `openssl::ssl::SslStream`
/// for the stream here. Any `Read + Write` streams are supported, including
/// those from `Mio` and others.
pub fn accept_with_config<S: Read + Write>(stream: S, config: Option<WebSocketConfig>)
-> Result<WebSocket<S>, HandshakeError<ServerHandshake<S, NoCallback>>>
{
accept_hdr_with_config(stream, NoCallback, config)
}
/// Accept the given Stream as a WebSocket. /// Accept the given Stream as a WebSocket.
/// ///
/// This function starts a server WebSocket handshake over the given stream. /// This function starts a server WebSocket handshake over the given stream.
/// If you want TLS support, use `native_tls::TlsStream` or `openssl::ssl::SslStream` /// If you want TLS support, use `native_tls::TlsStream` or `openssl::ssl::SslStream`
/// for the stream here. Any `Read + Write` streams are supported, including /// for the stream here. Any `Read + Write` streams are supported, including
/// those from `Mio` and others. /// those from `Mio` and others.
pub fn accept<S: Read + Write>(stream: S, config: Option<WebSocketConfig>) pub fn accept<S: Read + Write>(stream: S)
-> Result<WebSocket<S>, HandshakeError<ServerHandshake<S, NoCallback>>> -> Result<WebSocket<S>, HandshakeError<ServerHandshake<S, NoCallback>>>
{ {
accept_hdr(stream, NoCallback, config) accept_with_config(stream, None)
} }
/// Accept the given Stream as a WebSocket. /// Accept the given Stream as a WebSocket.
/// ///
/// Uses a configuration provided as an argument. Calling it with `None` will use the default one
/// used by `accept_hdr()`.
///
/// This function does the same as `accept()` but accepts an extra callback /// This function does the same as `accept()` but accepts an extra callback
/// for header processing. The callback receives headers of the incoming /// for header processing. The callback receives headers of the incoming
/// requests and is able to add extra headers to the reply. /// requests and is able to add extra headers to the reply.
pub fn accept_hdr<S: Read + Write, C: Callback>( pub fn accept_hdr_with_config<S: Read + Write, C: Callback>(
stream: S, stream: S,
callback: C, callback: C,
config: Option<WebSocketConfig> config: Option<WebSocketConfig>
) -> Result<WebSocket<S>, HandshakeError<ServerHandshake<S, C>>> { ) -> Result<WebSocket<S>, HandshakeError<ServerHandshake<S, C>>> {
ServerHandshake::start(stream, callback, config).handshake() ServerHandshake::start(stream, callback, config).handshake()
} }
/// Accept the given Stream as a WebSocket.
///
/// This function does the same as `accept()` but accepts an extra callback
/// for header processing. The callback receives headers of the incoming
/// requests and is able to add extra headers to the reply.
pub fn accept_hdr<S: Read + Write, C: Callback>(stream: S, callback: C)
-> Result<WebSocket<S>, HandshakeError<ServerHandshake<S, C>>>
{
accept_hdr_with_config(stream, callback, None)
}

Loading…
Cancel
Save