Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
server.cpp
Go to the documentation of this file.
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//#define BOOST_TEST_DYN_LINK
28#define BOOST_TEST_MODULE server
29#include <boost/test/unit_test.hpp>
30
31#include <iostream>
32
33// Test Environment:
34// server, no TLS, no locks, iostream based transport
37
40
41using websocketpp::lib::placeholders::_1;
42using websocketpp::lib::placeholders::_2;
43using websocketpp::lib::bind;
44
45/*struct stub_config : public websocketpp::config::core {
46 typedef core::concurrency_type concurrency_type;
47
48 typedef core::request_type request_type;
49 typedef core::response_type response_type;
50
51 typedef core::message_type message_type;
52 typedef core::con_msg_manager_type con_msg_manager_type;
53 typedef core::endpoint_msg_manager_type endpoint_msg_manager_type;
54
55 typedef core::alog_type alog_type;
56 typedef core::elog_type elog_type;
57
58 typedef core::rng_type rng_type;
59
60 typedef core::transport_type transport_type;
61
62 typedef core::endpoint_base endpoint_base;
63};*/
64
65/* Run server and return output test rig */
66std::string run_server_test(server& s, std::string input) {
68 std::stringstream output;
69
70 s.register_ostream(&output);
71 s.clear_access_channels(websocketpp::log::alevel::all);
72 s.clear_error_channels(websocketpp::log::elevel::all);
73
74 con = s.get_connection();
75 con->start();
76
77 std::stringstream channel;
78
79 channel << input;
80 channel >> *con;
81
82 return output.str();
83}
84
85/* handler library*/
87 s->send(hdl, msg->get_payload(), msg->get_opcode());
88}
89
90bool validate_func_subprotocol(server* s, std::string* out, std::string accept,
92{
93 server::connection_ptr con = s->get_con_from_hdl(hdl);
94
95 std::stringstream o;
96
97 const std::vector<std::string> & protocols = con->get_requested_subprotocols();
98 std::vector<std::string>::const_iterator it;
99
100 for (it = protocols.begin(); it != protocols.end(); ++it) {
101 o << *it << ",";
102 }
103
104 *out = o.str();
105
106 if (!accept.empty()) {
107 con->select_subprotocol(accept);
108 }
109
110 return true;
111}
112
114 server::connection_ptr con = s->get_con_from_hdl(hdl);
115
116 *out = con->get_subprotocol();
117}
118
119/* Tests */
120BOOST_AUTO_TEST_CASE( basic_websocket_request ) {
121 std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
122 std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: test\r\nUpgrade: websocket\r\n\r\n";
123
124 server s;
125 s.set_user_agent("test");
126
127 BOOST_CHECK_EQUAL(run_server_test(s,input), output);
128}
129
130BOOST_AUTO_TEST_CASE( invalid_websocket_version ) {
131 std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: a\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
132 std::string output = "HTTP/1.1 400 Bad Request\r\nServer: test\r\n\r\n";
133
134 server s;
135 s.set_user_agent("test");
136 //s.set_message_handler(bind(&echo_func,&s,::_1,::_2));
137
138 BOOST_CHECK_EQUAL(run_server_test(s,input), output);
139}
140
141BOOST_AUTO_TEST_CASE( unimplemented_websocket_version ) {
142 std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 14\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
143
144 std::string output = "HTTP/1.1 400 Bad Request\r\nSec-WebSocket-Version: 0,7,8,13\r\nServer: test\r\n\r\n";
145
146 server s;
147 s.set_user_agent("test");
148
149 BOOST_CHECK_EQUAL(run_server_test(s,input), output);
150}
151
152BOOST_AUTO_TEST_CASE( list_subprotocol_empty ) {
153 std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\nSec-WebSocket-Protocol: foo\r\n\r\n";
154
155 std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: test\r\nUpgrade: websocket\r\n\r\n";
156
157 std::string subprotocol;
158
159 server s;
160 s.set_user_agent("test");
161 s.set_open_handler(bind(&open_func_subprotocol,&s,&subprotocol,::_1));
162
163 BOOST_CHECK_EQUAL(run_server_test(s,input), output);
164 BOOST_CHECK_EQUAL(subprotocol, "");
165}
166
167BOOST_AUTO_TEST_CASE( list_subprotocol_one ) {
168 std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\nSec-WebSocket-Protocol: foo\r\n\r\n";
169
170 std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: test\r\nUpgrade: websocket\r\n\r\n";
171
172 std::string validate;
173 std::string open;
174
175 server s;
176 s.set_user_agent("test");
177 s.set_validate_handler(bind(&validate_func_subprotocol,&s,&validate,"",::_1));
178 s.set_open_handler(bind(&open_func_subprotocol,&s,&open,::_1));
179
180 BOOST_CHECK_EQUAL(run_server_test(s,input), output);
181 BOOST_CHECK_EQUAL(validate, "foo,");
182 BOOST_CHECK_EQUAL(open, "");
183}
184
185BOOST_AUTO_TEST_CASE( accept_subprotocol_one ) {
186 std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\nSec-WebSocket-Protocol: foo\r\n\r\n";
187
188 std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nSec-WebSocket-Protocol: foo\r\nServer: test\r\nUpgrade: websocket\r\n\r\n";
189
190 std::string validate;
191 std::string open;
192
193 server s;
194 s.set_user_agent("test");
195 s.set_validate_handler(bind(&validate_func_subprotocol,&s,&validate,"foo",::_1));
196 s.set_open_handler(bind(&open_func_subprotocol,&s,&open,::_1));
197
198 BOOST_CHECK_EQUAL(run_server_test(s,input), output);
199 BOOST_CHECK_EQUAL(validate, "foo,");
200 BOOST_CHECK_EQUAL(open, "foo");
201}
202
203BOOST_AUTO_TEST_CASE( accept_subprotocol_invalid ) {
204 std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\nSec-WebSocket-Protocol: foo\r\n\r\n";
205
206 std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nSec-WebSocket-Protocol: foo\r\nServer: test\r\nUpgrade: websocket\r\n\r\n";
207
208 std::string validate;
209 std::string open;
210
211 server s;
212 s.set_user_agent("test");
213 s.set_validate_handler(bind(&validate_func_subprotocol,&s,&validate,"foo2",::_1));
214 s.set_open_handler(bind(&open_func_subprotocol,&s,&open,::_1));
215
216 std::string o;
217
218 BOOST_CHECK_THROW(o = run_server_test(s,input), websocketpp::exception);
219}
220
221BOOST_AUTO_TEST_CASE( accept_subprotocol_two ) {
222 std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\nSec-WebSocket-Protocol: foo, bar\r\n\r\n";
223
224 std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nSec-WebSocket-Protocol: bar\r\nServer: test\r\nUpgrade: websocket\r\n\r\n";
225
226 std::string validate;
227 std::string open;
228
229 server s;
230 s.set_user_agent("test");
231 s.set_validate_handler(bind(&validate_func_subprotocol,&s,&validate,"bar",::_1));
232 s.set_open_handler(bind(&open_func_subprotocol,&s,&open,::_1));
233
234 BOOST_CHECK_EQUAL(run_server_test(s,input), output);
235 BOOST_CHECK_EQUAL(validate, "foo,bar,");
236 BOOST_CHECK_EQUAL(open, "bar");
237}
238
239/*BOOST_AUTO_TEST_CASE( user_reject_origin ) {
240 std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example2.com\r\n\r\n";
241 std::string output = "HTTP/1.1 403 Forbidden\r\nServer: test\r\n\r\n";
242
243 server s;
244 s.set_user_agent("test");
245
246 BOOST_CHECK(run_server_test(s,input) == output);
247}*/
void set_user_agent(std::string const &ua)
Sets the user agent string that this endpoint will use.
Definition endpoint.hpp:196
lib::shared_ptr< message > ptr
Definition message.hpp:86
Server endpoint role based on the given config.
websocketpp::config::asio_tls_client::message_type::ptr message_ptr
bool validate(server *, websocketpp::connection_hdl)
lib::weak_ptr< void > connection_hdl
A handle to uniquely identify a connection.
bool validate_func_subprotocol(server *s, std::string *out, std::string accept, websocketpp::connection_hdl hdl)
Definition server.cpp:90
BOOST_AUTO_TEST_CASE(basic_websocket_request)
Definition server.cpp:120
websocketpp::server< websocketpp::config::core > server
Definition server.cpp:38
void echo_func(server *s, websocketpp::connection_hdl hdl, message_ptr msg)
Definition server.cpp:86
std::string run_server_test(server &s, std::string input)
Definition server.cpp:66
void open_func_subprotocol(server *s, std::string *out, websocketpp::connection_hdl hdl)
Definition server.cpp:113
static level const all
Special aggregate value representing "all levels".
Definition levels.hpp:152
static level const all
Special aggregate value representing "all levels".
Definition levels.hpp:80
char * s