#![allow(deprecated)]
#![deny(missing_copy_implementations, trivial_casts, trivial_numeric_casts, unstable_features,
unused_import_braces)]
extern crate byteorder;
extern crate bytes;
extern crate httparse;
extern crate mio;
extern crate mio_extras;
#[cfg(feature = "ssl")]
extern crate openssl;
#[cfg(feature = "nativetls")]
extern crate native_tls;
extern crate rand;
extern crate sha1;
extern crate slab;
extern crate url;
#[macro_use]
extern crate log;
mod circular_buffer;
mod communication;
mod connection;
mod factory;
mod frame;
mod handler;
mod handshake;
mod io;
mod message;
mod protocol;
mod result;
mod stream;
#[cfg(feature = "permessage-deflate")]
pub mod deflate;
pub mod util;
pub use factory::Factory;
pub use handler::Handler;
pub use communication::Sender;
pub use frame::Frame;
pub use handshake::{Handshake, Request, Response};
pub use message::Message;
pub use protocol::{CloseCode, OpCode};
pub use result::Kind as ErrorKind;
pub use result::{Error, Result};
use std::borrow::Borrow;
use std::default::Default;
use std::fmt;
use std::net::{SocketAddr, ToSocketAddrs};
use mio::Poll;
pub fn listen<A, F, H>(addr: A, factory: F) -> Result<()>
where
A: ToSocketAddrs + fmt::Debug,
F: FnMut(Sender) -> H,
H: Handler,
{
let ws = WebSocket::new(factory)?;
ws.listen(addr)?;
Ok(())
}
pub fn connect<U, F, H>(url: U, factory: F) -> Result<()>
where
U: Borrow<str>,
F: FnMut(Sender) -> H,
H: Handler,
{
let mut ws = WebSocket::new(factory)?;
let parsed = url::Url::parse(url.borrow()).map_err(|err| {
Error::new(
ErrorKind::Internal,
format!("Unable to parse {} as url due to {:?}", url.borrow(), err),
)
})?;
ws.connect(parsed)?;
ws.run()?;
Ok(())
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy)]
pub struct Settings {
pub max_connections: usize,
pub queue_size: usize,
pub panic_on_new_connection: bool,
pub panic_on_shutdown: bool,
pub fragments_capacity: usize,
pub fragments_grow: bool,
pub fragment_size: usize,
pub max_fragment_size: usize,
pub max_total_fragments_size: usize,
pub in_buffer_capacity: usize,
pub in_buffer_capacity_hard_limit: usize,
pub in_buffer_capacity_soft_limit: usize,
pub out_buffer_capacity: usize,
pub out_buffer_capacity_hard_limit: usize,
pub out_buffer_capacity_soft_limit: usize,
pub panic_on_internal: bool,
pub panic_on_capacity: bool,
pub panic_on_protocol: bool,
pub panic_on_encoding: bool,
pub panic_on_queue: bool,
pub panic_on_io: bool,
pub panic_on_timeout: bool,
pub shutdown_on_interrupt: bool,
pub masking_strict: bool,
pub key_strict: bool,
pub method_strict: bool,
pub encrypt_server: bool,
pub tcp_nodelay: bool,
}
impl Default for Settings {
fn default() -> Settings {
Settings {
max_connections: 100,
queue_size: 5,
panic_on_new_connection: false,
panic_on_shutdown: false,
fragments_capacity: 10,
fragments_grow: true,
fragment_size: u16::max_value() as usize,
max_fragment_size: usize::max_value(),
max_total_fragments_size: usize::max_value(),
in_buffer_capacity: 2048,
in_buffer_capacity_hard_limit: 10 * 1024 * 1024,
in_buffer_capacity_soft_limit: 1024 * 1024,
out_buffer_capacity: 2048,
out_buffer_capacity_hard_limit: 10 * 1024 * 1024,
out_buffer_capacity_soft_limit: 1024 * 1024,
panic_on_internal: true,
panic_on_capacity: false,
panic_on_protocol: false,
panic_on_encoding: false,
panic_on_queue: false,
panic_on_io: false,
panic_on_timeout: false,
shutdown_on_interrupt: true,
masking_strict: false,
key_strict: false,
method_strict: false,
encrypt_server: false,
tcp_nodelay: false,
}
}
}
pub struct WebSocket<F>
where
F: Factory,
{
poll: Poll,
handler: io::Handler<F>,
}
impl<F> WebSocket<F>
where
F: Factory,
{
pub fn new(factory: F) -> Result<WebSocket<F>> {
Builder::new().build(factory)
}
pub fn bind<A>(mut self, addr_spec: A) -> Result<WebSocket<F>>
where
A: ToSocketAddrs,
{
let mut last_error = Error::new(ErrorKind::Internal, "No address given");
for addr in addr_spec.to_socket_addrs()? {
if let Err(e) = self.handler.listen(&mut self.poll, &addr) {
error!("Unable to listen on {}", addr);
last_error = e;
} else {
let actual_addr = self.handler.local_addr().unwrap_or(addr);
info!("Listening for new connections on {}.", actual_addr);
return Ok(self);
}
}
Err(last_error)
}
pub fn listen<A>(self, addr_spec: A) -> Result<WebSocket<F>>
where
A: ToSocketAddrs,
{
self.bind(addr_spec).and_then(|server| server.run())
}
pub fn connect(&mut self, url: url::Url) -> Result<&mut WebSocket<F>> {
let sender = self.handler.sender();
info!("Queuing connection to {}", url);
sender.connect(url)?;
Ok(self)
}
pub fn run(mut self) -> Result<WebSocket<F>> {
self.handler.run(&mut self.poll)?;
Ok(self)
}
#[inline]
pub fn broadcaster(&self) -> Sender {
self.handler.sender()
}
pub fn local_addr(&self) -> ::std::io::Result<SocketAddr> {
self.handler.local_addr()
}
}
#[derive(Debug, Default, Clone, Copy)]
pub struct Builder {
settings: Settings,
}
impl Builder {
pub fn new() -> Builder {
Builder::default()
}
pub fn build<F>(&self, factory: F) -> Result<WebSocket<F>>
where
F: Factory,
{
Ok(WebSocket {
poll: Poll::new()?,
handler: io::Handler::new(factory, self.settings),
})
}
pub fn with_settings(&mut self, settings: Settings) -> &mut Builder {
self.settings = settings;
self
}
}