Merge
[c11concurrency-benchmarks.git] / gdax-orderbook-hpp / demo / dependencies / websocketpp-0.7.0 / websocketpp / 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  */
59 typedef lib::function<void(connection_hdl)> open_handler;
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  */
69 typedef lib::function<void(connection_hdl)> close_handler;
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  */
79 typedef lib::function<void(connection_hdl)> fail_handler;
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  */
91 typedef lib::function<void(connection_hdl)> interrupt_handler;
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  */
101 typedef lib::function<bool(connection_hdl,std::string)> ping_handler;
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  */
109 typedef lib::function<void(connection_hdl,std::string)> pong_handler;
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  */
116 typedef lib::function<void(connection_hdl,std::string)> pong_timeout_handler;
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  */
129 typedef lib::function<bool(connection_hdl)> validate_handler;
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  */
151 typedef lib::function<void(connection_hdl)> http_handler;
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>
235 class connection
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
245     typedef lib::weak_ptr<type> weak_ptr;
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
256         transport_con_type;
257     /// Type of a shared pointer to the transport component of this connection
258     typedef typename transport_con_type::ptr transport_con_ptr;
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
277     typedef processor::processor<config> processor_type;
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
284     typedef typename transport_con_type::timer_ptr timer_ptr;
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, alog_type& alog,
298         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
336     ptr get_shared() {
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      */
351     void set_open_handler(open_handler h) {
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      */
361     void set_close_handler(close_handler h) {
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      */
372     void set_fail_handler(fail_handler h) {
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      */
387     void set_ping_handler(ping_handler h) {
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      */
398     void set_pong_handler(pong_handler h) {
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      */
421     void set_pong_timeout_handler(pong_timeout_handler h) {
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      */
432     void set_interrupt_handler(interrupt_handler h) {
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      */
447     void set_http_handler(http_handler h) {
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      */
463     void set_validate_handler(validate_handler h) {
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      */
525     void set_close_handshake_timeout(long dur) {
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      */
559     size_t get_max_message_size() const {
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      */
594     size_t get_max_http_body_size() const {
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      */
635     size_t buffered_amount() const {
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      */
655     lib::error_code send(std::string const & payload, frame::opcode::value op =
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      */
688     lib::error_code send(message_ptr msg);
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      */
703     lib::error_code interrupt();
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      */
728     lib::error_code pause_reading();
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      */
740     lib::error_code resume_reading();
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 request The subprotocol to request
896      * @param ec A reference to an error code that will be filled in the case of
897      * errors
898      */
899     void add_subprotocol(std::string const & request, lib::error_code & ec);
900
901     /// Adds the given subprotocol string to the request list
902     /**
903      * Adds a subprotocol to the list to send with the opening handshake. This
904      * may be called multiple times to request more than one. If the server
905      * supports one of these, it may choose one. If so, it will return it
906      * in it's handshake reponse and the value will be available via
907      * get_subprotocol(). Subprotocol requests should be added in order of
908      * preference.
909      *
910      * @param request The subprotocol to request
911      */
912     void add_subprotocol(std::string const & request);
913
914     /// Select a subprotocol to use (exception free)
915     /**
916      * Indicates which subprotocol should be used for this connection. Valid
917      * only during the validate handler callback. Subprotocol selected must have
918      * been requested by the client. Consult get_requested_subprotocols() for a
919      * list of valid subprotocols.
920      *
921      * This member function is valid on server endpoints/connections only
922      *
923      * @param value The subprotocol to select
924      * @param ec A reference to an error code that will be filled in the case of
925      * errors
926      */
927     void select_subprotocol(std::string const & value, lib::error_code & ec);
928
929     /// Select a subprotocol to use
930     /**
931      * Indicates which subprotocol should be used for this connection. Valid
932      * only during the validate handler callback. Subprotocol selected must have
933      * been requested by the client. Consult get_requested_subprotocols() for a
934      * list of valid subprotocols.
935      *
936      * This member function is valid on server endpoints/connections only
937      *
938      * @param value The subprotocol to select
939      */
940     void select_subprotocol(std::string const & value);
941
942     /////////////////////////////////////////////////////////////
943     // Pass-through access to the request and response objects //
944     /////////////////////////////////////////////////////////////
945
946     /// Retrieve a request header
947     /**
948      * Retrieve the value of a header from the handshake HTTP request.
949      *
950      * @param key Name of the header to get
951      * @return The value of the header
952      */
953     std::string const & get_request_header(std::string const & key) const;
954
955     /// Retrieve a request body
956     /**
957      * Retrieve the value of the request body. This value is typically used with
958      * PUT and POST requests to upload files or other data. Only HTTP
959      * connections will ever have bodies. WebSocket connection's will always
960      * have blank bodies.
961      *
962      * @return The value of the request body.
963      */
964     std::string const & get_request_body() const;
965
966     /// Retrieve a response header
967     /**
968      * Retrieve the value of a header from the handshake HTTP request.
969      *
970      * @param key Name of the header to get
971      * @return The value of the header
972      */
973     std::string const & get_response_header(std::string const & key) const;
974
975     /// Get response HTTP status code
976     /**
977      * Gets the response status code 
978      *
979      * @since 0.7.0
980      *
981      * @return The response status code sent
982      */
983     http::status_code::value get_response_code() const {
984         return m_response.get_status_code();
985     }
986
987     /// Get response HTTP status message
988     /**
989      * Gets the response status message 
990      *
991      * @since 0.7.0
992      *
993      * @return The response status message sent
994      */
995     std::string const & get_response_msg() const {
996         return m_response.get_status_msg();
997     }
998     
999     /// Set response status code and message
1000     /**
1001      * Sets the response status code to `code` and looks up the corresponding
1002      * message for standard codes. Non-standard codes will be entered as Unknown
1003      * use set_status(status_code::value,std::string) overload to set both
1004      * values explicitly.
1005      *
1006      * This member function is valid only from the http() and validate() handler
1007      * callbacks.
1008      *
1009      * @param code Code to set
1010      * @param msg Message to set
1011      * @see websocketpp::http::response::set_status
1012      */
1013     void set_status(http::status_code::value code);
1014
1015     /// Set response status code and message
1016     /**
1017      * Sets the response status code and message to independent custom values.
1018      * use set_status(status_code::value) to set the code and have the standard
1019      * message be automatically set.
1020      *
1021      * This member function is valid only from the http() and validate() handler
1022      * callbacks.
1023      *
1024      * @param code Code to set
1025      * @param msg Message to set
1026      * @see websocketpp::http::response::set_status
1027      */
1028     void set_status(http::status_code::value code, std::string const & msg);
1029
1030     /// Set response body content
1031     /**
1032      * Set the body content of the HTTP response to the parameter string. Note
1033      * set_body will also set the Content-Length HTTP header to the appropriate
1034      * value. If you want the Content-Length header to be something else set it
1035      * to something else after calling set_body
1036      *
1037      * This member function is valid only from the http() and validate() handler
1038      * callbacks.
1039      *
1040      * @param value String data to include as the body content.
1041      * @see websocketpp::http::response::set_body
1042      */
1043     void set_body(std::string const & value);
1044
1045     /// Append a header
1046     /**
1047      * If a header with this name already exists the value will be appended to
1048      * the existing header to form a comma separated list of values. Use
1049      * `connection::replace_header` to overwrite existing values.
1050      *
1051      * This member function is valid only from the http() and validate() handler
1052      * callbacks, or to a client connection before connect has been called.
1053      *
1054      * @param key Name of the header to set
1055      * @param val Value to add
1056      * @see replace_header
1057      * @see websocketpp::http::parser::append_header
1058      */
1059     void append_header(std::string const & key, std::string const & val);
1060
1061     /// Replace a header
1062     /**
1063      * If a header with this name already exists the old value will be replaced
1064      * Use `connection::append_header` to append to a list of existing values.
1065      *
1066      * This member function is valid only from the http() and validate() handler
1067      * callbacks, or to a client connection before connect has been called.
1068      *
1069      * @param key Name of the header to set
1070      * @param val Value to set
1071      * @see append_header
1072      * @see websocketpp::http::parser::replace_header
1073      */
1074     void replace_header(std::string const & key, std::string const & val);
1075
1076     /// Remove a header
1077     /**
1078      * Removes a header from the response.
1079      *
1080      * This member function is valid only from the http() and validate() handler
1081      * callbacks, or to a client connection before connect has been called.
1082      *
1083      * @param key The name of the header to remove
1084      * @see websocketpp::http::parser::remove_header
1085      */
1086     void remove_header(std::string const & key);
1087
1088     /// Get request object
1089     /**
1090      * Direct access to request object. This can be used to call methods of the
1091      * request object that are not part of the standard request API that
1092      * connection wraps.
1093      *
1094      * Note use of this method involves using behavior specific to the
1095      * configured HTTP policy. Such behavior may not work with alternate HTTP
1096      * policies.
1097      *
1098      * @since 0.3.0-alpha3
1099      *
1100      * @return A const reference to the raw request object
1101      */
1102     request_type const & get_request() const {
1103         return m_request;
1104     }
1105     
1106     /// Get response object
1107     /**
1108      * Direct access to the HTTP response sent or received as a part of the
1109      * opening handshake. This can be used to call methods of the response
1110      * object that are not part of the standard request API that connection
1111      * wraps.
1112      *
1113      * Note use of this method involves using behavior specific to the
1114      * configured HTTP policy. Such behavior may not work with alternate HTTP
1115      * policies.
1116      *
1117      * @since 0.7.0
1118      *
1119      * @return A const reference to the raw response object
1120      */
1121     response_type const & get_response() const {
1122         return m_response;
1123     }
1124     
1125     /// Defer HTTP Response until later (Exception free)
1126     /**
1127      * Used in the http handler to defer the HTTP response for this connection
1128      * until later. Handshake timers will be canceled and the connection will be
1129      * left open until `send_http_response` or an equivalent is called.
1130      *
1131      * Warning: deferred connections won't time out and as a result can tie up
1132      * resources.
1133      *
1134      * @since 0.6.0
1135      *
1136      * @return A status code, zero on success, non-zero otherwise
1137      */
1138     lib::error_code defer_http_response();
1139     
1140     /// Send deferred HTTP Response (exception free)
1141     /**
1142      * Sends an http response to an HTTP connection that was deferred. This will
1143      * send a complete response including all headers, status line, and body
1144      * text. The connection will be closed afterwards.
1145      *
1146      * @since 0.6.0
1147      *
1148      * @param ec A status code, zero on success, non-zero otherwise
1149      */
1150     void send_http_response(lib::error_code & ec);
1151     
1152     /// Send deferred HTTP Response
1153     void send_http_response();
1154     
1155     // TODO HTTPNBIO: write_headers
1156     // function that processes headers + status so far and writes it to the wire
1157     // beginning the HTTP response body state. This method will ignore anything
1158     // in the response body.
1159     
1160     // TODO HTTPNBIO: write_body_message
1161     // queues the specified message_buffer for async writing
1162     
1163     // TODO HTTPNBIO: finish connection
1164     //
1165     
1166     // TODO HTTPNBIO: write_response
1167     // Writes the whole response, headers + body and closes the connection
1168     
1169     
1170
1171     /////////////////////////////////////////////////////////////
1172     // Pass-through access to the other connection information //
1173     /////////////////////////////////////////////////////////////
1174
1175     /// Get Connection Handle
1176     /**
1177      * The connection handle is a token that can be shared outside the
1178      * WebSocket++ core for the purposes of identifying a connection and
1179      * sending it messages.
1180      *
1181      * @return A handle to the connection
1182      */
1183     connection_hdl get_handle() const {
1184         return m_connection_hdl;
1185     }
1186
1187     /// Get whether or not this connection is part of a server or client
1188     /**
1189      * @return whether or not the connection is attached to a server endpoint
1190      */
1191     bool is_server() const {
1192         return m_is_server;
1193     }
1194
1195     /// Return the same origin policy origin value from the opening request.
1196     /**
1197      * This value is available after the HTTP request has been fully read and
1198      * may be called from any thread.
1199      *
1200      * @return The connection's origin value from the opening handshake.
1201      */
1202     std::string const & get_origin() const;
1203
1204     /// Return the connection state.
1205     /**
1206      * Values can be connecting, open, closing, and closed
1207      *
1208      * @return The connection's current state.
1209      */
1210     session::state::value get_state() const;
1211
1212
1213     /// Get the WebSocket close code sent by this endpoint.
1214     /**
1215      * @return The WebSocket close code sent by this endpoint.
1216      */
1217     close::status::value get_local_close_code() const {
1218         return m_local_close_code;
1219     }
1220
1221     /// Get the WebSocket close reason sent by this endpoint.
1222     /**
1223      * @return The WebSocket close reason sent by this endpoint.
1224      */
1225     std::string const & get_local_close_reason() const {
1226         return m_local_close_reason;
1227     }
1228
1229     /// Get the WebSocket close code sent by the remote endpoint.
1230     /**
1231      * @return The WebSocket close code sent by the remote endpoint.
1232      */
1233     close::status::value get_remote_close_code() const {
1234         return m_remote_close_code;
1235     }
1236
1237     /// Get the WebSocket close reason sent by the remote endpoint.
1238     /**
1239      * @return The WebSocket close reason sent by the remote endpoint.
1240      */
1241     std::string const & get_remote_close_reason() const {
1242         return m_remote_close_reason;
1243     }
1244
1245     /// Get the internal error code for a closed/failed connection
1246     /**
1247      * Retrieves a machine readable detailed error code indicating the reason
1248      * that the connection was closed or failed. Valid only after the close or
1249      * fail handler is called.
1250      *
1251      * @return Error code indicating the reason the connection was closed or
1252      * failed
1253      */
1254     lib::error_code get_ec() const {
1255         return m_ec;
1256     }
1257
1258     /// Get a message buffer
1259     /**
1260      * Warning: The API related to directly sending message buffers may change
1261      * before the 1.0 release. If you plan to use it, please keep an eye on any
1262      * breaking changes notifications in future release notes. Also if you have
1263      * any feedback about usage and capabilities now is a great time to provide
1264      * it.
1265      *
1266      * Message buffers are used to store message payloads and other message
1267      * metadata.
1268      *
1269      * The size parameter is a hint only. Your final payload does not need to
1270      * match it. There may be some performance benefits if the initial size
1271      * guess is equal to or slightly higher than the final payload size.
1272      *
1273      * @param op The opcode for the new message
1274      * @param size A hint to optimize the initial allocation of payload space.
1275      * @return A new message buffer
1276      */
1277     message_ptr get_message(websocketpp::frame::opcode::value op, size_t size)
1278         const
1279     {
1280         return m_msg_manager->get_message(op, size);
1281     }
1282
1283     ////////////////////////////////////////////////////////////////////////
1284     // The remaining public member functions are for internal/policy use  //
1285     // only. Do not call from application code unless you understand what //
1286     // you are doing.                                                     //
1287     ////////////////////////////////////////////////////////////////////////
1288
1289     
1290
1291     void read_handshake(size_t num_bytes);
1292
1293     void handle_read_handshake(lib::error_code const & ec,
1294         size_t bytes_transferred);
1295     void handle_read_http_response(lib::error_code const & ec,
1296         size_t bytes_transferred);
1297
1298     
1299     void handle_write_http_response(lib::error_code const & ec);
1300     void handle_send_http_request(lib::error_code const & ec);
1301
1302     void handle_open_handshake_timeout(lib::error_code const & ec);
1303     void handle_close_handshake_timeout(lib::error_code const & ec);
1304
1305     void handle_read_frame(lib::error_code const & ec, size_t bytes_transferred);
1306     void read_frame();
1307
1308     /// Get array of WebSocket protocol versions that this connection supports.
1309     std::vector<int> const & get_supported_versions() const;
1310
1311     /// Sets the handler for a terminating connection. Should only be used
1312     /// internally by the endpoint class.
1313     void set_termination_handler(termination_handler new_handler);
1314
1315     void terminate(lib::error_code const & ec);
1316     void handle_terminate(terminate_status tstat, lib::error_code const & ec);
1317
1318     /// Checks if there are frames in the send queue and if there are sends one
1319     /**
1320      * \todo unit tests
1321      *
1322      * This method locks the m_write_lock mutex
1323      */
1324     void write_frame();
1325
1326     /// Process the results of a frame write operation and start the next write
1327     /**
1328      * \todo unit tests
1329      *
1330      * This method locks the m_write_lock mutex
1331      *
1332      * @param terminate Whether or not to terminate the connection upon
1333      * completion of this write.
1334      *
1335      * @param ec A status code from the transport layer, zero on success,
1336      * non-zero otherwise.
1337      */
1338     void handle_write_frame(lib::error_code const & ec);
1339 // protected:
1340     // This set of methods would really like to be protected, but doing so 
1341     // requires that the endpoint be able to friend the connection. This is 
1342     // allowed with C++11, but not prior versions
1343
1344     /// Start the connection state machine
1345     void start();
1346
1347     /// Set Connection Handle
1348     /**
1349      * The connection handle is a token that can be shared outside the
1350      * WebSocket++ core for the purposes of identifying a connection and
1351      * sending it messages.
1352      *
1353      * @param hdl A connection_hdl that the connection will use to refer
1354      * to itself.
1355      */
1356     void set_handle(connection_hdl hdl) {
1357         m_connection_hdl = hdl;
1358         transport_con_type::set_handle(hdl);
1359     }
1360 protected:
1361     void handle_transport_init(lib::error_code const & ec);
1362
1363     /// Set m_processor based on information in m_request. Set m_response
1364     /// status and return an error code indicating status.
1365     lib::error_code initialize_processor();
1366
1367     /// Perform WebSocket handshake validation of m_request using m_processor.
1368     /// set m_response and return an error code indicating status.
1369     lib::error_code process_handshake_request();
1370 private:
1371     
1372
1373     /// Completes m_response, serializes it, and sends it out on the wire.
1374     void write_http_response(lib::error_code const & ec);
1375
1376     /// Sends an opening WebSocket connect request
1377     void send_http_request();
1378
1379     /// Alternate path for write_http_response in error conditions
1380     void write_http_response_error(lib::error_code const & ec);
1381
1382     /// Process control message
1383     /**
1384      *
1385      */
1386     void process_control_frame(message_ptr msg);
1387
1388     /// Send close acknowledgement
1389     /**
1390      * If no arguments are present no close code/reason will be specified.
1391      *
1392      * Note: the close code/reason values provided here may be overrided by
1393      * other settings (such as silent close).
1394      *
1395      * @param code The close code to send
1396      * @param reason The close reason to send
1397      * @return A status code, zero on success, non-zero otherwise
1398      */
1399     lib::error_code send_close_ack(close::status::value code =
1400         close::status::blank, std::string const & reason = std::string());
1401
1402     /// Send close frame
1403     /**
1404      * If no arguments are present no close code/reason will be specified.
1405      *
1406      * Note: the close code/reason values provided here may be overrided by
1407      * other settings (such as silent close).
1408      *
1409      * The ack flag determines what to do in the case of a blank status and
1410      * whether or not to terminate the TCP connection after sending it.
1411      *
1412      * @param code The close code to send
1413      * @param reason The close reason to send
1414      * @param ack Whether or not this is an acknowledgement close frame
1415      * @return A status code, zero on success, non-zero otherwise
1416      */
1417     lib::error_code send_close_frame(close::status::value code =
1418         close::status::blank, std::string const & reason = std::string(), bool ack = false,
1419         bool terminal = false);
1420
1421     /// Get a pointer to a new WebSocket protocol processor for a given version
1422     /**
1423      * @param version Version number of the WebSocket protocol to get a
1424      * processor for. Negative values indicate invalid/unknown versions and will
1425      * always return a null ptr
1426      *
1427      * @return A shared_ptr to a new instance of the appropriate processor or a
1428      * null ptr if there is no installed processor that matches the version
1429      * number.
1430      */
1431     processor_ptr get_processor(int version) const;
1432
1433     /// Add a message to the write queue
1434     /**
1435      * Adds a message to the write queue and updates any associated shared state
1436      *
1437      * Must be called while holding m_write_lock
1438      *
1439      * @todo unit tests
1440      *
1441      * @param msg The message to push
1442      */
1443     void write_push(message_ptr msg);
1444
1445     /// Pop a message from the write queue
1446     /**
1447      * Removes and returns a message from the write queue and updates any
1448      * associated shared state.
1449      *
1450      * Must be called while holding m_write_lock
1451      *
1452      * @todo unit tests
1453      *
1454      * @return the message_ptr at the front of the queue
1455      */
1456     message_ptr write_pop();
1457
1458     /// Prints information about the incoming connection to the access log
1459     /**
1460      * Prints information about the incoming connection to the access log.
1461      * Includes: connection type, websocket version, remote endpoint, user agent
1462      * path, status code.
1463      */
1464     void log_open_result();
1465
1466     /// Prints information about a connection being closed to the access log
1467     /**
1468      * Includes: local and remote close codes and reasons
1469      */
1470     void log_close_result();
1471
1472     /// Prints information about a connection being failed to the access log
1473     /**
1474      * Includes: error code and message for why it was failed
1475      */
1476     void log_fail_result();
1477     
1478     /// Prints information about HTTP connections
1479     /**
1480      * Includes: TODO
1481      */
1482     void log_http_result();
1483
1484     /// Prints information about an arbitrary error code on the specified channel
1485     template <typename error_type>
1486     void log_err(log::level l, char const * msg, error_type const & ec) {
1487         std::stringstream s;
1488         s << msg << " error: " << ec << " (" << ec.message() << ")";
1489         m_elog.write(l, s.str());
1490     }
1491
1492     // internal handler functions
1493     read_handler            m_handle_read_frame;
1494     write_frame_handler     m_write_frame_handler;
1495
1496     // static settings
1497     std::string const       m_user_agent;
1498
1499     /// Pointer to the connection handle
1500     connection_hdl          m_connection_hdl;
1501
1502     /// Handler objects
1503     open_handler            m_open_handler;
1504     close_handler           m_close_handler;
1505     fail_handler            m_fail_handler;
1506     ping_handler            m_ping_handler;
1507     pong_handler            m_pong_handler;
1508     pong_timeout_handler    m_pong_timeout_handler;
1509     interrupt_handler       m_interrupt_handler;
1510     http_handler            m_http_handler;
1511     validate_handler        m_validate_handler;
1512     message_handler         m_message_handler;
1513
1514     /// constant values
1515     long                    m_open_handshake_timeout_dur;
1516     long                    m_close_handshake_timeout_dur;
1517     long                    m_pong_timeout_dur;
1518     size_t                  m_max_message_size;
1519
1520     /// External connection state
1521     /**
1522      * Lock: m_connection_state_lock
1523      */
1524     session::state::value   m_state;
1525
1526     /// Internal connection state
1527     /**
1528      * Lock: m_connection_state_lock
1529      */
1530     istate_type             m_internal_state;
1531
1532     mutable mutex_type      m_connection_state_lock;
1533
1534     /// The lock used to protect the message queue
1535     /**
1536      * Serializes access to the write queue as well as shared state within the
1537      * processor.
1538      */
1539     mutex_type              m_write_lock;
1540
1541     // connection resources
1542     char                    m_buf[config::connection_read_buffer_size];
1543     size_t                  m_buf_cursor;
1544     termination_handler     m_termination_handler;
1545     con_msg_manager_ptr     m_msg_manager;
1546     timer_ptr               m_handshake_timer;
1547     timer_ptr               m_ping_timer;
1548
1549     /// @todo this is not memory efficient. this value is not used after the
1550     /// handshake.
1551     std::string m_handshake_buffer;
1552
1553     /// Pointer to the processor object for this connection
1554     /**
1555      * The processor provides functionality that is specific to the WebSocket
1556      * protocol version that the client has negotiated. It also contains all of
1557      * the state necessary to encode and decode the incoming and outgoing
1558      * WebSocket byte streams
1559      *
1560      * Use of the prepare_data_frame method requires lock: m_write_lock
1561      */
1562     processor_ptr           m_processor;
1563
1564     /// Queue of unsent outgoing messages
1565     /**
1566      * Lock: m_write_lock
1567      */
1568     std::queue<message_ptr> m_send_queue;
1569
1570     /// Size in bytes of the outstanding payloads in the write queue
1571     /**
1572      * Lock: m_write_lock
1573      */
1574     size_t m_send_buffer_size;
1575
1576     /// buffer holding the various parts of the current message being writen
1577     /**
1578      * Lock m_write_lock
1579      */
1580     std::vector<transport::buffer> m_send_buffer;
1581
1582     /// a list of pointers to hold on to the messages being written to keep them
1583     /// from going out of scope before the write is complete.
1584     std::vector<message_ptr> m_current_msgs;
1585
1586     /// True if there is currently an outstanding transport write
1587     /**
1588      * Lock m_write_lock
1589      */
1590     bool m_write_flag;
1591
1592     /// True if this connection is presently reading new data
1593     bool m_read_flag;
1594
1595     // connection data
1596     request_type            m_request;
1597     response_type           m_response;
1598     uri_ptr                 m_uri;
1599     std::string             m_subprotocol;
1600
1601     // connection data that might not be necessary to keep around for the life
1602     // of the whole connection.
1603     std::vector<std::string> m_requested_subprotocols;
1604
1605     bool const              m_is_server;
1606     alog_type& m_alog;
1607     elog_type& m_elog;
1608
1609     rng_type & m_rng;
1610
1611     // Close state
1612     /// Close code that was sent on the wire by this endpoint
1613     close::status::value    m_local_close_code;
1614
1615     /// Close reason that was sent on the wire by this endpoint
1616     std::string             m_local_close_reason;
1617
1618     /// Close code that was received on the wire from the remote endpoint
1619     close::status::value    m_remote_close_code;
1620
1621     /// Close reason that was received on the wire from the remote endpoint
1622     std::string             m_remote_close_reason;
1623
1624     /// Detailed internal error code
1625     lib::error_code m_ec;
1626     
1627     /// A flag that gets set once it is determined that the connection is an
1628     /// HTTP connection and not a WebSocket one.
1629     bool m_is_http;
1630     
1631     /// A flag that gets set when the completion of an http connection is
1632     /// deferred until later.
1633     session::http_state::value m_http_state;
1634
1635     bool m_was_clean;
1636
1637     /// Whether or not this endpoint initiated the closing handshake.
1638     bool                    m_closed_by_me;
1639
1640     /// ???
1641     bool                    m_failed_by_me;
1642
1643     /// Whether or not this endpoint initiated the drop of the TCP connection
1644     bool                    m_dropped_by_me;
1645 };
1646
1647 } // namespace websocketpp
1648
1649 #include <websocketpp/impl/connection_impl.hpp>
1650
1651 #endif // WEBSOCKETPP_CONNECTION_HPP