websocket_simple/
handler.rs

1use url;
2use log::LogLevel::Error as ErrorLevel;
3#[cfg(feature="ssl")]
4use openssl::ssl::{Ssl, SslContext, SslMethod};
5
6use message::Message;
7use frame::Frame;
8use protocol::CloseCode;
9use handshake::{Handshake, Request, Response};
10use result::{Result, Error, Kind};
11
12
13/// The core trait of this library.
14/// Implementing this trait provides the business logic of the WebSocket application.
15pub trait Handler {
16
17    // general
18
19    /// Called when a request to shutdown all connections has been received.
20    #[inline]
21    fn on_shutdown(&mut self) {
22        debug!("Handler received WebSocket shutdown request.");
23    }
24
25    // WebSocket events
26
27    /// Called when the WebSocket handshake is successful and the connection is open for sending
28    /// and receiving messages.
29    fn on_open(&mut self, shake: Handshake) -> Result<()> {
30        if let Some(addr) = try!(shake.remote_addr()) {
31            debug!("Connection with {} now open", addr);
32        }
33        Ok(())
34    }
35
36    /// Called on incoming messages.
37    fn on_message(&mut self, msg: Message) -> Result<()> {
38        debug!("Received message {:?}", msg);
39        Ok(())
40    }
41
42    /// Called any time this endpoint receives a close control frame.
43    /// This may be because the other endpoint is initiating a closing handshake,
44    /// or it may be the other endpoint confirming the handshake initiated by this endpoint.
45    fn on_close(&mut self, code: CloseCode, reason: &str) {
46        debug!("Connection closing due to ({:?}) {}", code, reason);
47    }
48
49    /// Called when an error occurs on the WebSocket.
50    fn on_error(&mut self, err: Error) {
51        // Ignore connection reset errors by default, but allow library clients to see them by
52        // overriding this method if they want
53        if let Kind::Io(ref err) = err.kind {
54            if let Some(104) = err.raw_os_error() {
55                return
56            }
57        }
58
59        error!("{:?}", err);
60        if !log_enabled!(ErrorLevel) {
61            println!("Encountered an error: {}\nEnable a logger to see more information.", err);
62        }
63    }
64
65    // handshake events
66
67    /// A method for handling the low-level workings of the request portion of the WebSocket
68    /// handshake.
69    ///
70    /// Implementors should select a WebSocket protocol and extensions where they are supported.
71    ///
72    /// Implementors can inspect the Request and must return a Response or an error
73    /// indicating that the handshake failed. The default implementation provides conformance with
74    /// the WebSocket protocol, and implementors should use the `Response::from_request` method and
75    /// then modify the resulting response as necessary in order to maintain conformance.
76    ///
77    /// This method will not be called when the handler represents a client endpoint. Use
78    /// `build_request` to provide an initial handshake request.
79    ///
80    /// # Examples
81    ///
82    /// ```ignore
83    /// let mut res = try!(Response::from_request(req));
84    /// if try!(req.extensions()).iter().find(|&&ext| ext.contains("myextension-name")).is_some() {
85    ///     res.add_extension("myextension-name")
86    /// }
87    /// Ok(res)
88    /// ```
89    #[inline]
90    fn on_request(&mut self, req: &Request) -> Result<Response> {
91        debug!("Handler received request:\n{}", req);
92        Response::from_request(req)
93    }
94
95    /// A method for handling the low-level workings of the response portion of the WebSocket
96    /// handshake.
97    ///
98    /// Implementors can inspect the Response and choose to fail the connection by
99    /// returning an error. This method will not be called when the handler represents a server
100    /// endpoint. The response should indicate which WebSocket protocol and extensions the server
101    /// has agreed to if any.
102    #[inline]
103    fn on_response(&mut self, res: &Response) -> Result<()> {
104        debug!("Handler received response:\n{}", res);
105        Ok(())
106    }
107
108
109    // frame events
110
111    /// A method for handling incoming frames.
112    ///
113    /// This method provides very low-level access to the details of the WebSocket protocol. It may
114    /// be necessary to implement this method in order to provide a particular extension, but
115    /// incorrect implementation may cause the other endpoint to fail the connection.
116    ///
117    /// Returning `Ok(None)` will cause the connection to forget about a particular frame. This is
118    /// useful if you want ot filter out a frame or if you don't want any of the default handler
119    /// methods to run.
120    ///
121    /// By default this method simply ensures that no reserved bits are set.
122    #[inline]
123    fn on_frame(&mut self, frame: Frame) -> Result<Option<Frame>> {
124        debug!("Handler received: {}", frame);
125        // default implementation doesn't allow for reserved bits to be set
126        if frame.has_rsv1() || frame.has_rsv2() || frame.has_rsv3() {
127            Err(Error::new(Kind::Protocol, "Encountered frame with reserved bits set."))
128        } else {
129            Ok(Some(frame))
130        }
131    }
132
133    /// A method for handling outgoing frames.
134    ///
135    /// This method provides very low-level access to the details of the WebSocket protocol. It may
136    /// be necessary to implement this method in order to provide a particular extension, but
137    /// incorrect implementation may cause the other endpoint to fail the connection.
138    ///
139    /// Returning `Ok(None)` will cause the connection to forget about a particular frame, meaning
140    /// that it will not be sent. You can use this approach to merge multiple frames into a single
141    /// frame before sending the message.
142    ///
143    /// For messages, this method will be called with a single complete, final frame before any
144    /// fragmentation is performed. Automatic fragmentation will be performed on the returned
145    /// frame, if any, based on the `fragment_size` setting.
146    ///
147    /// By default this method simply ensures that no reserved bits are set.
148    #[inline]
149    fn on_send_frame(&mut self, frame: Frame) -> Result<Option<Frame>> {
150        // debug!("Handler will send: {}", frame);
151        // default implementation doesn't allow for reserved bits to be set
152        if frame.has_rsv1() || frame.has_rsv2() || frame.has_rsv3() {
153            Err(Error::new(Kind::Protocol, "Encountered frame with reserved bits set."))
154        } else {
155            Ok(Some(frame))
156        }
157    }
158
159    // constructors
160
161    /// A method for creating the initial handshake request for WebSocket clients.
162    ///
163    /// The default implementation provides conformance with the WebSocket protocol, but this
164    /// method may be overriden. In order to facilitate conformance,
165    /// implementors should use the `Request::from_url` method and then modify the resulting
166    /// request as necessary.
167    ///
168    /// Implementors should indicate any available WebSocket extensions here.
169    ///
170    /// # Examples
171    /// ```ignore
172    /// let mut req = try!(Request::from_url(url));
173    /// req.add_extension("permessage-deflate; client_max_window_bits");
174    /// Ok(req)
175    /// ```
176    #[inline]
177    fn build_request(&mut self, url: &url::Url) -> Result<Request> {
178        // debug!("Handler is building request from {}.", url);
179        Request::from_url(url)
180    }
181
182    /// A method for obtaining an Ssl object for use in wss connections.
183    ///
184    /// Override this method to customize the Ssl object used to encrypt the connection.
185    #[inline]
186    #[cfg(feature="ssl")]
187    fn build_ssl(&mut self) -> Result<Ssl> {
188        let context = try!(SslContext::new(SslMethod::Tlsv1));
189        Ssl::new(&context).map_err(Error::from)
190    }
191}
192
193impl<F> Handler for F
194    where F: Fn(Message) -> Result<()>
195{
196    fn on_message(&mut self, msg: Message) -> Result<()> {
197        self(msg)
198    }
199}