#![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;
#[cfg(feature = "ssl")]
extern crate openssl;
extern crate rand;
extern crate sha1;
extern crate slab;
extern crate url;
#[macro_use]
extern crate log;
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 = try!(WebSocket::new(factory));
try!(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 = try!(WebSocket::new(factory));
let parsed = try!(url::Url::parse(url.borrow()).map_err(|err| Error::new(
ErrorKind::Internal,
format!("Unable to parse {} as url due to {:?}", url.borrow(), err)
)));
try!(ws.connect(parsed));
try!(ws.run());
Ok(())
}
#[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 in_buffer_capacity: usize,
pub in_buffer_grow: bool,
pub max_in_buffer: usize,
pub out_buffer_capacity: usize,
pub out_buffer_grow: bool,
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,
in_buffer_capacity: 2048,
in_buffer_grow: true,
max_in_buffer: usize::max_value(),
out_buffer_capacity: 2048,
out_buffer_grow: true,
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 try!(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);
try!(sender.connect(url));
Ok(self)
}
pub fn run(mut self) -> Result<WebSocket<F>> {
try!(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, Clone, Copy)]
pub struct Builder {
settings: Settings,
}
impl Builder {
pub fn new() -> Builder {
Builder {
settings: Settings::default(),
}
}
pub fn build<F>(&self, factory: F) -> Result<WebSocket<F>>
where
F: Factory,
{
Ok(WebSocket {
poll: try!(Poll::new()),
handler: io::Handler::new(factory, self.settings),
})
}
pub fn with_settings(&mut self, settings: Settings) -> &mut Builder {
self.settings = settings;
self
}
}