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