Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
processor.hpp
Go to the documentation of this file.
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_HPP
29#define WEBSOCKETPP_PROCESSOR_HPP
30
33
34#include <websocketpp/close.hpp>
36#include <websocketpp/uri.hpp>
37
38#include <sstream>
39#include <string>
40#include <utility>
41#include <vector>
42
43namespace websocketpp {
45
59namespace processor {
60
62
67template <typename request_type>
68bool is_websocket_handshake(request_type& r) {
70
71 std::string const & upgrade_header = r.get_header("Upgrade");
72
73 if (ci_find_substr(upgrade_header, constants::upgrade_token,
74 sizeof(constants::upgrade_token)-1) == upgrade_header.end())
75 {
76 return false;
77 }
78
79 std::string const & con_header = r.get_header("Connection");
80
81 if (ci_find_substr(con_header, constants::connection_token,
82 sizeof(constants::connection_token)-1) == con_header.end())
83 {
84 return false;
85 }
86
87 return true;
88}
89
91
106template <typename request_type>
107int get_websocket_version(request_type& r) {
108 if (!r.ready()) {
109 return -2;
110 }
111
112 if (r.get_header("Sec-WebSocket-Version").empty()) {
113 return 0;
114 }
115
116 int version;
117 std::istringstream ss(r.get_header("Sec-WebSocket-Version"));
118
119 if ((ss >> version).fail()) {
120 return -1;
121 }
122
123 return version;
124}
125
127
135template <typename request_type>
136uri_ptr get_uri_from_host(request_type & request, std::string scheme) {
137 std::string h = request.get_header("Host");
138
139 size_t last_colon = h.rfind(":");
140 size_t last_sbrace = h.rfind("]");
141
142 // no : = hostname with no port
143 // last : before ] = ipv6 literal with no port
144 // : with no ] = hostname with port
145 // : after ] = ipv6 literal with port
146 if (last_colon == std::string::npos ||
147 (last_sbrace != std::string::npos && last_sbrace > last_colon))
148 {
149 return lib::make_shared<uri>(scheme, h, request.get_uri());
150 } else {
151 return lib::make_shared<uri>(scheme,
152 h.substr(0,last_colon),
153 h.substr(last_colon+1),
154 request.get_uri());
155 }
156}
157
159template <typename config>
161public:
163 typedef typename config::request_type request_type;
164 typedef typename config::response_type response_type;
165 typedef typename config::message_type::ptr message_ptr;
166 typedef std::pair<lib::error_code,std::string> err_str_pair;
167
168 explicit processor(bool secure, bool p_is_server)
169 : m_secure(secure)
170 , m_server(p_is_server)
171 , m_max_message_size(config::max_message_size)
172 {}
173
174 virtual ~processor() {}
175
177 virtual int get_version() const = 0;
178
180
188 size_t get_max_message_size() const {
189 return m_max_message_size;
190 }
191
193
203 void set_max_message_size(size_t new_value) {
204 m_max_message_size = new_value;
205 }
206
208
212 virtual bool has_permessage_compress() const {
213 return false;
214 }
215
217
226 return err_str_pair();
227 }
228
230
240 return err_str_pair();
241 }
242
244
252 virtual lib::error_code validate_handshake(request_type const & request) const = 0;
253
255
264 virtual lib::error_code process_handshake(request_type const & req,
265 std::string const & subprotocol, response_type& res) const = 0;
266
268
273 virtual lib::error_code client_handshake_request(request_type & req,
274 uri_ptr uri, std::vector<std::string> const & subprotocols) const = 0;
275
277
283 const & req, response_type & res) const = 0;
284
286 virtual std::string get_raw(response_type const & request) const = 0;
287
289 virtual std::string const & get_origin(request_type const & request) const = 0;
290
292
300 virtual lib::error_code extract_subprotocols(const request_type & req,
301 std::vector<std::string> & subprotocol_list) = 0;
302
304 virtual uri_ptr get_uri(request_type const & request) const = 0;
305
307
316 virtual size_t consume(uint8_t *buf, size_t len, lib::error_code & ec) = 0;
317
319
327 virtual bool ready() const = 0;
328
330
342
344 virtual bool get_error() const = 0;
345
349 virtual size_t get_bytes_needed() const {
350 return 1;
351 }
352
354
358 virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out) = 0;
359
361
369 virtual lib::error_code prepare_ping(std::string const & in, message_ptr out) const
370 = 0;
371
373
381 virtual lib::error_code prepare_pong(std::string const & in, message_ptr out) const
382 = 0;
383
385
396 virtual lib::error_code prepare_close(close::status::value code,
397 std::string const & reason, message_ptr out) const = 0;
398protected:
399 bool const m_secure;
400 bool const m_server;
402};
403
404} // namespace processor
405} // namespace websocketpp
406
407#endif //WEBSOCKETPP_PROCESSOR_HPP
const mie::Vuint & r
Definition bn.cpp:28
WebSocket protocol processor abstract base class.
virtual lib::error_code prepare_data_frame(message_ptr in, message_ptr out)=0
Prepare a data message for writing.
virtual size_t get_bytes_needed() const
virtual size_t consume(uint8_t *buf, size_t len, lib::error_code &ec)=0
process new websocket connection bytes
virtual lib::error_code prepare_close(close::status::value code, std::string const &reason, message_ptr out) const =0
Prepare a close frame.
virtual err_str_pair negotiate_extensions(response_type const &)
Initializes extensions based on the Sec-WebSocket-Extensions header.
virtual int get_version() const =0
Get the protocol version of this processor.
virtual std::string get_raw(response_type const &request) const =0
Given a completed response, get the raw bytes to put on the wire.
virtual bool ready() const =0
Checks if there is a message ready.
virtual lib::error_code process_handshake(request_type const &req, std::string const &subprotocol, response_type &res) const =0
Calculate the appropriate response for this websocket request.
processor(bool secure, bool p_is_server)
config::request_type request_type
virtual lib::error_code validate_handshake(request_type const &request) const =0
validate a WebSocket handshake request for this version
virtual uri_ptr get_uri(request_type const &request) const =0
Extracts client uri from a handshake request.
config::message_type::ptr message_ptr
virtual err_str_pair negotiate_extensions(request_type const &)
Initializes extensions based on the Sec-WebSocket-Extensions header.
virtual bool has_permessage_compress() const
Returns whether or not the permessage_compress extension is implemented.
virtual lib::error_code prepare_ping(std::string const &in, message_ptr out) const =0
Prepare a ping frame.
virtual lib::error_code validate_server_handshake_response(request_type const &req, response_type &res) const =0
Validate the server's response to an outgoing handshake request.
virtual lib::error_code client_handshake_request(request_type &req, uri_ptr uri, std::vector< std::string > const &subprotocols) const =0
Fill in an HTTP request for an outgoing connection handshake.
virtual lib::error_code extract_subprotocols(const request_type &req, std::vector< std::string > &subprotocol_list)=0
Extracts requested subprotocols from a handshake request.
virtual bool get_error() const =0
Tests whether the processor is in a fatal error state.
config::response_type response_type
void set_max_message_size(size_t new_value)
Set maximum message size.
virtual std::string const & get_origin(request_type const &request) const =0
Return the value of the header containing the CORS origin.
size_t get_max_message_size() const
Get maximum message size.
std::pair< lib::error_code, std::string > err_str_pair
virtual message_ptr get_message()=0
Retrieves the most recently processed message.
virtual lib::error_code prepare_pong(std::string const &in, message_ptr out) const =0
Prepare a pong frame.
uint16_t value
The type of a close code value.
Definition close.hpp:49
int get_websocket_version(request_type &r)
Extract the version from a WebSocket handshake request.
uri_ptr get_uri_from_host(request_type &request, std::string scheme)
Extract a URI ptr from the host header of the request.
bool is_websocket_handshake(request_type &r)
Determine whether or not a generic HTTP request is a WebSocket handshake.
Definition processor.hpp:68
T::const_iterator ci_find_substr(T const &haystack, T const &needle, std::locale const &loc=std::locale())
Find substring (case insensitive)
Namespace for the WebSocket++ project.
Definition base64.hpp:41
lib::shared_ptr< uri > uri_ptr
Pointer to a URI.
Definition uri.hpp:351
unsigned char uint8_t
Definition stdint.h:124
size_t len
uint8_t buf[2048]