fixed adding file problem
[c11concurrency-benchmarks.git] / gdax-orderbook-hpp / demo / dependencies / websocketpp-0.7.0 / websocketpp / processors / hybi13.hpp
1 /*
2  * Copyright (c) 2015, 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_PROCESSOR_HYBI13_HPP
29 #define WEBSOCKETPP_PROCESSOR_HYBI13_HPP
30
31 #include <websocketpp/processors/processor.hpp>
32
33 #include <websocketpp/frame.hpp>
34 #include <websocketpp/http/constants.hpp>
35
36 #include <websocketpp/utf8_validator.hpp>
37 #include <websocketpp/sha1/sha1.hpp>
38 #include <websocketpp/base64/base64.hpp>
39
40 #include <websocketpp/common/network.hpp>
41 #include <websocketpp/common/platforms.hpp>
42
43 #include <algorithm>
44 #include <cassert>
45 #include <string>
46 #include <vector>
47 #include <utility>
48
49 namespace websocketpp {
50 namespace processor {
51
52 /// Processor for Hybi version 13 (RFC6455)
53 template <typename config>
54 class hybi13 : public processor<config> {
55 public:
56     typedef processor<config> base;
57
58     typedef typename config::request_type request_type;
59     typedef typename config::response_type response_type;
60
61     typedef typename config::message_type message_type;
62     typedef typename message_type::ptr message_ptr;
63
64     typedef typename config::con_msg_manager_type msg_manager_type;
65     typedef typename msg_manager_type::ptr msg_manager_ptr;
66     typedef typename config::rng_type rng_type;
67
68     typedef typename config::permessage_deflate_type permessage_deflate_type;
69
70     typedef std::pair<lib::error_code,std::string> err_str_pair;
71
72     explicit hybi13(bool secure, bool p_is_server, msg_manager_ptr manager, rng_type& rng)
73       : processor<config>(secure, p_is_server)
74       , m_msg_manager(manager)
75       , m_rng(rng)
76     {
77         reset_headers();
78     }
79
80     int get_version() const {
81         return 13;
82     }
83
84     bool has_permessage_deflate() const {
85         return m_permessage_deflate.is_implemented();
86     }
87
88     err_str_pair negotiate_extensions(request_type const & request) {
89         return negotiate_extensions_helper(request);
90     }
91     
92     err_str_pair negotiate_extensions(response_type const & response) {
93         return negotiate_extensions_helper(response);
94     }
95     
96     /// Extension negotiation helper function
97     /**
98      * This exists mostly because the code for requests and responses is
99      * identical and I can't have virtual template methods.
100      */
101     template <typename header_type>
102     err_str_pair negotiate_extensions_helper(header_type const & header) {
103         err_str_pair ret;
104
105         // Respect blanket disabling of all extensions and don't even parse
106         // the extension header
107         if (!config::enable_extensions) {
108             ret.first = make_error_code(error::extensions_disabled);
109             return ret;
110         }
111
112         http::parameter_list p;
113
114         bool error = header.get_header_as_plist("Sec-WebSocket-Extensions",p);
115
116         if (error) {
117             ret.first = make_error_code(error::extension_parse_error);
118             return ret;
119         }
120
121         // If there are no extensions parsed then we are done!
122         if (p.size() == 0) {
123             return ret;
124         }
125
126         http::parameter_list::const_iterator it;
127
128         if (m_permessage_deflate.is_implemented()) {
129             err_str_pair neg_ret;
130             for (it = p.begin(); it != p.end(); ++it) {
131                 // look through each extension, if the key is permessage-deflate
132                 if (it->first == "permessage-deflate") {
133                     // if we have already successfully negotiated this extension
134                     // then skip any other requests to negotiate the same one
135                     // with different parameters 
136                     if (m_permessage_deflate.is_enabled()) {
137                         continue;
138                     }
139                     
140                     
141                     neg_ret = m_permessage_deflate.negotiate(it->second);
142
143                     if (neg_ret.first) {
144                         // Figure out if this is an error that should halt all
145                         // extension negotiations or simply cause negotiation of
146                         // this specific extension to fail.
147                         //std::cout << "permessage-compress negotiation failed: "
148                         //          << neg_ret.first.message() << std::endl;
149                     } else {
150                         // Note: this list will need commas if WebSocket++ ever
151                         // supports more than one extension
152                         ret.second += neg_ret.second;
153                         m_permessage_deflate.init(base::m_server);
154                         continue;
155                     }
156                 }
157             }
158         }
159
160         return ret;
161     }
162
163     lib::error_code validate_handshake(request_type const & r) const {
164         if (r.get_method() != "GET") {
165             return make_error_code(error::invalid_http_method);
166         }
167
168         if (r.get_version() != "HTTP/1.1") {
169             return make_error_code(error::invalid_http_version);
170         }
171
172         // required headers
173         // Host is required by HTTP/1.1
174         // Connection is required by is_websocket_handshake
175         // Upgrade is required by is_websocket_handshake
176         if (r.get_header("Sec-WebSocket-Key").empty()) {
177             return make_error_code(error::missing_required_header);
178         }
179
180         return lib::error_code();
181     }
182
183     /* TODO: the 'subprotocol' parameter may need to be expanded into a more
184      * generic struct if other user input parameters to the processed handshake
185      * are found.
186      */
187     lib::error_code process_handshake(request_type const & request, 
188         std::string const & subprotocol, response_type & response) const
189     {
190         std::string server_key = request.get_header("Sec-WebSocket-Key");
191
192         lib::error_code ec = process_handshake_key(server_key);
193
194         if (ec) {
195             return ec;
196         }
197
198         response.replace_header("Sec-WebSocket-Accept",server_key);
199         response.append_header("Upgrade",constants::upgrade_token);
200         response.append_header("Connection",constants::connection_token);
201
202         if (!subprotocol.empty()) {
203             response.replace_header("Sec-WebSocket-Protocol",subprotocol);
204         }
205
206         return lib::error_code();
207     }
208
209     /// Fill in a set of request headers for a client connection request
210     /**
211      * @param [out] req  Set of headers to fill in
212      * @param [in] uri The uri being connected to
213      * @param [in] subprotocols The list of subprotocols to request
214      */
215     lib::error_code client_handshake_request(request_type & req, uri_ptr
216         uri, std::vector<std::string> const & subprotocols) const
217     {
218         req.set_method("GET");
219         req.set_uri(uri->get_resource());
220         req.set_version("HTTP/1.1");
221
222         req.append_header("Upgrade","websocket");
223         req.append_header("Connection","Upgrade");
224         req.replace_header("Sec-WebSocket-Version","13");
225         req.replace_header("Host",uri->get_host_port());
226
227         if (!subprotocols.empty()) {
228             std::ostringstream result;
229             std::vector<std::string>::const_iterator it = subprotocols.begin();
230             result << *it++;
231             while (it != subprotocols.end()) {
232                 result << ", " << *it++;
233             }
234
235             req.replace_header("Sec-WebSocket-Protocol",result.str());
236         }
237
238         // Generate handshake key
239         frame::uint32_converter conv;
240         unsigned char raw_key[16];
241
242         for (int i = 0; i < 4; i++) {
243             conv.i = m_rng();
244             std::copy(conv.c,conv.c+4,&raw_key[i*4]);
245         }
246
247         req.replace_header("Sec-WebSocket-Key",base64_encode(raw_key, 16));
248
249         if (m_permessage_deflate.is_implemented()) {
250             std::string offer = m_permessage_deflate.generate_offer();
251             if (!offer.empty()) {
252                 req.replace_header("Sec-WebSocket-Extensions",offer);
253             }
254         }
255
256         return lib::error_code();
257     }
258
259     /// Validate the server's response to an outgoing handshake request
260     /**
261      * @param req The original request sent
262      * @param res The reponse to generate
263      * @return An error code, 0 on success, non-zero for other errors
264      */
265     lib::error_code validate_server_handshake_response(request_type const & req,
266         response_type& res) const
267     {
268         // A valid response has an HTTP 101 switching protocols code
269         if (res.get_status_code() != http::status_code::switching_protocols) {
270             return error::make_error_code(error::invalid_http_status);
271         }
272
273         // And the upgrade token in an upgrade header
274         std::string const & upgrade_header = res.get_header("Upgrade");
275         if (utility::ci_find_substr(upgrade_header, constants::upgrade_token,
276             sizeof(constants::upgrade_token)-1) == upgrade_header.end())
277         {
278             return error::make_error_code(error::missing_required_header);
279         }
280
281         // And the websocket token in the connection header
282         std::string const & con_header = res.get_header("Connection");
283         if (utility::ci_find_substr(con_header, constants::connection_token,
284             sizeof(constants::connection_token)-1) == con_header.end())
285         {
286             return error::make_error_code(error::missing_required_header);
287         }
288
289         // And has a valid Sec-WebSocket-Accept value
290         std::string key = req.get_header("Sec-WebSocket-Key");
291         lib::error_code ec = process_handshake_key(key);
292
293         if (ec || key != res.get_header("Sec-WebSocket-Accept")) {
294             return error::make_error_code(error::missing_required_header);
295         }
296
297         // check extensions
298
299         return lib::error_code();
300     }
301
302     std::string get_raw(response_type const & res) const {
303         return res.raw();
304     }
305
306     std::string const & get_origin(request_type const & r) const {
307         return r.get_header("Origin");
308     }
309
310     lib::error_code extract_subprotocols(request_type const & req,
311         std::vector<std::string> & subprotocol_list)
312     {
313         if (!req.get_header("Sec-WebSocket-Protocol").empty()) {
314             http::parameter_list p;
315
316              if (!req.get_header_as_plist("Sec-WebSocket-Protocol",p)) {
317                  http::parameter_list::const_iterator it;
318
319                  for (it = p.begin(); it != p.end(); ++it) {
320                      subprotocol_list.push_back(it->first);
321                  }
322              } else {
323                  return error::make_error_code(error::subprotocol_parse_error);
324              }
325         }
326         return lib::error_code();
327     }
328
329     uri_ptr get_uri(request_type const & request) const {
330         return get_uri_from_host(request,(base::m_secure ? "wss" : "ws"));
331     }
332
333     /// Process new websocket connection bytes
334     /**
335      *
336      * Hybi 13 data streams represent a series of variable length frames. Each
337      * frame is made up of a series of fixed length fields. The lengths of later
338      * fields are contained in earlier fields. The first field length is fixed
339      * by the spec.
340      *
341      * This processor represents a state machine that keeps track of what field
342      * is presently being read and how many more bytes are needed to complete it
343      *
344      *
345      *
346      *
347      * Read two header bytes
348      *   Extract full frame length.
349      *   Read extra header bytes
350      * Validate frame header (including extension validate)
351      * Read extension data into extension message state object
352      * Read payload data into payload
353      *
354      * @param buf Input buffer
355      *
356      * @param len Length of input buffer
357      *
358      * @return Number of bytes processed or zero on error
359      */
360     size_t consume(uint8_t * buf, size_t len, lib::error_code & ec) {
361         size_t p = 0;
362
363         ec = lib::error_code();
364
365         //std::cout << "consume: " << utility::to_hex(buf,len) << std::endl;
366
367         // Loop while we don't have a message ready and we still have bytes
368         // left to process.
369         while (m_state != READY && m_state != FATAL_ERROR &&
370                (p < len || m_bytes_needed == 0))
371         {
372             if (m_state == HEADER_BASIC) {
373                 p += this->copy_basic_header_bytes(buf+p,len-p);
374
375                 if (m_bytes_needed > 0) {
376                     continue;
377                 }
378
379                 ec = this->validate_incoming_basic_header(
380                     m_basic_header, base::m_server, !m_data_msg.msg_ptr
381                 );
382                 if (ec) {break;}
383
384                 // extract full header size and adjust consume state accordingly
385                 m_state = HEADER_EXTENDED;
386                 m_cursor = 0;
387                 m_bytes_needed = frame::get_header_len(m_basic_header) -
388                     frame::BASIC_HEADER_LENGTH;
389             } else if (m_state == HEADER_EXTENDED) {
390                 p += this->copy_extended_header_bytes(buf+p,len-p);
391
392                 if (m_bytes_needed > 0) {
393                     continue;
394                 }
395
396                 ec = validate_incoming_extended_header(m_basic_header,m_extended_header);
397                 if (ec){break;}
398
399                 m_state = APPLICATION;
400                 m_bytes_needed = static_cast<size_t>(get_payload_size(m_basic_header,m_extended_header));
401
402                 // check if this frame is the start of a new message and set up
403                 // the appropriate message metadata.
404                 frame::opcode::value op = frame::get_opcode(m_basic_header);
405
406                 // TODO: get_message failure conditions
407
408                 if (frame::opcode::is_control(op)) {
409                     m_control_msg = msg_metadata(
410                         m_msg_manager->get_message(op,m_bytes_needed),
411                         frame::get_masking_key(m_basic_header,m_extended_header)
412                     );
413
414                     m_current_msg = &m_control_msg;
415                 } else {
416                     if (!m_data_msg.msg_ptr) {
417                         if (m_bytes_needed > base::m_max_message_size) {
418                             ec = make_error_code(error::message_too_big);
419                             break;
420                         }
421                         
422                         m_data_msg = msg_metadata(
423                             m_msg_manager->get_message(op,m_bytes_needed),
424                             frame::get_masking_key(m_basic_header,m_extended_header)
425                         );
426                         
427                         if (m_permessage_deflate.is_enabled()) {
428                             m_data_msg.msg_ptr->set_compressed(frame::get_rsv1(m_basic_header));
429                         }
430                     } else {
431                         // Fetch the underlying payload buffer from the data message we
432                         // are writing into.
433                         std::string & out = m_data_msg.msg_ptr->get_raw_payload();
434                         
435                         if (out.size() + m_bytes_needed > base::m_max_message_size) {
436                             ec = make_error_code(error::message_too_big);
437                             break;
438                         }
439                         
440                         // Each frame starts a new masking key. All other state
441                         // remains between frames.
442                         m_data_msg.prepared_key = prepare_masking_key(
443                             frame::get_masking_key(
444                                 m_basic_header,
445                                 m_extended_header
446                             )
447                         );
448                         
449                         out.reserve(out.size() + m_bytes_needed);
450                     }
451                     m_current_msg = &m_data_msg;
452                 }
453             } else if (m_state == EXTENSION) {
454                 m_state = APPLICATION;
455             } else if (m_state == APPLICATION) {
456                 size_t bytes_to_process = (std::min)(m_bytes_needed,len-p);
457
458                 if (bytes_to_process > 0) {
459                     p += this->process_payload_bytes(buf+p,bytes_to_process,ec);
460
461                     if (ec) {break;}
462                 }
463
464                 if (m_bytes_needed > 0) {
465                     continue;
466                 }
467
468                 // If this was the last frame in the message set the ready flag.
469                 // Otherwise, reset processor state to read additional frames.
470                 if (frame::get_fin(m_basic_header)) {
471                     ec = finalize_message();
472                     if (ec) {
473                         break;
474                     }
475                 } else {
476                     this->reset_headers();
477                 }
478             } else {
479                 // shouldn't be here
480                 ec = make_error_code(error::general);
481                 return 0;
482             }
483         }
484
485         return p;
486     }
487
488     /// Perform any finalization actions on an incoming message
489     /**
490      * Called after the full message is received. Provides the opportunity for
491      * extensions to complete any data post processing as well as final UTF8
492      * validation checks for text messages.
493      *
494      * @return A code indicating errors, if any
495      */
496     lib::error_code finalize_message() {
497         std::string & out = m_current_msg->msg_ptr->get_raw_payload();
498
499         // if the frame is compressed, append the compression
500         // trailer and flush the compression buffer.
501         if (m_permessage_deflate.is_enabled()
502             && m_current_msg->msg_ptr->get_compressed())
503         {
504             uint8_t trailer[4] = {0x00, 0x00, 0xff, 0xff};
505
506             // Decompress current buffer into the message buffer
507             lib::error_code ec;
508             ec = m_permessage_deflate.decompress(trailer,4,out);
509             if (ec) {
510                 return ec;
511             }
512         }
513
514         // ensure that text messages end on a valid UTF8 code point
515         if (frame::get_opcode(m_basic_header) == frame::opcode::TEXT) {
516             if (!m_current_msg->validator.complete()) {
517                 return make_error_code(error::invalid_utf8);
518             }
519         }
520
521         m_state = READY;
522
523         return lib::error_code();
524     }
525
526     void reset_headers() {
527         m_state = HEADER_BASIC;
528         m_bytes_needed = frame::BASIC_HEADER_LENGTH;
529
530         m_basic_header.b0 = 0x00;
531         m_basic_header.b1 = 0x00;
532
533         std::fill_n(
534             m_extended_header.bytes,
535             frame::MAX_EXTENDED_HEADER_LENGTH,
536             0x00
537         );
538     }
539
540     /// Test whether or not the processor has a message ready
541     bool ready() const {
542         return (m_state == READY);
543     }
544
545     message_ptr get_message() {
546         if (!ready()) {
547             return message_ptr();
548         }
549         message_ptr ret = m_current_msg->msg_ptr;
550         m_current_msg->msg_ptr.reset();
551
552         if (frame::opcode::is_control(ret->get_opcode())) {
553             m_control_msg.msg_ptr.reset();
554         } else {
555             m_data_msg.msg_ptr.reset();
556         }
557
558         this->reset_headers();
559
560         return ret;
561     }
562
563     /// Test whether or not the processor is in a fatal error state.
564     bool get_error() const {
565         return m_state == FATAL_ERROR;
566     }
567
568     size_t get_bytes_needed() const {
569         return m_bytes_needed;
570     }
571
572     /// Prepare a user data message for writing
573     /**
574      * Performs validation, masking, compression, etc. will return an error if
575      * there was an error, otherwise msg will be ready to be written
576      *
577      * TODO: tests
578      *
579      * @param in An unprepared message to prepare
580      * @param out A message to be overwritten with the prepared message
581      * @return error code
582      */
583     virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out)
584     {
585         if (!in || !out) {
586             return make_error_code(error::invalid_arguments);
587         }
588
589         frame::opcode::value op = in->get_opcode();
590
591         // validate opcode: only regular data frames
592         if (frame::opcode::is_control(op)) {
593             return make_error_code(error::invalid_opcode);
594         }
595
596         std::string& i = in->get_raw_payload();
597         std::string& o = out->get_raw_payload();
598
599         // validate payload utf8
600         if (op == frame::opcode::TEXT && !utf8_validator::validate(i)) {
601             return make_error_code(error::invalid_payload);
602         }
603
604         frame::masking_key_type key;
605         bool masked = !base::m_server;
606         bool compressed = m_permessage_deflate.is_enabled()
607                           && in->get_compressed();
608         bool fin = in->get_fin();
609
610         if (masked) {
611             // Generate masking key.
612             key.i = m_rng();
613         } else {
614             key.i = 0;
615         }
616
617         // prepare payload
618         if (compressed) {
619             // compress and store in o after header.
620             m_permessage_deflate.compress(i,o);
621
622             if (o.size() < 4) {
623                 return make_error_code(error::general);
624             }
625
626             // Strip trailing 4 0x00 0x00 0xff 0xff bytes before writing to the
627             // wire
628             o.resize(o.size()-4);
629
630             // mask in place if necessary
631             if (masked) {
632                 this->masked_copy(o,o,key);
633             }
634         } else {
635             // no compression, just copy data into the output buffer
636             o.resize(i.size());
637
638             // if we are masked, have the masking function write to the output
639             // buffer directly to avoid another copy. If not masked, copy
640             // directly without masking.
641             if (masked) {
642                 this->masked_copy(i,o,key);
643             } else {
644                 std::copy(i.begin(),i.end(),o.begin());
645             }
646         }
647
648         // generate header
649         frame::basic_header h(op,o.size(),fin,masked,compressed);
650
651         if (masked) {
652             frame::extended_header e(o.size(),key.i);
653             out->set_header(frame::prepare_header(h,e));
654         } else {
655             frame::extended_header e(o.size());
656             out->set_header(frame::prepare_header(h,e));
657         }
658
659         out->set_prepared(true);
660         out->set_opcode(op);
661
662         return lib::error_code();
663     }
664
665     /// Get URI
666     lib::error_code prepare_ping(std::string const & in, message_ptr out) const {
667         return this->prepare_control(frame::opcode::PING,in,out);
668     }
669
670     lib::error_code prepare_pong(std::string const & in, message_ptr out) const {
671         return this->prepare_control(frame::opcode::PONG,in,out);
672     }
673
674     virtual lib::error_code prepare_close(close::status::value code,
675         std::string const & reason, message_ptr out) const
676     {
677         if (close::status::reserved(code)) {
678             return make_error_code(error::reserved_close_code);
679         }
680
681         if (close::status::invalid(code) && code != close::status::no_status) {
682             return make_error_code(error::invalid_close_code);
683         }
684
685         if (code == close::status::no_status && reason.size() > 0) {
686             return make_error_code(error::reason_requires_code);
687         }
688
689         if (reason.size() > frame:: limits::payload_size_basic-2) {
690             return make_error_code(error::control_too_big);
691         }
692
693         std::string payload;
694
695         if (code != close::status::no_status) {
696             close::code_converter val;
697             val.i = htons(code);
698
699             payload.resize(reason.size()+2);
700
701             payload[0] = val.c[0];
702             payload[1] = val.c[1];
703
704             std::copy(reason.begin(),reason.end(),payload.begin()+2);
705         }
706
707         return this->prepare_control(frame::opcode::CLOSE,payload,out);
708     }
709 protected:
710     /// Convert a client handshake key into a server response key in place
711     lib::error_code process_handshake_key(std::string & key) const {
712         key.append(constants::handshake_guid);
713
714         unsigned char message_digest[20];
715         sha1::calc(key.c_str(),key.length(),message_digest);
716         key = base64_encode(message_digest,20);
717
718         return lib::error_code();
719     }
720
721     /// Reads bytes from buf into m_basic_header
722     size_t copy_basic_header_bytes(uint8_t const * buf, size_t len) {
723         if (len == 0 || m_bytes_needed == 0) {
724             return 0;
725         }
726
727         if (len > 1) {
728             // have at least two bytes
729             if (m_bytes_needed == 2) {
730                 m_basic_header.b0 = buf[0];
731                 m_basic_header.b1 = buf[1];
732                 m_bytes_needed -= 2;
733                 return 2;
734             } else {
735                 m_basic_header.b1 = buf[0];
736                 m_bytes_needed--;
737                 return 1;
738             }
739         } else {
740             // have exactly one byte
741             if (m_bytes_needed == 2) {
742                 m_basic_header.b0 = buf[0];
743                 m_bytes_needed--;
744                 return 1;
745             } else {
746                 m_basic_header.b1 = buf[0];
747                 m_bytes_needed--;
748                 return 1;
749             }
750         }
751     }
752
753     /// Reads bytes from buf into m_extended_header
754     size_t copy_extended_header_bytes(uint8_t const * buf, size_t len) {
755         size_t bytes_to_read = (std::min)(m_bytes_needed,len);
756
757         std::copy(buf,buf+bytes_to_read,m_extended_header.bytes+m_cursor);
758         m_cursor += bytes_to_read;
759         m_bytes_needed -= bytes_to_read;
760
761         return bytes_to_read;
762     }
763
764     /// Reads bytes from buf into message payload
765     /**
766      * This function performs unmasking and uncompression, validates the
767      * decoded bytes, and writes them to the appropriate message buffer.
768      *
769      * This member function will use the input buffer as stratch space for its
770      * work. The raw input bytes will not be preserved. This applies only to the
771      * bytes actually needed. At most min(m_bytes_needed,len) will be processed.
772      *
773      * @param buf Input/working buffer
774      * @param len Length of buf
775      * @return Number of bytes processed or zero in case of an error
776      */
777     size_t process_payload_bytes(uint8_t * buf, size_t len, lib::error_code& ec)
778     {
779         // unmask if masked
780         if (frame::get_masked(m_basic_header)) {
781             m_current_msg->prepared_key = frame::byte_mask_circ(
782                 buf, len, m_current_msg->prepared_key);
783             // TODO: SIMD masking
784         }
785
786         std::string & out = m_current_msg->msg_ptr->get_raw_payload();
787         size_t offset = out.size();
788
789         // decompress message if needed.
790         if (m_permessage_deflate.is_enabled()
791             && m_current_msg->msg_ptr->get_compressed())
792         {
793             // Decompress current buffer into the message buffer
794             ec = m_permessage_deflate.decompress(buf,len,out);
795             if (ec) {
796                 return 0;
797             }
798         } else {
799             // No compression, straight copy
800             out.append(reinterpret_cast<char *>(buf),len);
801         }
802
803         // validate unmasked, decompressed values
804         if (m_current_msg->msg_ptr->get_opcode() == frame::opcode::TEXT) {
805             if (!m_current_msg->validator.decode(out.begin()+offset,out.end())) {
806                 ec = make_error_code(error::invalid_utf8);
807                 return 0;
808             }
809         }
810
811         m_bytes_needed -= len;
812
813         return len;
814     }
815
816     /// Validate an incoming basic header
817     /**
818      * Validates an incoming hybi13 basic header.
819      *
820      * @param h The basic header to validate
821      * @param is_server Whether or not the endpoint that received this frame
822      * is a server.
823      * @param new_msg Whether or not this is the first frame of the message
824      * @return 0 on success or a non-zero error code on failure
825      */
826     lib::error_code validate_incoming_basic_header(frame::basic_header const & h,
827         bool is_server, bool new_msg) const
828     {
829         frame::opcode::value op = frame::get_opcode(h);
830
831         // Check control frame size limit
832         if (frame::opcode::is_control(op) &&
833             frame::get_basic_size(h) > frame::limits::payload_size_basic)
834         {
835             return make_error_code(error::control_too_big);
836         }
837
838         // Check that RSV bits are clear
839         // The only RSV bits allowed are rsv1 if the permessage_compress
840         // extension is enabled for this connection and the message is not
841         // a control message.
842         //
843         // TODO: unit tests for this
844         if (frame::get_rsv1(h) && (!m_permessage_deflate.is_enabled()
845                 || frame::opcode::is_control(op)))
846         {
847             return make_error_code(error::invalid_rsv_bit);
848         }
849
850         if (frame::get_rsv2(h) || frame::get_rsv3(h)) {
851             return make_error_code(error::invalid_rsv_bit);
852         }
853
854         // Check for reserved opcodes
855         if (frame::opcode::reserved(op)) {
856             return make_error_code(error::invalid_opcode);
857         }
858
859         // Check for invalid opcodes
860         // TODO: unit tests for this?
861         if (frame::opcode::invalid(op)) {
862             return make_error_code(error::invalid_opcode);
863         }
864
865         // Check for fragmented control message
866         if (frame::opcode::is_control(op) && !frame::get_fin(h)) {
867             return make_error_code(error::fragmented_control);
868         }
869
870         // Check for continuation without an active message
871         if (new_msg && op == frame::opcode::CONTINUATION) {
872             return make_error_code(error::invalid_continuation);
873         }
874
875         // Check for new data frame when expecting continuation
876         if (!new_msg && !frame::opcode::is_control(op) &&
877             op != frame::opcode::CONTINUATION)
878         {
879             return make_error_code(error::invalid_continuation);
880         }
881
882         // Servers should reject any unmasked frames from clients.
883         // Clients should reject any masked frames from servers.
884         if (is_server && !frame::get_masked(h)) {
885             return make_error_code(error::masking_required);
886         } else if (!is_server && frame::get_masked(h)) {
887             return make_error_code(error::masking_forbidden);
888         }
889
890         return lib::error_code();
891     }
892
893     /// Validate an incoming extended header
894     /**
895      * Validates an incoming hybi13 full header.
896      *
897      * @todo unit test for the >32 bit frames on 32 bit systems case
898      *
899      * @param h The basic header to validate
900      * @param e The extended header to validate
901      * @return An error_code, non-zero values indicate why the validation
902      * failed
903      */
904     lib::error_code validate_incoming_extended_header(frame::basic_header h,
905         frame::extended_header e) const
906     {
907         uint8_t basic_size = frame::get_basic_size(h);
908         uint64_t payload_size = frame::get_payload_size(h,e);
909
910         // Check for non-minimally encoded payloads
911         if (basic_size == frame::payload_size_code_16bit &&
912             payload_size <= frame::limits::payload_size_basic)
913         {
914             return make_error_code(error::non_minimal_encoding);
915         }
916
917         if (basic_size == frame::payload_size_code_64bit &&
918             payload_size <= frame::limits::payload_size_extended)
919         {
920             return make_error_code(error::non_minimal_encoding);
921         }
922
923         // Check for >32bit frames on 32 bit systems
924         if (sizeof(size_t) == 4 && (payload_size >> 32)) {
925             return make_error_code(error::requires_64bit);
926         }
927
928         return lib::error_code();
929     }
930
931     /// Copy and mask/unmask in one operation
932     /**
933      * Reads input from one string and writes unmasked output to another.
934      *
935      * @param [in] i The input string.
936      * @param [out] o The output string.
937      * @param [in] key The masking key to use for masking/unmasking
938      */
939     void masked_copy (std::string const & i, std::string & o,
940         frame::masking_key_type key) const
941     {
942         frame::byte_mask(i.begin(),i.end(),o.begin(),key);
943         // TODO: SIMD masking
944     }
945
946     /// Generic prepare control frame with opcode and payload.
947     /**
948      * Internal control frame building method. Handles validation, masking, etc
949      *
950      * @param op The control opcode to use
951      * @param payload The payload to use
952      * @param out The message buffer to store the prepared frame in
953      * @return Status code, zero on success, non-zero on error
954      */
955     lib::error_code prepare_control(frame::opcode::value op,
956         std::string const & payload, message_ptr out) const
957     {
958         if (!out) {
959             return make_error_code(error::invalid_arguments);
960         }
961
962         if (!frame::opcode::is_control(op)) {
963             return make_error_code(error::invalid_opcode);
964         }
965
966         if (payload.size() > frame::limits::payload_size_basic) {
967             return make_error_code(error::control_too_big);
968         }
969
970         frame::masking_key_type key;
971         bool masked = !base::m_server;
972
973         frame::basic_header h(op,payload.size(),true,masked);
974
975         std::string & o = out->get_raw_payload();
976         o.resize(payload.size());
977
978         if (masked) {
979             // Generate masking key.
980             key.i = m_rng();
981
982             frame::extended_header e(payload.size(),key.i);
983             out->set_header(frame::prepare_header(h,e));
984             this->masked_copy(payload,o,key);
985         } else {
986             frame::extended_header e(payload.size());
987             out->set_header(frame::prepare_header(h,e));
988             std::copy(payload.begin(),payload.end(),o.begin());
989         }
990     
991         out->set_opcode(op);
992         out->set_prepared(true);
993
994         return lib::error_code();
995     }
996
997     enum state {
998         HEADER_BASIC = 0,
999         HEADER_EXTENDED = 1,
1000         EXTENSION = 2,
1001         APPLICATION = 3,
1002         READY = 4,
1003         FATAL_ERROR = 5
1004     };
1005
1006     /// This data structure holds data related to processing a message, such as
1007     /// the buffer it is being written to, its masking key, its UTF8 validation
1008     /// state, and sometimes its compression state.
1009     struct msg_metadata {
1010         msg_metadata() {}
1011         msg_metadata(message_ptr m, size_t p) : msg_ptr(m),prepared_key(p) {}
1012         msg_metadata(message_ptr m, frame::masking_key_type p)
1013           : msg_ptr(m)
1014           , prepared_key(prepare_masking_key(p)) {}
1015
1016         message_ptr msg_ptr;        // pointer to the message data buffer
1017         size_t      prepared_key;   // prepared masking key
1018         utf8_validator::validator validator; // utf8 validation state
1019     };
1020
1021     // Basic header of the frame being read
1022     frame::basic_header m_basic_header;
1023
1024     // Pointer to a manager that can create message buffers for us.
1025     msg_manager_ptr m_msg_manager;
1026
1027     // Number of bytes needed to complete the current operation
1028     size_t m_bytes_needed;
1029
1030     // Number of extended header bytes read
1031     size_t m_cursor;
1032
1033     // Metadata for the current data msg
1034     msg_metadata m_data_msg;
1035     // Metadata for the current control msg
1036     msg_metadata m_control_msg;
1037
1038     // Pointer to the metadata associated with the frame being read
1039     msg_metadata * m_current_msg;
1040
1041     // Extended header of current frame
1042     frame::extended_header m_extended_header;
1043
1044     rng_type & m_rng;
1045
1046     // Overall state of the processor
1047     state m_state;
1048
1049     // Extensions
1050     permessage_deflate_type m_permessage_deflate;
1051 };
1052
1053 } // namespace processor
1054 } // namespace websocketpp
1055
1056 #endif //WEBSOCKETPP_PROCESSOR_HYBI13_HPP