WebSocket++  0.8.3-dev
C++ websocket client/server library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
connection.hpp
1 /*
2  * Copyright (c) 2014, Peter Thorson. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  * * Redistributions of source code must retain the above copyright
7  * notice, this list of conditions and the following disclaimer.
8  * * Redistributions in binary form must reproduce the above copyright
9  * notice, this list of conditions and the following disclaimer in the
10  * documentation and/or other materials provided with the distribution.
11  * * Neither the name of the WebSocket++ Project nor the
12  * names of its contributors may be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  */
27 
28 #ifndef WEBSOCKETPP_CONNECTION_HPP
29 #define WEBSOCKETPP_CONNECTION_HPP
30 
31 #include <websocketpp/close.hpp>
32 #include <websocketpp/error.hpp>
33 #include <websocketpp/frame.hpp>
34 
35 #include <websocketpp/logger/levels.hpp>
36 #include <websocketpp/processors/processor.hpp>
37 #include <websocketpp/transport/base/connection.hpp>
38 #include <websocketpp/http/constants.hpp>
39 
40 #include <websocketpp/common/connection_hdl.hpp>
41 #include <websocketpp/common/cpp11.hpp>
42 #include <websocketpp/common/functional.hpp>
43 
44 #include <queue>
45 #include <sstream>
46 #include <string>
47 #include <vector>
48 
49 namespace websocketpp {
50 
51 /// The type and function signature of an open handler
52 /**
53  * The open handler is called once for every successful WebSocket connection
54  * attempt. Either the fail handler or the open handler will be called for each
55  * WebSocket connection attempt. HTTP Connections that did not attempt to
56  * upgrade the connection to the WebSocket protocol will trigger the http
57  * handler instead of fail/open.
58  */
60 
61 /// The type and function signature of a close handler
62 /**
63  * The close handler is called once for every successfully established
64  * connection after it is no longer capable of sending or receiving new messages
65  *
66  * The close handler will be called exactly once for every connection for which
67  * the open handler was called.
68  */
70 
71 /// The type and function signature of a fail handler
72 /**
73  * The fail handler is called once for every unsuccessful WebSocket connection
74  * attempt. Either the fail handler or the open handler will be called for each
75  * WebSocket connection attempt. HTTP Connections that did not attempt to
76  * upgrade the connection to the WebSocket protocol will trigger the http
77  * handler instead of fail/open.
78  */
80 
81 /// The type and function signature of an interrupt handler
82 /**
83  * The interrupt handler is called when a connection receives an interrupt
84  * request from the application. Interrupts allow the application to trigger a
85  * handler to be run in the absense of a WebSocket level handler trigger (like
86  * a new message).
87  *
88  * This is typically used by another application thread to schedule some tasks
89  * that can only be run from within the handler chain for thread safety reasons.
90  */
92 
93 /// The type and function signature of a ping handler
94 /**
95  * The ping handler is called when the connection receives a WebSocket ping
96  * control frame. The string argument contains the ping payload. The payload is
97  * a binary string up to 126 bytes in length. The ping handler returns a bool,
98  * true if a pong response should be sent, false if the pong response should be
99  * suppressed.
100  */
102 
103 /// The type and function signature of a pong handler
104 /**
105  * The pong handler is called when the connection receives a WebSocket pong
106  * control frame. The string argument contains the pong payload. The payload is
107  * a binary string up to 126 bytes in length.
108  */
110 
111 /// The type and function signature of a pong timeout handler
112 /**
113  * The pong timeout handler is called when a ping goes unanswered by a pong for
114  * longer than the locally specified timeout period.
115  */
117 
118 /// The type and function signature of a validate handler
119 /**
120  * The validate handler is called after a WebSocket handshake has been received
121  * and processed but before it has been accepted. This gives the application a
122  * chance to implement connection details specific policies for accepting
123  * connections and the ability to negotiate extensions and subprotocols.
124  *
125  * The validate handler return value indicates whether or not the connection
126  * should be accepted. Additional methods may be called during the function to
127  * set response headers, set HTTP return/error codes, etc.
128  */
130 
131 /// The type and function signature of a http handler
132 /**
133  * The http handler is called when an HTTP connection is made that does not
134  * attempt to upgrade the connection to the WebSocket protocol. This allows
135  * WebSocket++ servers to respond to these requests with regular HTTP responses.
136  *
137  * This can be used to deliver error pages & dashboards and to deliver static
138  * files such as the base HTML & JavaScript for an otherwise single page
139  * WebSocket application.
140  *
141  * Note: WebSocket++ is designed to be a high performance WebSocket server. It
142  * is not tuned to provide a full featured, high performance, HTTP web server
143  * solution. The HTTP handler is appropriate only for low volume HTTP traffic.
144  * If you expect to serve high volumes of HTTP traffic a dedicated HTTP web
145  * server is strongly recommended.
146  *
147  * The default HTTP handler will return a 426 Upgrade Required error. Custom
148  * handlers may override the response status code to deliver any type of
149  * response.
150  */
152 
153 //
154 typedef lib::function<void(lib::error_code const & ec, size_t bytes_transferred)> read_handler;
155 typedef lib::function<void(lib::error_code const & ec)> write_frame_handler;
156 
157 // constants related to the default WebSocket protocol versions available
158 #ifdef _WEBSOCKETPP_INITIALIZER_LISTS_ // simplified C++11 version
159  /// Container that stores the list of protocol versions supported
160  /**
161  * @todo Move this to configs to allow compile/runtime disabling or enabling
162  * of protocol versions
163  */
164  static std::vector<int> const versions_supported = {0,7,8,13};
165 #else
166  /// Helper array to get around lack of initializer lists pre C++11
167  static int const helper[] = {0,7,8,13};
168  /// Container that stores the list of protocol versions supported
169  /**
170  * @todo Move this to configs to allow compile/runtime disabling or enabling
171  * of protocol versions
172  */
173  static std::vector<int> const versions_supported(helper,helper+4);
174 #endif
175 
176 namespace session {
177 namespace state {
178  // externally visible session state (states based on the RFC)
179  enum value {
180  connecting = 0,
181  open = 1,
182  closing = 2,
183  closed = 3
184  };
185 } // namespace state
186 
187 
188 namespace fail {
189 namespace status {
190  enum value {
191  GOOD = 0, // no failure yet!
192  SYSTEM = 1, // system call returned error, check that code
193  WEBSOCKET = 2, // websocket close codes contain error
194  UNKNOWN = 3, // No failure information is available
195  TIMEOUT_TLS = 4, // TLS handshake timed out
196  TIMEOUT_WS = 5 // WS handshake timed out
197  };
198 } // namespace status
199 } // namespace fail
200 
201 namespace internal_state {
202  // More granular internal states. These are used for multi-threaded
203  // connection synchronization and preventing values that are not yet or no
204  // longer available from being used.
205 
206  enum value {
207  USER_INIT = 0,
208  TRANSPORT_INIT = 1,
209  READ_HTTP_REQUEST = 2,
210  WRITE_HTTP_REQUEST = 3,
211  READ_HTTP_RESPONSE = 4,
212  WRITE_HTTP_RESPONSE = 5,
213  PROCESS_HTTP_REQUEST = 6,
214  PROCESS_CONNECTION = 7
215  };
216 } // namespace internal_state
217 
218 
219 namespace http_state {
220  // states to keep track of the progress of http connections
221 
222  enum value {
223  init = 0,
224  deferred = 1,
225  headers_written = 2,
226  body_written = 3,
227  closed = 4
228  };
229 } // namespace http_state
230 
231 } // namespace session
232 
233 /// Represents an individual WebSocket connection
234 template <typename config>
236  : public config::transport_type::transport_con_type
237  , public config::connection_base
238 {
239 public:
240  /// Type of this connection
241  typedef connection<config> type;
242  /// Type of a shared pointer to this connection
243  typedef lib::shared_ptr<type> ptr;
244  /// Type of a weak pointer to this connection
246 
247  /// Type of the concurrency component of this connection
248  typedef typename config::concurrency_type concurrency_type;
249  /// Type of the access logging policy
250  typedef typename config::alog_type alog_type;
251  /// Type of the error logging policy
252  typedef typename config::elog_type elog_type;
253 
254  /// Type of the transport component of this connection
255  typedef typename config::transport_type::transport_con_type
257  /// Type of a shared pointer to the transport component of this connection
259 
260  typedef lib::function<void(ptr)> termination_handler;
261 
262  typedef typename concurrency_type::scoped_lock_type scoped_lock_type;
263  typedef typename concurrency_type::mutex_type mutex_type;
264 
265  typedef typename config::request_type request_type;
266  typedef typename config::response_type response_type;
267 
268  typedef typename config::message_type message_type;
269  typedef typename message_type::ptr message_ptr;
270 
271  typedef typename config::con_msg_manager_type con_msg_manager_type;
272  typedef typename con_msg_manager_type::ptr con_msg_manager_ptr;
273 
274  /// Type of RNG
275  typedef typename config::rng_type rng_type;
276 
278  typedef lib::shared_ptr<processor_type> processor_ptr;
279 
280  // Message handler (needs to know message type)
281  typedef lib::function<void(connection_hdl,message_ptr)> message_handler;
282 
283  /// Type of a pointer to a transport timer handle
285 
286  // Misc Convenience Types
287  typedef session::internal_state::value istate_type;
288 
289 private:
290  enum terminate_status {
291  failed = 1,
292  closed,
293  unknown
294  };
295 public:
296 
297  explicit connection(bool p_is_server, std::string const & ua, const lib::shared_ptr<alog_type>& alog,
298  const lib::shared_ptr<elog_type>& elog, rng_type & rng)
299  : transport_con_type(p_is_server, alog, elog)
300  , m_handle_read_frame(lib::bind(
301  &type::handle_read_frame,
302  this,
303  lib::placeholders::_1,
304  lib::placeholders::_2
305  ))
306  , m_write_frame_handler(lib::bind(
307  &type::handle_write_frame,
308  this,
309  lib::placeholders::_1
310  ))
311  , m_user_agent(ua)
312  , m_open_handshake_timeout_dur(config::timeout_open_handshake)
313  , m_close_handshake_timeout_dur(config::timeout_close_handshake)
314  , m_pong_timeout_dur(config::timeout_pong)
315  , m_max_message_size(config::max_message_size)
316  , m_state(session::state::connecting)
317  , m_internal_state(session::internal_state::USER_INIT)
318  , m_msg_manager(new con_msg_manager_type())
319  , m_send_buffer_size(0)
320  , m_write_flag(false)
321  , m_read_flag(true)
322  , m_is_server(p_is_server)
323  , m_alog(alog)
324  , m_elog(elog)
325  , m_rng(rng)
326  , m_local_close_code(close::status::abnormal_close)
327  , m_remote_close_code(close::status::abnormal_close)
328  , m_is_http(false)
329  , m_http_state(session::http_state::init)
330  , m_was_clean(false)
331  {
332  m_alog->write(log::alevel::devel,"connection constructor");
333  }
334 
335  /// Get a shared pointer to this component
337  return lib::static_pointer_cast<type>(transport_con_type::get_shared());
338  }
339 
340  ///////////////////////////
341  // Set Handler Callbacks //
342  ///////////////////////////
343 
344  /// Set open handler
345  /**
346  * The open handler is called after the WebSocket handshake is complete and
347  * the connection is considered OPEN.
348  *
349  * @param h The new open_handler
350  */
352  m_open_handler = h;
353  }
354 
355  /// Set close handler
356  /**
357  * The close handler is called immediately after the connection is closed.
358  *
359  * @param h The new close_handler
360  */
362  m_close_handler = h;
363  }
364 
365  /// Set fail handler
366  /**
367  * The fail handler is called whenever the connection fails while the
368  * handshake is bring processed.
369  *
370  * @param h The new fail_handler
371  */
373  m_fail_handler = h;
374  }
375 
376  /// Set ping handler
377  /**
378  * The ping handler is called whenever the connection receives a ping
379  * control frame. The ping payload is included.
380  *
381  * The ping handler's return time controls whether or not a pong is
382  * sent in response to this ping. Returning false will suppress the
383  * return pong. If no ping handler is set a pong will be sent.
384  *
385  * @param h The new ping_handler
386  */
388  m_ping_handler = h;
389  }
390 
391  /// Set pong handler
392  /**
393  * The pong handler is called whenever the connection receives a pong
394  * control frame. The pong payload is included.
395  *
396  * @param h The new pong_handler
397  */
399  m_pong_handler = h;
400  }
401 
402  /// Set pong timeout handler
403  /**
404  * If the transport component being used supports timers, the pong timeout
405  * handler is called whenever a pong control frame is not received with the
406  * configured timeout period after the application sends a ping.
407  *
408  * The config setting `timeout_pong` controls the length of the timeout
409  * period. It is specified in milliseconds.
410  *
411  * This can be used to probe the health of the remote endpoint's WebSocket
412  * implementation. This does not guarantee that the remote application
413  * itself is still healthy but can be a useful diagnostic.
414  *
415  * Note: receipt of this callback doesn't mean the pong will never come.
416  * This functionality will not suppress delivery of the pong in question
417  * should it arrive after the timeout.
418  *
419  * @param h The new pong_timeout_handler
420  */
422  m_pong_timeout_handler = h;
423  }
424 
425  /// Set interrupt handler
426  /**
427  * The interrupt handler is called whenever the connection is manually
428  * interrupted by the application.
429  *
430  * @param h The new interrupt_handler
431  */
433  m_interrupt_handler = h;
434  }
435 
436  /// Set http handler
437  /**
438  * The http handler is called after an HTTP request other than a WebSocket
439  * upgrade request is received. It allows a WebSocket++ server to respond
440  * to regular HTTP requests on the same port as it processes WebSocket
441  * connections. This can be useful for hosting error messages, flash
442  * policy files, status pages, and other simple HTTP responses. It is not
443  * intended to be used as a primary web server.
444  *
445  * @param h The new http_handler
446  */
448  m_http_handler = h;
449  }
450 
451  /// Set validate handler
452  /**
453  * The validate handler is called after a WebSocket handshake has been
454  * parsed but before a response is returned. It provides the application
455  * a chance to examine the request and determine whether or not it wants
456  * to accept the connection.
457  *
458  * Returning false from the validate handler will reject the connection.
459  * If no validate handler is present, all connections will be allowed.
460  *
461  * @param h The new validate_handler
462  */
464  m_validate_handler = h;
465  }
466 
467  /// Set message handler
468  /**
469  * The message handler is called after a new message has been received.
470  *
471  * @param h The new message_handler
472  */
473  void set_message_handler(message_handler h) {
474  m_message_handler = h;
475  }
476 
477  //////////////////////////////////////////
478  // Connection timeouts and other limits //
479  //////////////////////////////////////////
480 
481  /// Set open handshake timeout
482  /**
483  * Sets the length of time the library will wait after an opening handshake
484  * has been initiated before cancelling it. This can be used to prevent
485  * excessive wait times for outgoing clients or excessive resource usage
486  * from broken clients or DoS attacks on servers.
487  *
488  * Connections that time out will have their fail handlers called with the
489  * open_handshake_timeout error code.
490  *
491  * The default value is specified via the compile time config value
492  * 'timeout_open_handshake'. The default value in the core config
493  * is 5000ms. A value of 0 will disable the timer entirely.
494  *
495  * To be effective, the transport you are using must support timers. See
496  * the documentation for your transport policy for details about its
497  * timer support.
498  *
499  * @param dur The length of the open handshake timeout in ms
500  */
501  void set_open_handshake_timeout(long dur) {
502  m_open_handshake_timeout_dur = dur;
503  }
504 
505  /// Set close handshake timeout
506  /**
507  * Sets the length of time the library will wait after a closing handshake
508  * has been initiated before cancelling it. This can be used to prevent
509  * excessive wait times for outgoing clients or excessive resource usage
510  * from broken clients or DoS attacks on servers.
511  *
512  * Connections that time out will have their close handlers called with the
513  * close_handshake_timeout error code.
514  *
515  * The default value is specified via the compile time config value
516  * 'timeout_close_handshake'. The default value in the core config
517  * is 5000ms. A value of 0 will disable the timer entirely.
518  *
519  * To be effective, the transport you are using must support timers. See
520  * the documentation for your transport policy for details about its
521  * timer support.
522  *
523  * @param dur The length of the close handshake timeout in ms
524  */
526  m_close_handshake_timeout_dur = dur;
527  }
528 
529  /// Set pong timeout
530  /**
531  * Sets the length of time the library will wait for a pong response to a
532  * ping. This can be used as a keepalive or to detect broken connections.
533  *
534  * Pong responses that time out will have the pong timeout handler called.
535  *
536  * The default value is specified via the compile time config value
537  * 'timeout_pong'. The default value in the core config
538  * is 5000ms. A value of 0 will disable the timer entirely.
539  *
540  * To be effective, the transport you are using must support timers. See
541  * the documentation for your transport policy for details about its
542  * timer support.
543  *
544  * @param dur The length of the pong timeout in ms
545  */
546  void set_pong_timeout(long dur) {
547  m_pong_timeout_dur = dur;
548  }
549 
550  /// Get maximum message size
551  /**
552  * Get maximum message size. Maximum message size determines the point at
553  * which the connection will fail with the message_too_big protocol error.
554  *
555  * The default is set by the endpoint that creates the connection.
556  *
557  * @since 0.3.0
558  */
560  return m_max_message_size;
561  }
562 
563  /// Set maximum message size
564  /**
565  * Set maximum message size. Maximum message size determines the point at
566  * which the connection will fail with the message_too_big protocol error.
567  * This value may be changed during the connection.
568  *
569  * The default is set by the endpoint that creates the connection.
570  *
571  * @since 0.3.0
572  *
573  * @param new_value The value to set as the maximum message size.
574  */
575  void set_max_message_size(size_t new_value) {
576  m_max_message_size = new_value;
577  if (m_processor) {
578  m_processor->set_max_message_size(new_value);
579  }
580  }
581 
582  /// Get maximum HTTP message body size
583  /**
584  * Get maximum HTTP message body size. Maximum message body size determines
585  * the point at which the connection will stop reading an HTTP request whose
586  * body is too large.
587  *
588  * The default is set by the endpoint that creates the connection.
589  *
590  * @since 0.5.0
591  *
592  * @return The maximum HTTP message body size
593  */
595  return m_request.get_max_body_size();
596  }
597 
598  /// Set maximum HTTP message body size
599  /**
600  * Set maximum HTTP message body size. Maximum message body size determines
601  * the point at which the connection will stop reading an HTTP request whose
602  * body is too large.
603  *
604  * The default is set by the endpoint that creates the connection.
605  *
606  * @since 0.5.0
607  *
608  * @param new_value The value to set as the maximum message size.
609  */
610  void set_max_http_body_size(size_t new_value) {
611  m_request.set_max_body_size(new_value);
612  }
613 
614  //////////////////////////////////
615  // Uncategorized public methods //
616  //////////////////////////////////
617 
618  /// Get the size of the outgoing write buffer (in payload bytes)
619  /**
620  * Retrieves the number of bytes in the outgoing write buffer that have not
621  * already been dispatched to the transport layer. This represents the bytes
622  * that are presently cancelable without uncleanly ending the websocket
623  * connection
624  *
625  * This method invokes the m_write_lock mutex
626  *
627  * @return The current number of bytes in the outgoing send buffer.
628  */
629  size_t get_buffered_amount() const;
630 
631  /// Get the size of the outgoing write buffer (in payload bytes)
632  /**
633  * @deprecated use `get_buffered_amount` instead
634  */
636  return get_buffered_amount();
637  }
638 
639  ////////////////////
640  // Action Methods //
641  ////////////////////
642 
643  /// Create a message and then add it to the outgoing send queue
644  /**
645  * Convenience method to send a message given a payload string and
646  * optionally an opcode. Default opcode is utf8 text.
647  *
648  * This method locks the m_write_lock mutex
649  *
650  * @param payload The payload string to generated the message with
651  *
652  * @param op The opcode to generated the message with. Default is
653  * frame::opcode::text
654  */
656  frame::opcode::text);
657 
658  /// Send a message (raw array overload)
659  /**
660  * Convenience method to send a message given a raw array and optionally an
661  * opcode. Default opcode is binary.
662  *
663  * This method locks the m_write_lock mutex
664  *
665  * @param payload A pointer to the array containing the bytes to send.
666  *
667  * @param len Length of the array.
668  *
669  * @param op The opcode to generated the message with. Default is
670  * frame::opcode::binary
671  */
672  lib::error_code send(void const * payload, size_t len, frame::opcode::value
673  op = frame::opcode::binary);
674 
675  /// Add a message to the outgoing send queue
676  /**
677  * If presented with a prepared message it is added without validation or
678  * framing. If presented with an unprepared message it is validated, framed,
679  * and then added
680  *
681  * Errors are returned via an exception
682  * \todo make exception system_error rather than error_code
683  *
684  * This method invokes the m_write_lock mutex
685  *
686  * @param msg A message_ptr to the message to send.
687  */
689 
690  /// Asyncronously invoke handler::on_inturrupt
691  /**
692  * Signals to the connection to asyncronously invoke the on_inturrupt
693  * callback for this connection's handler once it is safe to do so.
694  *
695  * When the on_inturrupt handler callback is called it will be from
696  * within the transport event loop with all the thread safety features
697  * guaranteed by the transport to regular handlers
698  *
699  * Multiple inturrupt signals can be active at once on the same connection
700  *
701  * @return An error code
702  */
704 
705  /// Transport inturrupt callback
706  void handle_interrupt();
707 
708  /// Pause reading of new data
709  /**
710  * Signals to the connection to halt reading of new data. While reading is paused,
711  * the connection will stop reading from its associated socket. In turn this will
712  * result in TCP based flow control kicking in and slowing data flow from the remote
713  * endpoint.
714  *
715  * This is useful for applications that push new requests to a queue to be processed
716  * by another thread and need a way to signal when their request queue is full without
717  * blocking the network processing thread.
718  *
719  * Use `resume_reading()` to resume.
720  *
721  * If supported by the transport this is done asynchronously. As such reading may not
722  * stop until the current read operation completes. Typically you can expect to
723  * receive no more bytes after initiating a read pause than the size of the read
724  * buffer.
725  *
726  * If reading is paused for this connection already nothing is changed.
727  */
729 
730  /// Pause reading callback
731  void handle_pause_reading();
732 
733  /// Resume reading of new data
734  /**
735  * Signals to the connection to resume reading of new data after it was paused by
736  * `pause_reading()`.
737  *
738  * If reading is not paused for this connection already nothing is changed.
739  */
741 
742  /// Resume reading callback
743  void handle_resume_reading();
744 
745  /// Send a ping
746  /**
747  * Initiates a ping with the given payload/
748  *
749  * There is no feedback directly from ping except in cases of immediately
750  * detectable errors. Feedback will be provided via on_pong or
751  * on_pong_timeout callbacks.
752  *
753  * Ping locks the m_write_lock mutex
754  *
755  * @param payload Payload to be used for the ping
756  */
757  void ping(std::string const & payload);
758 
759  /// exception free variant of ping
760  void ping(std::string const & payload, lib::error_code & ec);
761 
762  /// Utility method that gets called back when the ping timer expires
763  void handle_pong_timeout(std::string payload, lib::error_code const & ec);
764 
765  /// Send a pong
766  /**
767  * Initiates a pong with the given payload.
768  *
769  * There is no feedback from a pong once sent.
770  *
771  * Pong locks the m_write_lock mutex
772  *
773  * @param payload Payload to be used for the pong
774  */
775  void pong(std::string const & payload);
776 
777  /// exception free variant of pong
778  void pong(std::string const & payload, lib::error_code & ec);
779 
780  /// Close the connection
781  /**
782  * Initiates the close handshake process.
783  *
784  * If close returns successfully the connection will be in the closing
785  * state and no additional messages may be sent. All messages sent prior
786  * to calling close will be written out before the connection is closed.
787  *
788  * If no reason is specified none will be sent. If no code is specified
789  * then no code will be sent.
790  *
791  * The handler's on_close callback will be called once the close handshake
792  * is complete.
793  *
794  * Reasons will be automatically truncated to the maximum length (123 bytes)
795  * if necessary.
796  *
797  * @param code The close code to send
798  * @param reason The close reason to send
799  */
800  void close(close::status::value const code, std::string const & reason);
801 
802  /// exception free variant of close
803  void close(close::status::value const code, std::string const & reason,
804  lib::error_code & ec);
805 
806  ////////////////////////////////////////////////
807  // Pass-through access to the uri information //
808  ////////////////////////////////////////////////
809 
810  /// Returns the secure flag from the connection URI
811  /**
812  * This value is available after the HTTP request has been fully read and
813  * may be called from any thread.
814  *
815  * @return Whether or not the connection URI is flagged secure.
816  */
817  bool get_secure() const;
818 
819  /// Returns the host component of the connection URI
820  /**
821  * This value is available after the HTTP request has been fully read and
822  * may be called from any thread.
823  *
824  * @return The host component of the connection URI
825  */
826  std::string const & get_host() const;
827 
828  /// Returns the resource component of the connection URI
829  /**
830  * This value is available after the HTTP request has been fully read and
831  * may be called from any thread.
832  *
833  * @return The resource component of the connection URI
834  */
835  std::string const & get_resource() const;
836 
837  /// Returns the port component of the connection URI
838  /**
839  * This value is available after the HTTP request has been fully read and
840  * may be called from any thread.
841  *
842  * @return The port component of the connection URI
843  */
844  uint16_t get_port() const;
845 
846  /// Gets the connection URI
847  /**
848  * This should really only be called by internal library methods unless you
849  * really know what you are doing.
850  *
851  * @return A pointer to the connection's URI
852  */
853  uri_ptr get_uri() const;
854 
855  /// Sets the connection URI
856  /**
857  * This should really only be called by internal library methods unless you
858  * really know what you are doing.
859  *
860  * @param uri The new URI to set
861  */
862  void set_uri(uri_ptr uri);
863 
864  /////////////////////////////
865  // Subprotocol negotiation //
866  /////////////////////////////
867 
868  /// Gets the negotated subprotocol
869  /**
870  * Retrieves the subprotocol that was negotiated during the handshake. This
871  * method is valid in the open handler and later.
872  *
873  * @return The negotiated subprotocol
874  */
875  std::string const & get_subprotocol() const;
876 
877  /// Gets all of the subprotocols requested by the client
878  /**
879  * Retrieves the subprotocols that were requested during the handshake. This
880  * method is valid in the validate handler and later.
881  *
882  * @return A vector of the requested subprotocol
883  */
884  std::vector<std::string> const & get_requested_subprotocols() const;
885 
886  /// Adds the given subprotocol string to the request list (exception free)
887  /**
888  * Adds a subprotocol to the list to send with the opening handshake. This
889  * may be called multiple times to request more than one. If the server
890  * supports one of these, it may choose one. If so, it will return it
891  * in it's handshake reponse and the value will be available via
892  * get_subprotocol(). Subprotocol requests should be added in order of
893  * preference.
894  *
895  * @param[in] request The subprotocol to request
896  * @param[out] ec A status code describing the outcome of the operation
897  */
898  void add_subprotocol(std::string const & request, lib::error_code & ec);
899 
900  /// Adds the given subprotocol string to the request list (exception)
901  /**
902  * Adds a subprotocol to the list to send with the opening handshake. This
903  * may be called multiple times to request more than one. If the server
904  * supports one of these, it may choose one. If so, it will return it
905  * in it's handshake reponse and the value will be available via
906  * get_subprotocol(). Subprotocol requests should be added in order of
907  * preference.
908  *
909  * @param[in] request The subprotocol to request
910  */
911  void add_subprotocol(std::string const & request);
912 
913  /// Select a subprotocol to use (exception free)
914  /**
915  * Indicates which subprotocol should be used for this connection. Valid
916  * only during the validate handler callback. Subprotocol selected must have
917  * been requested by the client. Consult get_requested_subprotocols() for a
918  * list of valid subprotocols.
919  *
920  * This member function is valid on server endpoints/connections only
921  *
922  * @param[in] value The subprotocol to select
923  * @param[out] ec A status code describing the outcome of the operation
924  */
925  void select_subprotocol(std::string const & value, lib::error_code & ec);
926 
927  /// Select a subprotocol to use (exception)
928  /**
929  * Indicates which subprotocol should be used for this connection. Valid
930  * only during the validate handler callback. Subprotocol selected must have
931  * been requested by the client. Consult get_requested_subprotocols() for a
932  * list of valid subprotocols.
933  *
934  * This member function is valid on server endpoints/connections only
935  *
936  * @param[in] value The subprotocol to select
937  */
938  void select_subprotocol(std::string const & value);
939 
940  /////////////////////////////////////////////////////////////
941  // Pass-through access to the request and response objects //
942  /////////////////////////////////////////////////////////////
943 
944  /// Retrieve a request header
945  /**
946  * Retrieve the value of a header from the handshake HTTP request.
947  *
948  * @param[in] key Name of the header to get
949  * @return The value of the header
950  */
951  std::string const & get_request_header(std::string const & key) const;
952 
953  /// Retrieve a request body
954  /**
955  * Retrieve the value of the request body. This value is typically used with
956  * PUT and POST requests to upload files or other data. Only HTTP
957  * connections will ever have bodies. WebSocket connection's will always
958  * have blank bodies.
959  *
960  * @return The value of the request body.
961  */
962  std::string const & get_request_body() const;
963 
964  /// Retrieve a response header
965  /**
966  * Retrieve the value of a header from the handshake HTTP request.
967  *
968  * @param[in] key Name of the header to get
969  * @return The value of the header
970  */
971  std::string const & get_response_header(std::string const & key) const;
972 
973  /// Get response HTTP status code
974  /**
975  * Gets the response status code
976  *
977  * @since 0.7.0
978  *
979  * @return The response status code sent
980  */
982  return m_response.get_status_code();
983  }
984 
985  /// Get response HTTP status message
986  /**
987  * Gets the response status message
988  *
989  * @since 0.7.0
990  *
991  * @return The response status message sent
992  */
993  std::string const & get_response_msg() const {
994  return m_response.get_status_msg();
995  }
996 
997  /// Set response status code and message (exception free)
998  /**
999  * Sets the response status code to `code` and looks up the corresponding
1000  * message for standard codes. Non-standard codes will be entered as Unknown
1001  * use set_status(status_code::value,std::string) overload to set both
1002  * values explicitly.
1003  *
1004  * This member function is valid only from the http() and validate() handler
1005  * callbacks.
1006  *
1007  * @since 0.9.0
1008  *
1009  * @param[in] code Code to set
1010  * @param[in] msg Message to set
1011  * @param[out] ec A status code describing the outcome of the operation
1012  * @see websocketpp::http::parser::response::set_status
1013  * @see websocketpp::http::status_code::value (list of valid codes)
1014  */
1015  void set_status(http::status_code::value code, lib::error_code & ec);
1016 
1017  /// Set response status code and message (exception)
1018  /**
1019  * Sets the response status code and message to independent custom values.
1020  * use set_status(status_code::value) to set the code and have the standard
1021  * message be automatically set.
1022  *
1023  * This member function is valid only from the http() and validate() handler
1024  * callbacks.
1025  *
1026  * @param[in] code Code to set
1027  * @param[in] msg Message to set
1028  * @throw websocketpp::exception
1029  * @see websocketpp::http::response::set_status()
1030  * @see websocketpp::http::status_code::value (list of valid codes)
1031  */
1032  void set_status(http::status_code::value code);
1033 
1034  /// Set response status code and message (exception free)
1035  /**
1036  * Sets the response status code and message to independent custom values.
1037  * use set_status(status_code::value) to set the code and have the standard
1038  * message be automatically set.
1039  *
1040  * This member function is valid only from the http() and validate() handler
1041  * callbacks.
1042  *
1043  * @since 0.9.0
1044  *
1045  * @param[in] code Code to set
1046  * @param[in] msg Message to set
1047  * @param[out] ec A status code describing the outcome of the operation
1048  * @see websocketpp::http::response::set_status()
1049  * @see websocketpp::http::status_code::value (list of valid codes)
1050  */
1051  void set_status(http::status_code::value code, std::string const & msg,
1052  lib::error_code & ec);
1053 
1054  /// Set response status code and message (exception)
1055  /**
1056  * Sets the response status code and message to independent custom values.
1057  * use set_status(status_code::value) to set the code and have the standard
1058  * message be automatically set.
1059  *
1060  * This member function is valid only from the http() and validate() handler
1061  * callbacks.
1062  *
1063  * @param[in] code Code to set
1064  * @param[in] msg Message to set
1065  * @throw websocketpp::exception
1066  * @see websocketpp::http::response::set_status()
1067  * @see websocketpp::http::status_code::value (list of valid codes)
1068  */
1069  void set_status(http::status_code::value code, std::string const & msg);
1070 
1071  /// Set response body content (exception free)
1072  /**
1073  * Set the body content of the HTTP response to the parameter string. Note
1074  * set_body will also set the Content-Length HTTP header to the appropriate
1075  * value. If you want the Content-Length header to be something else set it
1076  * to something else after calling set_body
1077  *
1078  * This member function is valid only from the http() and validate() handler
1079  * callbacks.
1080  *
1081  * @since 0.9.0
1082  *
1083  * @param[in] value String data to include as the body content.
1084  * @param[out] ec A status code describing the outcome of the operation
1085  * @see websocketpp::http::response::set_body
1086  * @see set_body(std::string const &) (exception version)
1087  */
1088  void set_body(std::string const & value, lib::error_code & ec);
1089 
1090  /// Set response body content (exception)
1091  /**
1092  * Set the body content of the HTTP response to the parameter string. Note
1093  * set_body will also set the Content-Length HTTP header to the appropriate
1094  * value. If you want the Content-Length header to be something else set it
1095  * to something else after calling set_body
1096  *
1097  * This member function is valid only from the http() and validate() handler
1098  * callbacks.
1099  *
1100  * @param[in] value String data to include as the body content.
1101  * @throw websocketpp::exception
1102  * @see websocketpp::http::response::set_body
1103  * @see set_body(std::string const &, lib::error_code &)
1104  * (exception free version)
1105  */
1106  void set_body(std::string const & value);
1107 
1108  /// Append a header (exception free)
1109  /**
1110  * Set the value of a header in the handshake HTTP request or response. If
1111  * a header with this name already exists the value will be appended to the
1112  * existing header to form a comma separated list of values. Use
1113  * `connection::replace_header` to overwrite existing values.
1114  *
1115  * *When can this member function be called?*
1116  * - Servers: Valid from the http and validate handlers
1117  * - Clients: Valid before websocketpp::client::connect() has been called
1118  *
1119  * @since 0.9.0
1120  *
1121  * @param[in] key Name of the header to set
1122  * @param[in] val Value to add
1123  * @param[out] ec A status code describing the outcome of the operation
1124  * @see connection::replace_header
1125  * @see websocketpp::http::parser::parser::append_header
1126  * @see append_header(std::string const &, std::string const &)
1127  * (exception version)
1128  */
1129  void append_header(std::string const & key, std::string const & val,
1130  lib::error_code & ec);
1131 
1132  /// Append a header (exception)
1133  /**
1134  * Set the value of a header in the handshake HTTP request or response. If
1135  * a header with this name already exists the value will be appended to the
1136  * existing header to form a comma separated list of values. Use
1137  * `connection::replace_header` to overwrite existing values.
1138  *
1139  * *When can this member function be called?*
1140  * - Servers: Valid from the http and validate handlers
1141  * - Clients: Valid before websocketpp::client::connect() has been called
1142  *
1143  * @param[in] key Name of the header to set
1144  * @param[in] val Value to add
1145  * @throw websocketpp::exception
1146  * @see connection::replace_header
1147  * @see websocketpp::http::parser::parser::append_header
1148  * @see append_header(std::string const &, std::string const &,
1149  * lib::error_code &) (exception free version)
1150  */
1151  void append_header(std::string const & key, std::string const & val);
1152 
1153  /// Replace a header (exception free)
1154  /**
1155  * Set the value of a header in the handshake HTTP request or response. If
1156  * a header with this name already exists the old value will be replaced
1157  * Use `connection::append_header` to append to a list of existing values.
1158  *
1159  * *When can this member function be called?*
1160  * - Servers: Valid from the http and validate handlers
1161  * - Clients: Valid before websocketpp::client::connect() has been called
1162  *
1163  * @param[in] key Name of the header to set
1164  * @param[in] val Value to set
1165  * @param[out] ec A status code describing the outcome of the operation
1166  * @see connection::append_header
1167  * @see websocketpp::http::parser::parser::replace_header
1168  * @see replace_header(std::string const &, std::string const &)
1169  * (exception version)
1170  */
1171  void replace_header(std::string const & key, std::string const & val,
1172  lib::error_code & ec);
1173 
1174  /// Replace a header (exception)
1175  /**
1176  * Set the value of a header in the handshake HTTP request or response. If
1177  * a header with this name already exists the old value will be replaced
1178  * Use `connection::append_header` to append to a list of existing values.
1179  *
1180  * *When can this member function be called?*
1181  * - Servers: Valid from the http and validate handlers
1182  * - Clients: Valid before websocketpp::client::connect() has been called
1183  *
1184  * @param[in] key Name of the header to set
1185  * @param[in] val Value to set
1186  * @throw websocketpp::exception
1187  * @see connection::append_header
1188  * @see websocketpp::http::parser::parser::replace_header
1189  * @see replace_header(std::string const & key, std::string const & val,
1190  * lib::error_code & ec) (exception free version)
1191  */
1192  void replace_header(std::string const & key, std::string const & val);
1193 
1194  /// Remove a header (exception free)
1195  /**
1196  * Removes a header from the handshake HTTP request or response.
1197  *
1198  * *When can this member function be called?*
1199  * - Servers: Valid from the http and validate handlers
1200  * - Clients: Valid before websocketpp::client::connect() has been called
1201  *
1202  * @param[in] key The name of the header to remove
1203  * @param[out] ec A status code describing the outcome of the operation
1204  * @see websocketpp::http::parser::parser::remove_header
1205  * @see remove_header(std::string const &) (exception version)
1206  */
1207  void remove_header(std::string const & key, lib::error_code & ec);
1208 
1209  /// Remove a header (exception)
1210  /**
1211  * Removes a header from the handshake HTTP request or response.
1212  *
1213  * *When can this member function be called?*
1214  * - Servers: Valid from the http and validate handlers
1215  * - Clients: Valid before websocketpp::client::connect() has been called
1216  *
1217  * @param[in] key The name of the header to remove
1218  * @throw websocketpp::exception
1219  * @see websocketpp::http::parser::parser::remove_header
1220  * @see remove_header(std::string const &, lib::error_code &)
1221  * (exception free version)
1222  */
1223  void remove_header(std::string const & key);
1224 
1225  /// Get request object
1226  /**
1227  * Direct access to request object. This can be used to call methods of the
1228  * request object that are not part of the standard request API that
1229  * connection wraps.
1230  *
1231  * Note use of this method involves using behavior specific to the
1232  * configured HTTP policy. Such behavior may not work with alternate HTTP
1233  * policies.
1234  *
1235  * @since 0.3.0-alpha3
1236  *
1237  * @return A const reference to the raw request object
1238  */
1239  request_type const & get_request() const {
1240  return m_request;
1241  }
1242 
1243  /// Get response object
1244  /**
1245  * Direct access to the HTTP response sent or received as a part of the
1246  * opening handshake. This can be used to call methods of the response
1247  * object that are not part of the standard request API that connection
1248  * wraps.
1249  *
1250  * Note use of this method involves using behavior specific to the
1251  * configured HTTP policy. Such behavior may not work with alternate HTTP
1252  * policies.
1253  *
1254  * @since 0.7.0
1255  *
1256  * @return A const reference to the raw response object
1257  */
1258  response_type const & get_response() const {
1259  return m_response;
1260  }
1261 
1262  /// Defer HTTP Response until later (Exception free)
1263  /**
1264  * Used in the http handler to defer the HTTP response for this connection
1265  * until later. Handshake timers will be canceled and the connection will
1266  * be left open until `send_http_response` or an equivalent is called.
1267  *
1268  * Warning: deferred connections won't time out and as a result can tie up
1269  * resources.
1270  *
1271  * @since 0.6.0
1272  *
1273  * @return A status code, zero on success, non-zero otherwise
1274  */
1276 
1277  /// Send deferred HTTP Response (exception free)
1278  /**
1279  * Sends an http response to an HTTP connection that was deferred. This will
1280  * send a complete response including all headers, status line, and body
1281  * text. The connection will be closed afterwards.
1282  *
1283  * @since 0.6.0
1284  *
1285  * @param ec A status code, zero on success, non-zero otherwise
1286  */
1287  void send_http_response(lib::error_code & ec);
1288 
1289  /// Send deferred HTTP Response
1290  void send_http_response();
1291 
1292  // TODO HTTPNBIO: write_headers
1293  // function that processes headers + status so far and writes it to the wire
1294  // beginning the HTTP response body state. This method will ignore anything
1295  // in the response body.
1296 
1297  // TODO HTTPNBIO: write_body_message
1298  // queues the specified message_buffer for async writing
1299 
1300  // TODO HTTPNBIO: finish connection
1301  //
1302 
1303  // TODO HTTPNBIO: write_response
1304  // Writes the whole response, headers + body and closes the connection
1305 
1306 
1307 
1308  /////////////////////////////////////////////////////////////
1309  // Pass-through access to the other connection information //
1310  /////////////////////////////////////////////////////////////
1311 
1312  /// Get Connection Handle
1313  /**
1314  * The connection handle is a token that can be shared outside the
1315  * WebSocket++ core for the purposes of identifying a connection and
1316  * sending it messages.
1317  *
1318  * @return A handle to the connection
1319  */
1321  return m_connection_hdl;
1322  }
1323 
1324  /// Get whether or not this connection is part of a server or client
1325  /**
1326  * @return whether or not the connection is attached to a server endpoint
1327  */
1328  bool is_server() const {
1329  return m_is_server;
1330  }
1331 
1332  /// Return the same origin policy origin value from the opening request.
1333  /**
1334  * This value is available after the HTTP request has been fully read and
1335  * may be called from any thread.
1336  *
1337  * @return The connection's origin value from the opening handshake.
1338  */
1339  std::string const & get_origin() const;
1340 
1341  /// Return the connection state.
1342  /**
1343  * Values can be connecting, open, closing, and closed
1344  *
1345  * @return The connection's current state.
1346  */
1347  session::state::value get_state() const;
1348 
1349 
1350  /// Get the WebSocket close code sent by this endpoint.
1351  /**
1352  * @return The WebSocket close code sent by this endpoint.
1353  */
1355  return m_local_close_code;
1356  }
1357 
1358  /// Get the WebSocket close reason sent by this endpoint.
1359  /**
1360  * @return The WebSocket close reason sent by this endpoint.
1361  */
1362  std::string const & get_local_close_reason() const {
1363  return m_local_close_reason;
1364  }
1365 
1366  /// Get the WebSocket close code sent by the remote endpoint.
1367  /**
1368  * @return The WebSocket close code sent by the remote endpoint.
1369  */
1371  return m_remote_close_code;
1372  }
1373 
1374  /// Get the WebSocket close reason sent by the remote endpoint.
1375  /**
1376  * @return The WebSocket close reason sent by the remote endpoint.
1377  */
1379  return m_remote_close_reason;
1380  }
1381 
1382  /// Get the internal error code for a closed/failed connection
1383  /**
1384  * Retrieves a machine readable detailed error code indicating the reason
1385  * that the connection was closed or failed. Valid only after the close or
1386  * fail handler is called.
1387  *
1388  * @return Error code indicating the reason the connection was closed or
1389  * failed
1390  */
1391  lib::error_code get_ec() const {
1392  return m_ec;
1393  }
1394 
1395  /// Get a message buffer
1396  /**
1397  * Warning: The API related to directly sending message buffers may change
1398  * before the 1.0 release. If you plan to use it, please keep an eye on any
1399  * breaking changes notifications in future release notes. Also if you have
1400  * any feedback about usage and capabilities now is a great time to provide
1401  * it.
1402  *
1403  * Message buffers are used to store message payloads and other message
1404  * metadata.
1405  *
1406  * The size parameter is a hint only. Your final payload does not need to
1407  * match it. There may be some performance benefits if the initial size
1408  * guess is equal to or slightly higher than the final payload size.
1409  *
1410  * @param op The opcode for the new message
1411  * @param size A hint to optimize the initial allocation of payload space.
1412  * @return A new message buffer
1413  */
1415  const
1416  {
1417  return m_msg_manager->get_message(op, size);
1418  }
1419 
1420  ////////////////////////////////////////////////////////////////////////
1421  // The remaining public member functions are for internal/policy use //
1422  // only. Do not call from application code unless you understand what //
1423  // you are doing. //
1424  ////////////////////////////////////////////////////////////////////////
1425 
1426 
1427 
1429 
1430  void handle_read_handshake(lib::error_code const & ec,
1431  size_t bytes_transferred);
1432  void handle_read_http_response(lib::error_code const & ec,
1433  size_t bytes_transferred);
1434 
1435 
1436  void handle_write_http_response(lib::error_code const & ec);
1437  void handle_send_http_request(lib::error_code const & ec);
1438 
1439  void handle_open_handshake_timeout(lib::error_code const & ec);
1440  void handle_close_handshake_timeout(lib::error_code const & ec);
1441 
1442  void handle_read_frame(lib::error_code const & ec, size_t bytes_transferred);
1443  void read_frame();
1444 
1445  /// Get array of WebSocket protocol versions that this connection supports.
1446  std::vector<int> const & get_supported_versions() const;
1447 
1448  /// Sets the handler for a terminating connection. Should only be used
1449  /// internally by the endpoint class.
1450  void set_termination_handler(termination_handler new_handler);
1451 
1452  void terminate(lib::error_code const & ec);
1453  void handle_terminate(terminate_status tstat, lib::error_code const & ec);
1454 
1455  /// Checks if there are frames in the send queue and if there are sends one
1456  /**
1457  * \todo unit tests
1458  *
1459  * This method locks the m_write_lock mutex
1460  */
1461  void write_frame();
1462 
1463  /// Process the results of a frame write operation and start the next write
1464  /**
1465  * \todo unit tests
1466  *
1467  * This method locks the m_write_lock mutex
1468  *
1469  * @param terminate Whether or not to terminate the connection upon
1470  * completion of this write.
1471  *
1472  * @param ec A status code from the transport layer, zero on success,
1473  * non-zero otherwise.
1474  */
1475  void handle_write_frame(lib::error_code const & ec);
1476 // protected:
1477  // This set of methods would really like to be protected, but doing so
1478  // requires that the endpoint be able to friend the connection. This is
1479  // allowed with C++11, but not prior versions
1480 
1481  /// Start the connection state machine
1482  void start();
1483 
1484  /// Set Connection Handle
1485  /**
1486  * The connection handle is a token that can be shared outside the
1487  * WebSocket++ core for the purposes of identifying a connection and
1488  * sending it messages.
1489  *
1490  * @param hdl A connection_hdl that the connection will use to refer
1491  * to itself.
1492  */
1493  void set_handle(connection_hdl hdl) {
1494  m_connection_hdl = hdl;
1495  transport_con_type::set_handle(hdl);
1496  }
1497 protected:
1498  void handle_transport_init(lib::error_code const & ec);
1499 
1500  /// Set m_processor based on information in m_request. Set m_response
1501  /// status and return an error code indicating status.
1503 
1504  /// Perform WebSocket handshake validation of m_request using m_processor.
1505  /// set m_response and return an error code indicating status.
1507 private:
1508 
1509 
1510  /// Completes m_response, serializes it, and sends it out on the wire.
1511  void write_http_response(lib::error_code const & ec);
1512 
1513  /// Sends an opening WebSocket connect request
1514  void send_http_request();
1515 
1516  /// Alternate path for write_http_response in error conditions
1517  void write_http_response_error(lib::error_code const & ec);
1518 
1519  /// Process control message
1520  /**
1521  *
1522  */
1523  void process_control_frame(message_ptr msg);
1524 
1525  /// Send close acknowledgement
1526  /**
1527  * If no arguments are present no close code/reason will be specified.
1528  *
1529  * Note: the close code/reason values provided here may be overrided by
1530  * other settings (such as silent close).
1531  *
1532  * @param code The close code to send
1533  * @param reason The close reason to send
1534  * @return A status code, zero on success, non-zero otherwise
1535  */
1536  lib::error_code send_close_ack(close::status::value code =
1537  close::status::blank, std::string const & reason = std::string());
1538 
1539  /// Send close frame
1540  /**
1541  * If no arguments are present no close code/reason will be specified.
1542  *
1543  * Note: the close code/reason values provided here may be overrided by
1544  * other settings (such as silent close).
1545  *
1546  * The ack flag determines what to do in the case of a blank status and
1547  * whether or not to terminate the TCP connection after sending it.
1548  *
1549  * @param code The close code to send
1550  * @param reason The close reason to send
1551  * @param ack Whether or not this is an acknowledgement close frame
1552  * @return A status code, zero on success, non-zero otherwise
1553  */
1554  lib::error_code send_close_frame(close::status::value code =
1555  close::status::blank, std::string const & reason = std::string(), bool ack = false,
1556  bool terminal = false);
1557 
1558  /// Get a pointer to a new WebSocket protocol processor for a given version
1559  /**
1560  * @param version Version number of the WebSocket protocol to get a
1561  * processor for. Negative values indicate invalid/unknown versions and will
1562  * always return a null ptr
1563  *
1564  * @return A shared_ptr to a new instance of the appropriate processor or a
1565  * null ptr if there is no installed processor that matches the version
1566  * number.
1567  */
1568  processor_ptr get_processor(int version) const;
1569 
1570  /// Add a message to the write queue
1571  /**
1572  * Adds a message to the write queue and updates any associated shared state
1573  *
1574  * Must be called while holding m_write_lock
1575  *
1576  * @todo unit tests
1577  *
1578  * @param msg The message to push
1579  */
1580  void write_push(message_ptr msg);
1581 
1582  /// Pop a message from the write queue
1583  /**
1584  * Removes and returns a message from the write queue and updates any
1585  * associated shared state.
1586  *
1587  * Must be called while holding m_write_lock
1588  *
1589  * @todo unit tests
1590  *
1591  * @return the message_ptr at the front of the queue
1592  */
1593  message_ptr write_pop();
1594 
1595  /// Prints information about the incoming connection to the access log
1596  /**
1597  * Prints information about the incoming connection to the access log.
1598  * Includes: connection type, websocket version, remote endpoint, user agent
1599  * path, status code.
1600  */
1601  void log_open_result();
1602 
1603  /// Prints information about a connection being closed to the access log
1604  /**
1605  * Includes: local and remote close codes and reasons
1606  */
1607  void log_close_result();
1608 
1609  /// Prints information about a connection being failed to the access log
1610  /**
1611  * Includes: error code and message for why it was failed
1612  */
1613  void log_fail_result();
1614 
1615  /// Prints information about HTTP connections
1616  /**
1617  * Includes: TODO
1618  */
1619  void log_http_result();
1620 
1621  /// Prints information about an arbitrary error code on the specified channel
1622  template <typename error_type>
1623  void log_err(log::level l, char const * msg, error_type const & ec) {
1624  std::stringstream s;
1625  s << msg << " error: " << ec << " (" << ec.message() << ")";
1626  m_elog->write(l, s.str());
1627  }
1628 
1629  // internal handler functions
1630  read_handler m_handle_read_frame;
1631  write_frame_handler m_write_frame_handler;
1632 
1633  // static settings
1634  std::string const m_user_agent;
1635 
1636  /// Pointer to the connection handle
1637  connection_hdl m_connection_hdl;
1638 
1639  /// Handler objects
1640  open_handler m_open_handler;
1641  close_handler m_close_handler;
1642  fail_handler m_fail_handler;
1643  ping_handler m_ping_handler;
1644  pong_handler m_pong_handler;
1645  pong_timeout_handler m_pong_timeout_handler;
1646  interrupt_handler m_interrupt_handler;
1647  http_handler m_http_handler;
1648  validate_handler m_validate_handler;
1649  message_handler m_message_handler;
1650 
1651  /// constant values
1652  long m_open_handshake_timeout_dur;
1653  long m_close_handshake_timeout_dur;
1654  long m_pong_timeout_dur;
1655  size_t m_max_message_size;
1656 
1657  /// External connection state
1658  /**
1659  * Lock: m_connection_state_lock
1660  */
1661  session::state::value m_state;
1662 
1663  /// Internal connection state
1664  /**
1665  * Lock: m_connection_state_lock
1666  */
1667  istate_type m_internal_state;
1668 
1669  mutable mutex_type m_connection_state_lock;
1670 
1671  /// The lock used to protect the message queue
1672  /**
1673  * Serializes access to the write queue as well as shared state within the
1674  * processor.
1675  */
1676  mutex_type m_write_lock;
1677 
1678  // connection resources
1679  char m_buf[config::connection_read_buffer_size];
1680  size_t m_buf_cursor;
1681  termination_handler m_termination_handler;
1682  con_msg_manager_ptr m_msg_manager;
1683  timer_ptr m_handshake_timer;
1684  timer_ptr m_ping_timer;
1685 
1686  /// @todo this is not memory efficient. this value is not used after the
1687  /// handshake.
1688  std::string m_handshake_buffer;
1689 
1690  /// Pointer to the processor object for this connection
1691  /**
1692  * The processor provides functionality that is specific to the WebSocket
1693  * protocol version that the client has negotiated. It also contains all of
1694  * the state necessary to encode and decode the incoming and outgoing
1695  * WebSocket byte streams
1696  *
1697  * Use of the prepare_data_frame method requires lock: m_write_lock
1698  */
1699  processor_ptr m_processor;
1700 
1701  /// Queue of unsent outgoing messages
1702  /**
1703  * Lock: m_write_lock
1704  */
1706 
1707  /// Size in bytes of the outstanding payloads in the write queue
1708  /**
1709  * Lock: m_write_lock
1710  */
1711  size_t m_send_buffer_size;
1712 
1713  /// buffer holding the various parts of the current message being writen
1714  /**
1715  * Lock m_write_lock
1716  */
1717  std::vector<transport::buffer> m_send_buffer;
1718 
1719  /// a list of pointers to hold on to the messages being written to keep them
1720  /// from going out of scope before the write is complete.
1722 
1723  /// True if there is currently an outstanding transport write
1724  /**
1725  * Lock m_write_lock
1726  */
1727  bool m_write_flag;
1728 
1729  /// True if this connection is presently reading new data
1730  bool m_read_flag;
1731 
1732  // connection data
1733  request_type m_request;
1734  response_type m_response;
1735  uri_ptr m_uri;
1736  std::string m_subprotocol;
1737 
1738  // connection data that might not be necessary to keep around for the life
1739  // of the whole connection.
1740  std::vector<std::string> m_requested_subprotocols;
1741 
1742  bool const m_is_server;
1743  const lib::shared_ptr<alog_type> m_alog;
1744  const lib::shared_ptr<elog_type> m_elog;
1745 
1746  rng_type & m_rng;
1747 
1748  // Close state
1749  /// Close code that was sent on the wire by this endpoint
1751 
1752  /// Close reason that was sent on the wire by this endpoint
1753  std::string m_local_close_reason;
1754 
1755  /// Close code that was received on the wire from the remote endpoint
1757 
1758  /// Close reason that was received on the wire from the remote endpoint
1759  std::string m_remote_close_reason;
1760 
1761  /// Detailed internal error code
1762  lib::error_code m_ec;
1763 
1764  /// A flag that gets set once it is determined that the connection is an
1765  /// HTTP connection and not a WebSocket one.
1766  bool m_is_http;
1767 
1768  /// A flag that gets set when the completion of an http connection is
1769  /// deferred until later.
1770  session::http_state::value m_http_state;
1771 
1772  bool m_was_clean;
1773 };
1774 
1775 } // namespace websocketpp
1776 
1777 #include <websocketpp/impl/connection_impl.hpp>
1778 
1779 #endif // WEBSOCKETPP_CONNECTION_HPP
websocketpp::connection::set_status
void set_status(http::status_code::value code)
Set response status code and message (exception)
Definition: connection_impl.hpp:557
websocketpp::connection::send
lib::error_code send(message_ptr msg)
Add a message to the outgoing send queue.
websocketpp::connection::handle_pause_reading
void handle_pause_reading()
Pause reading callback.
Definition: connection_impl.hpp:372
websocketpp::connection::concurrency_type
config::concurrency_type concurrency_type
Type of the concurrency component of this connection.
Definition: connection.hpp:248
websocketpp::connection::set_validate_handler
void set_validate_handler(validate_handler h)
Set validate handler.
Definition: connection.hpp:463
websocketpp::http_handler
lib::function< void(connection_hdl)> http_handler
The type and function signature of a http handler.
Definition: connection.hpp:151
websocketpp::connection::initialize_processor
lib::error_code initialize_processor()
Definition: connection_impl.hpp:1196
websocketpp::connection::set_ping_handler
void set_ping_handler(ping_handler h)
Set ping handler.
Definition: connection.hpp:387
websocketpp::validate_handler
lib::function< bool(connection_hdl)> validate_handler
The type and function signature of a validate handler.
Definition: connection.hpp:129
websocketpp::connection::set_pong_timeout_handler
void set_pong_timeout_handler(pong_timeout_handler h)
Set pong timeout handler.
Definition: connection.hpp:421
websocketpp::connection::set_close_handshake_timeout
void set_close_handshake_timeout(long dur)
Set close handshake timeout.
Definition: connection.hpp:525
websocketpp::connection::get_resource
std::string const & get_resource() const
Returns the resource component of the connection URI.
Definition: connection_impl.hpp:418
websocketpp::connection::set_handle
void set_handle(connection_hdl hdl)
Set Connection Handle.
Definition: connection.hpp:1493
websocketpp::connection::get_request_header
std::string const & get_request_header(std::string const &key) const
Retrieve a request header.
Definition: connection_impl.hpp:528
websocketpp::connection::handle_interrupt
void handle_interrupt()
Transport inturrupt callback.
Definition: connection_impl.hpp:353
websocketpp::connection::set_status
void set_status(http::status_code::value code, std::string const &msg, lib::error_code &ec)
Set response status code and message (exception free)
Definition: connection_impl.hpp:567
websocketpp::connection::rng_type
config::rng_type rng_type
Type of RNG.
Definition: connection.hpp:275
websocketpp::connection::append_header
void append_header(std::string const &key, std::string const &val)
Append a header (exception)
Definition: connection_impl.hpp:633
websocketpp::connection::send
lib::error_code send(std::string const &payload, frame::opcode::value op=frame::opcode::text)
Create a message and then add it to the outgoing send queue.
Definition: connection_impl.hpp:83
websocketpp::connection::transport_con_type
config::transport_type::transport_con_type transport_con_type
Type of the transport component of this connection.
Definition: connection.hpp:256
websocketpp::connection::remove_header
void remove_header(std::string const &key, lib::error_code &ec)
Remove a header (exception free)
websocketpp::connection::is_server
bool is_server() const
Get whether or not this connection is part of a server or client.
Definition: connection.hpp:1328
websocketpp::connection::set_message_handler
void set_message_handler(message_handler h)
Set message handler.
Definition: connection.hpp:473
websocketpp::connection::handle_write_frame
void handle_write_frame(lib::error_code const &ec)
Process the results of a frame write operation and start the next write.
Definition: connection_impl.hpp:1963
websocketpp::connection::set_max_http_body_size
void set_max_http_body_size(size_t new_value)
Set maximum HTTP message body size.
Definition: connection.hpp:610
websocketpp::pong_timeout_handler
lib::function< void(connection_hdl, std::string)> pong_timeout_handler
The type and function signature of a pong timeout handler.
Definition: connection.hpp:116
websocketpp::connection::set_body
void set_body(std::string const &value, lib::error_code &ec)
Set response body content (exception free)
Definition: connection_impl.hpp:591
websocketpp::connection::get_requested_subprotocols
std::vector< std::string > const & get_requested_subprotocols() const
Gets all of the subprotocols requested by the client.
Definition: connection_impl.hpp:453
websocketpp::interrupt_handler
lib::function< void(connection_hdl)> interrupt_handler
The type and function signature of an interrupt handler.
Definition: connection.hpp:91
websocketpp::connection::get_state
session::state::value get_state() const
Return the connection state.
Definition: connection_impl.hpp:77
websocketpp::connection::get_max_message_size
size_t get_max_message_size() const
Get maximum message size.
Definition: connection.hpp:559
websocketpp::connection::get_supported_versions
std::vector< int > const & get_supported_versions() const
Get array of WebSocket protocol versions that this connection supports.
Definition: connection_impl.hpp:2005
websocketpp::connection::set_status
void set_status(http::status_code::value code, lib::error_code &ec)
Set response status code and message (exception free)
Definition: connection_impl.hpp:545
websocketpp::connection::get_handle
connection_hdl get_handle() const
Get Connection Handle.
Definition: connection.hpp:1320
websocketpp::connection::get_origin
std::string const & get_origin() const
Return the same origin policy origin value from the opening request.
Definition: connection_impl.hpp:65
websocketpp::connection::get_secure
bool get_secure() const
Returns the secure flag from the connection URI.
Definition: connection_impl.hpp:406
websocketpp::connection::send_http_response
void send_http_response(lib::error_code &ec)
Send deferred HTTP Response (exception free)
Definition: connection_impl.hpp:742
websocketpp::connection::interrupt
lib::error_code interrupt()
Asyncronously invoke handler::on_inturrupt.
Definition: connection_impl.hpp:341
websocketpp::connection::timer_ptr
transport_con_type::timer_ptr timer_ptr
Type of a pointer to a transport timer handle.
Definition: connection.hpp:284
websocketpp::fail_handler
lib::function< void(connection_hdl)> fail_handler
The type and function signature of a fail handler.
Definition: connection.hpp:79
websocketpp::versions_supported
static std::vector< int > const versions_supported(helper, helper+4)
Container that stores the list of protocol versions supported.
websocketpp::connection::get_response_msg
std::string const & get_response_msg() const
Get response HTTP status message.
Definition: connection.hpp:993
websocketpp::connection::set_open_handler
void set_open_handler(open_handler h)
Set open handler.
Definition: connection.hpp:351
websocketpp::connection::remove_header
void remove_header(std::string const &key)
Remove a header (exception)
Definition: connection_impl.hpp:676
websocketpp::connection::get_port
uint16_t get_port() const
Returns the port component of the connection URI.
Definition: connection_impl.hpp:424
websocketpp::connection::get_response_code
http::status_code::value get_response_code() const
Get response HTTP status code.
Definition: connection.hpp:981
websocketpp::connection::set_body
void set_body(std::string const &value)
Set response body content (exception)
Definition: connection_impl.hpp:603
websocketpp::connection::get_request_body
std::string const & get_request_body() const
Retrieve a request body.
Definition: connection_impl.hpp:534
websocketpp::connection::add_subprotocol
void add_subprotocol(std::string const &request, lib::error_code &ec)
Adds the given subprotocol string to the request list (exception free)
Definition: connection_impl.hpp:458
websocketpp::connection::process_handshake_request
lib::error_code process_handshake_request()
Definition: connection_impl.hpp:1238
websocketpp::connection::set_open_handshake_timeout
void set_open_handshake_timeout(long dur)
Set open handshake timeout.
Definition: connection.hpp:501
websocketpp::connection::get_request
request_type const & get_request() const
Get request object.
Definition: connection.hpp:1239
websocketpp::connection::select_subprotocol
void select_subprotocol(std::string const &value)
Select a subprotocol to use (exception)
Definition: connection_impl.hpp:517
websocketpp::connection::set_pong_timeout
void set_pong_timeout(long dur)
Set pong timeout.
Definition: connection.hpp:546
websocketpp::connection::get_shared
ptr get_shared()
Get a shared pointer to this component.
Definition: connection.hpp:336
websocketpp::connection::set_uri
void set_uri(uri_ptr uri)
Sets the connection URI.
Definition: connection_impl.hpp:436
websocketpp::connection::get_response
response_type const & get_response() const
Get response object.
Definition: connection.hpp:1258
websocketpp::connection::select_subprotocol
void select_subprotocol(std::string const &value, lib::error_code &ec)
Select a subprotocol to use (exception free)
Definition: connection_impl.hpp:488
websocketpp::connection::set_close_handler
void set_close_handler(close_handler h)
Set close handler.
Definition: connection.hpp:361
websocketpp::connection::get_response_header
std::string const & get_response_header(std::string const &key) const
Retrieve a response header.
Definition: connection_impl.hpp:540
websocketpp::connection::send
lib::error_code send(void const *payload, size_t len, frame::opcode::value op=frame::opcode::binary)
Send a message (raw array overload)
Definition: connection_impl.hpp:94
websocketpp::ping_handler
lib::function< bool(connection_hdl, std::string)> ping_handler
The type and function signature of a ping handler.
Definition: connection.hpp:101
websocketpp::connection::elog_type
config::elog_type elog_type
Type of the error logging policy.
Definition: connection.hpp:252
websocketpp::pong_handler
lib::function< void(connection_hdl, std::string)> pong_handler
The type and function signature of a pong handler.
Definition: connection.hpp:109
websocketpp::connection::get_uri
uri_ptr get_uri() const
Gets the connection URI.
Definition: connection_impl.hpp:430
websocketpp::close_handler
lib::function< void(connection_hdl)> close_handler
The type and function signature of a close handler.
Definition: connection.hpp:69
websocketpp::connection::pong
void pong(std::string const &payload, lib::error_code &ec)
exception free variant of pong
Definition: connection_impl.hpp:252
websocketpp::connection::add_subprotocol
void add_subprotocol(std::string const &request)
Adds the given subprotocol string to the request list (exception)
Definition: connection_impl.hpp:478
websocketpp::connection::set_fail_handler
void set_fail_handler(fail_handler h)
Set fail handler.
Definition: connection.hpp:372
websocketpp::connection::set_termination_handler
void set_termination_handler(termination_handler new_handler)
Definition: connection_impl.hpp:53
websocketpp::connection::read_frame
void read_frame()
Issue a new transport read unless reading is paused.
Definition: connection_impl.hpp:1175
websocketpp::connection::type
connection< config > type
Type of this connection.
Definition: connection.hpp:241
websocketpp::connection::append_header
void append_header(std::string const &key, std::string const &val, lib::error_code &ec)
Append a header (exception free)
Definition: connection_impl.hpp:612
websocketpp::connection::get_host
std::string const & get_host() const
Returns the host component of the connection URI.
Definition: connection_impl.hpp:412
websocketpp::connection::set_status
void set_status(http::status_code::value code, std::string const &msg)
Set response status code and message (exception)
Definition: connection_impl.hpp:580
websocketpp::connection::set_http_handler
void set_http_handler(http_handler h)
Set http handler.
Definition: connection.hpp:447
websocketpp::connection::get_max_http_body_size
size_t get_max_http_body_size() const
Get maximum HTTP message body size.
Definition: connection.hpp:594
websocketpp::connection::replace_header
void replace_header(std::string const &key, std::string const &val, lib::error_code &ec)
Replace a header (exception free)
websocketpp::connection::pause_reading
lib::error_code pause_reading()
Pause reading of new data.
Definition: connection_impl.hpp:360
websocketpp::connection::start
void start()
Start the connection state machine.
Definition: connection_impl.hpp:772
websocketpp::connection::send_http_response
void send_http_response()
Send deferred HTTP Response.
Definition: connection_impl.hpp:758
websocketpp::connection::buffered_amount
size_t buffered_amount() const
Get the size of the outgoing write buffer (in payload bytes)
Definition: connection.hpp:635
websocketpp::connection::pong
void pong(std::string const &payload)
Send a pong.
Definition: connection_impl.hpp:295
websocketpp::open_handler
lib::function< void(connection_hdl)> open_handler
The type and function signature of an open handler.
Definition: connection.hpp:59
websocketpp::connection::handle_pong_timeout
void handle_pong_timeout(std::string payload, lib::error_code const &ec)
Utility method that gets called back when the ping timer expires.
Definition: connection_impl.hpp:233
websocketpp::connection::handle_resume_reading
void handle_resume_reading()
Resume reading callback.
Definition: connection_impl.hpp:390
websocketpp::connection::transport_con_ptr
transport_con_type::ptr transport_con_ptr
Type of a shared pointer to the transport component of this connection.
Definition: connection.hpp:258
websocketpp::connection::close
void close(close::status::value const code, std::string const &reason, lib::error_code &ec)
exception free variant of close
Definition: connection_impl.hpp:304
websocketpp::connection::alog_type
config::alog_type alog_type
Type of the access logging policy.
Definition: connection.hpp:250
websocketpp::connection::replace_header
void replace_header(std::string const &key, std::string const &val)
Replace a header (exception)
Definition: connection_impl.hpp:644
websocketpp::connection::ping
void ping(std::string const &payload)
Send a ping.
Definition: connection_impl.hpp:224
websocketpp::connection::write_frame
void write_frame()
Checks if there are frames in the send queue and if there are sends one.
Definition: connection_impl.hpp:1867
websocketpp::connection::get_subprotocol
std::string const & get_subprotocol() const
Gets the negotated subprotocol.
Definition: connection_impl.hpp:447
websocketpp::connection::ping
void ping(std::string const &payload, lib::error_code &ec)
exception free variant of ping
Definition: connection_impl.hpp:155
websocketpp::connection::set_pong_handler
void set_pong_handler(pong_handler h)
Set pong handler.
Definition: connection.hpp:398
websocketpp::connection::set_max_message_size
void set_max_message_size(size_t new_value)
Set maximum message size.
Definition: connection.hpp:575
websocketpp::connection::get_buffered_amount
size_t get_buffered_amount() const
Get the size of the outgoing write buffer (in payload bytes)
Definition: connection_impl.hpp:71
websocketpp::helper
static int const helper[]
Helper array to get around lack of initializer lists pre C++11.
Definition: connection.hpp:167
websocketpp::connection::resume_reading
lib::error_code resume_reading()
Resume reading of new data.
Definition: connection_impl.hpp:378
websocketpp::connection::set_interrupt_handler
void set_interrupt_handler(interrupt_handler h)
Set interrupt handler.
Definition: connection.hpp:432
websocketpp::connection::close
void close(close::status::value const code, std::string const &reason)
Close the connection.
Definition: connection_impl.hpp:326
websocketpp::connection::defer_http_response
lib::error_code defer_http_response()
Defer HTTP Response until later (Exception free)
Definition: connection_impl.hpp:717