1 //! Lightweight, event-driven WebSockets for Rust.
2 #![allow(deprecated)]
3 #![deny(missing_copy_implementations, trivial_casts, trivial_numeric_casts, unstable_features,
4         unused_import_braces)]
5 
6 extern crate byteorder;
7 extern crate bytes;
8 extern crate httparse;
9 extern crate mio;
10 extern crate mio_extras;
11 #[cfg(feature = "ssl")]
12 extern crate openssl;
13 #[cfg(feature = "nativetls")]
14 extern crate native_tls;
15 extern crate rand;
16 extern crate sha1;
17 extern crate slab;
18 extern crate url;
19 #[macro_use]
20 extern crate log;
21 
22 mod circular_buffer;
23 mod communication;
24 mod connection;
25 mod factory;
26 mod frame;
27 mod handler;
28 mod handshake;
29 mod io;
30 mod message;
31 mod protocol;
32 mod result;
33 mod stream;
34 
35 #[cfg(feature = "permessage-deflate")]
36 pub mod deflate;
37 
38 pub mod util;
39 
40 pub use factory::Factory;
41 pub use handler::Handler;
42 
43 pub use communication::Sender;
44 pub use frame::Frame;
45 pub use handshake::{Handshake, Request, Response};
46 pub use message::Message;
47 pub use protocol::{CloseCode, OpCode};
48 pub use result::Kind as ErrorKind;
49 pub use result::{Error, Result};
50 
51 use std::borrow::Borrow;
52 use std::default::Default;
53 use std::fmt;
54 use std::net::{SocketAddr, ToSocketAddrs};
55 
56 use mio::Poll;
57 
58 /// A utility function for setting up a WebSocket server.
59 ///
60 /// # Safety
61 ///
62 /// This function blocks until the event loop finishes running. Avoid calling this method within
63 /// another WebSocket handler.
64 ///
65 /// # Examples
66 ///
67 /// ```no_run
68 /// use parity_ws::listen;
69 ///
70 /// listen("127.0.0.1:3012", |out| {
71 ///     move |msg| {
72 ///        out.send(msg)
73 ///    }
74 /// }).unwrap()
75 /// ```
76 ///
listen<A, F, H>(addr: A, factory: F) -> Result<()> where A: ToSocketAddrs + fmt::Debug, F: FnMut(Sender) -> H, H: Handler,77 pub fn listen<A, F, H>(addr: A, factory: F) -> Result<()>
78 where
79     A: ToSocketAddrs + fmt::Debug,
80     F: FnMut(Sender) -> H,
81     H: Handler,
82 {
83     let ws = WebSocket::new(factory)?;
84     ws.listen(addr)?;
85     Ok(())
86 }
87 
88 /// A utility function for setting up a WebSocket client.
89 ///
90 /// # Safety
91 ///
92 /// This function blocks until the event loop finishes running. Avoid calling this method within
93 /// another WebSocket handler. If you need to establish a connection from inside of a handler,
94 /// use the `connect` method on the Sender.
95 ///
96 /// # Examples
97 ///
98 /// ```no_run
99 /// use parity_ws::{connect, CloseCode};
100 ///
101 /// connect("ws://127.0.0.1:3012", |out| {
102 ///     out.send("Hello WebSocket").unwrap();
103 ///
104 ///     move |msg| {
105 ///         println!("Got message: {}", msg);
106 ///         out.close(CloseCode::Normal)
107 ///     }
108 /// }).unwrap()
109 /// ```
110 ///
connect<U, F, H>(url: U, factory: F) -> Result<()> where U: Borrow<str>, F: FnMut(Sender) -> H, H: Handler,111 pub fn connect<U, F, H>(url: U, factory: F) -> Result<()>
112 where
113     U: Borrow<str>,
114     F: FnMut(Sender) -> H,
115     H: Handler,
116 {
117     let mut ws = WebSocket::new(factory)?;
118     let parsed = url::Url::parse(url.borrow()).map_err(|err| {
119         Error::new(
120             ErrorKind::Internal,
121             format!("Unable to parse {} as url due to {:?}", url.borrow(), err),
122         )
123     })?;
124     ws.connect(parsed)?;
125     ws.run()?;
126     Ok(())
127 }
128 
129 /// WebSocket settings
130 #[non_exhaustive]
131 #[derive(Debug, Clone, Copy)]
132 pub struct Settings {
133     /// The maximum number of connections that this WebSocket will support.
134     /// The default setting is low and should be increased when expecting more
135     /// connections because this is a hard limit and no new connections beyond
136     /// this limit can be made until an old connection is dropped.
137     /// Default: 100
138     pub max_connections: usize,
139     /// The number of events anticipated per connection. The event loop queue size will
140     /// be `queue_size` * `max_connections`. In order to avoid an overflow error,
141     /// `queue_size` * `max_connections` must be less than or equal to `usize::max_value()`.
142     /// The queue is shared between connections, which means that a connection may schedule
143     /// more events than `queue_size` provided that another connection is using less than
144     /// `queue_size`. However, if the queue is maxed out a Queue error will occur.
145     /// Default: 5
146     pub queue_size: usize,
147     /// Whether to panic when unable to establish a new TCP connection.
148     /// Default: false
149     pub panic_on_new_connection: bool,
150     /// Whether to panic when a shutdown of the WebSocket is requested.
151     /// Default: false
152     pub panic_on_shutdown: bool,
153     /// The maximum number of fragments the connection can handle without reallocating.
154     /// Default: 10
155     pub fragments_capacity: usize,
156     /// Whether to reallocate when `fragments_capacity` is reached. If this is false,
157     /// a Capacity error will be triggered instead.
158     /// Default: true
159     pub fragments_grow: bool,
160     /// The maximum length of outgoing frames. Messages longer than this will be fragmented.
161     /// Default: 65,535
162     pub fragment_size: usize,
163     /// The maximum length of a single frame. Frames longer than this will be rejected.
164     /// Default: unlimited
165     pub max_fragment_size: usize,
166     /// The maximum total length of all incoming frames. Messages longer than this will be rejected.
167     /// Default: unlimited
168     pub max_total_fragments_size: usize,
169     /// The initial size of the incoming buffer. A larger buffer uses more memory but will allow for
170     /// fewer reallocations.
171     /// Default: 2048
172     pub in_buffer_capacity: usize,
173     /// The maximum size to which the incoming buffer can grow. This is a hard limit, and anything
174     /// written to the buffer over this limit will result in an error.
175     /// Default: 10,485,760
176     pub in_buffer_capacity_hard_limit: usize,
177     /// The maximum size to which the incoming buffer should grow. This is a soft limit, so it is
178     /// possible for the buffer to grow over this limit, however once its capacity grows beyond
179     /// this value it will be freed as soon as the buffer is emptied out, and reallocated with
180     /// its initial capacity once it's needed again.
181     /// Default: 1,048,576
182     pub in_buffer_capacity_soft_limit: usize,
183     /// The initial size of the outgoing buffer. A larger buffer uses more memory but will allow for
184     /// fewer reallocations.
185     /// Default: 2048
186     pub out_buffer_capacity: usize,
187     /// The maximum size to which the outgoing buffer can grow. This is a hard limit, and anything
188     /// written to the buffer over this limit will result in an error.
189     /// Default: 10,485,760
190     pub out_buffer_capacity_hard_limit: usize,
191     /// The maximum size to which the outgoing buffer should grow. This is a soft limit, so it is
192     /// possible for the buffer to grow over this limit, however once its capacity grows beyond
193     /// this value it will be freed as soon as the buffer is emptied out, and reallocated with
194     /// its initial capacity once it's needed again.
195     /// Default: 1,048,576
196     pub out_buffer_capacity_soft_limit: usize,
197     /// Whether to panic when an Internal error is encountered. Internal errors should generally
198     /// not occur, so this setting defaults to true as a debug measure, whereas production
199     /// applications should consider setting it to false.
200     /// Default: true
201     pub panic_on_internal: bool,
202     /// Whether to panic when a Capacity error is encountered.
203     /// Default: false
204     pub panic_on_capacity: bool,
205     /// Whether to panic when a Protocol error is encountered.
206     /// Default: false
207     pub panic_on_protocol: bool,
208     /// Whether to panic when an Encoding error is encountered.
209     /// Default: false
210     pub panic_on_encoding: bool,
211     /// Whether to panic when a Queue error is encountered.
212     /// Default: false
213     pub panic_on_queue: bool,
214     /// Whether to panic when an Io error is encountered.
215     /// Default: false
216     pub panic_on_io: bool,
217     /// Whether to panic when a Timer error is encountered.
218     /// Default: false
219     pub panic_on_timeout: bool,
220     /// Whether to shutdown the eventloop when an interrupt is received.
221     /// Default: true
222     pub shutdown_on_interrupt: bool,
223     /// The WebSocket protocol requires frames sent from client endpoints to be masked as a
224     /// security and sanity precaution. Enforcing this requirement, which may be removed at some
225     /// point may cause incompatibilities. If you need the extra security, set this to true.
226     /// Default: false
227     pub masking_strict: bool,
228     /// The WebSocket protocol requires clients to verify the key returned by a server to ensure
229     /// that the server and all intermediaries can perform the protocol. Verifying the key will
230     /// consume processing time and other resources with the benefit that we can fail the
231     /// connection early. The default in WS-RS is to accept any key from the server and instead
232     /// fail late if a protocol error occurs. Change this setting to enable key verification.
233     /// Default: false
234     pub key_strict: bool,
235     /// The WebSocket protocol requires clients to perform an opening handshake using the HTTP
236     /// GET method for the request. However, since only WebSockets are supported on the connection,
237     /// verifying the method of handshake requests is not always necessary. To enforce the
238     /// requirement that handshakes begin with a GET method, set this to true.
239     /// Default: false
240     pub method_strict: bool,
241     /// Indicate whether server connections should use ssl encryption when accepting connections.
242     /// Setting this to true means that clients should use the `wss` scheme to connect to this
243     /// server. Note that using this flag will in general necessitate overriding the
244     /// `Handler::upgrade_ssl_server` method in order to provide the details of the ssl context. It may be
245     /// simpler for most users to use a reverse proxy such as nginx to provide server side
246     /// encryption.
247     ///
248     /// Default: false
249     pub encrypt_server: bool,
250     /// Disables Nagle's algorithm.
251     /// Usually tcp socket tries to accumulate packets to send them all together (every 200ms).
252     /// When enabled socket will try to send packet as fast as possible.
253     ///
254     /// Default: false
255     pub tcp_nodelay: bool,
256 }
257 
258 impl Default for Settings {
default() -> Settings259     fn default() -> Settings {
260         Settings {
261             max_connections: 100,
262             queue_size: 5,
263             panic_on_new_connection: false,
264             panic_on_shutdown: false,
265             fragments_capacity: 10,
266             fragments_grow: true,
267             fragment_size: u16::max_value() as usize,
268             max_fragment_size: usize::max_value(),
269             max_total_fragments_size: usize::max_value(),
270             in_buffer_capacity: 2048,
271             in_buffer_capacity_hard_limit: 10 * 1024 * 1024,
272             in_buffer_capacity_soft_limit: 1024 * 1024,
273             out_buffer_capacity: 2048,
274             out_buffer_capacity_hard_limit: 10 * 1024 * 1024,
275             out_buffer_capacity_soft_limit: 1024 * 1024,
276             panic_on_internal: true,
277             panic_on_capacity: false,
278             panic_on_protocol: false,
279             panic_on_encoding: false,
280             panic_on_queue: false,
281             panic_on_io: false,
282             panic_on_timeout: false,
283             shutdown_on_interrupt: true,
284             masking_strict: false,
285             key_strict: false,
286             method_strict: false,
287             encrypt_server: false,
288             tcp_nodelay: false,
289         }
290     }
291 }
292 
293 /// The WebSocket struct. A WebSocket can support multiple incoming and outgoing connections.
294 pub struct WebSocket<F>
295 where
296     F: Factory,
297 {
298     poll: Poll,
299     handler: io::Handler<F>,
300 }
301 
302 impl<F> WebSocket<F>
303 where
304     F: Factory,
305 {
306     /// Create a new WebSocket using the given Factory to create handlers.
new(factory: F) -> Result<WebSocket<F>>307     pub fn new(factory: F) -> Result<WebSocket<F>> {
308         Builder::new().build(factory)
309     }
310 
311     /// Consume the WebSocket and bind to the specified address.
312     /// If the `addr_spec` yields multiple addresses this will return after the
313     /// first successful bind. `local_addr` can be called to determine which
314     /// address it ended up binding to.
315     /// After the server is successfully bound you should start it using `run`.
bind<A>(mut self, addr_spec: A) -> Result<WebSocket<F>> where A: ToSocketAddrs,316     pub fn bind<A>(mut self, addr_spec: A) -> Result<WebSocket<F>>
317     where
318         A: ToSocketAddrs,
319     {
320         let mut last_error = Error::new(ErrorKind::Internal, "No address given");
321 
322         for addr in addr_spec.to_socket_addrs()? {
323             if let Err(e) = self.handler.listen(&mut self.poll, &addr) {
324                 error!("Unable to listen on {}", addr);
325                 last_error = e;
326             } else {
327                 let actual_addr = self.handler.local_addr().unwrap_or(addr);
328                 info!("Listening for new connections on {}.", actual_addr);
329                 return Ok(self);
330             }
331         }
332 
333         Err(last_error)
334     }
335 
336     /// Consume the WebSocket and listen for new connections on the specified address.
337     ///
338     /// # Safety
339     ///
340     /// This method will block until the event loop finishes running.
listen<A>(self, addr_spec: A) -> Result<WebSocket<F>> where A: ToSocketAddrs,341     pub fn listen<A>(self, addr_spec: A) -> Result<WebSocket<F>>
342     where
343         A: ToSocketAddrs,
344     {
345         self.bind(addr_spec).and_then(|server| server.run())
346     }
347 
348     /// Queue an outgoing connection on this WebSocket. This method may be called multiple times,
349     /// but the actual connections will not be established until `run` is called.
connect(&mut self, url: url::Url) -> Result<&mut WebSocket<F>>350     pub fn connect(&mut self, url: url::Url) -> Result<&mut WebSocket<F>> {
351         let sender = self.handler.sender();
352         info!("Queuing connection to {}", url);
353         sender.connect(url)?;
354         Ok(self)
355     }
356 
357     /// Run the WebSocket. This will run the encapsulated event loop blocking the calling thread until
358     /// the WebSocket is shutdown.
run(mut self) -> Result<WebSocket<F>>359     pub fn run(mut self) -> Result<WebSocket<F>> {
360         self.handler.run(&mut self.poll)?;
361         Ok(self)
362     }
363 
364     /// Get a Sender that can be used to send messages on all connections.
365     /// Calling `send` on this Sender is equivalent to calling `broadcast`.
366     /// Calling `shutdown` on this Sender will shutdown the WebSocket even if no connections have
367     /// been established.
368     #[inline]
broadcaster(&self) -> Sender369     pub fn broadcaster(&self) -> Sender {
370         self.handler.sender()
371     }
372 
373     /// Get the local socket address this socket is bound to. Will return an error
374     /// if the backend returns an error. Will return a `NotFound` error if
375     /// this WebSocket is not a listening socket.
local_addr(&self) -> ::std::io::Result<SocketAddr>376     pub fn local_addr(&self) -> ::std::io::Result<SocketAddr> {
377         self.handler.local_addr()
378     }
379 }
380 
381 /// Utility for constructing a WebSocket from various settings.
382 #[derive(Debug, Default, Clone, Copy)]
383 pub struct Builder {
384     settings: Settings,
385 }
386 
387 // TODO: add convenience methods for each setting
388 impl Builder {
389     /// Create a new Builder with default settings.
new() -> Builder390     pub fn new() -> Builder {
391         Builder::default()
392     }
393 
394     /// Build a WebSocket using this builder and a factory.
395     /// It is possible to use the same builder to create multiple WebSockets.
build<F>(&self, factory: F) -> Result<WebSocket<F>> where F: Factory,396     pub fn build<F>(&self, factory: F) -> Result<WebSocket<F>>
397     where
398         F: Factory,
399     {
400         Ok(WebSocket {
401             poll: Poll::new()?,
402             handler: io::Handler::new(factory, self.settings),
403         })
404     }
405 
406     /// Set the WebSocket settings to use.
with_settings(&mut self, settings: Settings) -> &mut Builder407     pub fn with_settings(&mut self, settings: Settings) -> &mut Builder {
408         self.settings = settings;
409         self
410     }
411 }
412