fixed adding file problem
[c11concurrency-benchmarks.git] / gdax-orderbook-hpp / demo / dependencies / websocketpp-0.7.0 / test / connection / connection.cpp
1 /*
2  * Copyright (c) 2011, 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 connection
29 #include <boost/test/unit_test.hpp>
30
31 #include "connection_tu2.hpp"
32
33 // Include special debugging transport
34 //#include <websocketpp/config/minimal_client.hpp>
35 #include <websocketpp/transport/debug/endpoint.hpp>
36
37 // NOTE: these tests currently test against hardcoded output values. I am not
38 // sure how problematic this will be. If issues arise like order of headers the
39 // output should be parsed by http::response and have values checked directly
40
41 BOOST_AUTO_TEST_CASE( basic_http_request ) {
42     std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
43     std::string output = "HTTP/1.1 426 Upgrade Required\r\nServer: " +
44                          std::string(websocketpp::user_agent)+"\r\n\r\n";
45
46     std::string o2 = run_server_test(input);
47
48     BOOST_CHECK(o2 == output);
49 }
50
51 struct connection_extension {
52     connection_extension() : extension_value(5) {}
53
54     int extension_method() {
55         return extension_value;
56     }
57
58     bool is_server() const {
59         return false;
60     }
61
62     int extension_value;
63 };
64
65 struct stub_config : public websocketpp::config::core {
66     typedef core::concurrency_type concurrency_type;
67
68     typedef core::request_type request_type;
69     typedef core::response_type response_type;
70
71     typedef core::message_type message_type;
72     typedef core::con_msg_manager_type con_msg_manager_type;
73     typedef core::endpoint_msg_manager_type endpoint_msg_manager_type;
74
75     typedef core::alog_type alog_type;
76     typedef core::elog_type elog_type;
77
78     typedef core::rng_type rng_type;
79
80     typedef core::transport_type transport_type;
81
82     typedef core::endpoint_base endpoint_base;
83     typedef connection_extension connection_base;
84 };
85
86 struct debug_config_client : public websocketpp::config::core {
87     typedef debug_config_client type;
88     
89     typedef core::concurrency_type concurrency_type;
90
91     typedef core::request_type request_type;
92     typedef core::response_type response_type;
93
94     typedef core::message_type message_type;
95     typedef core::con_msg_manager_type con_msg_manager_type;
96     typedef core::endpoint_msg_manager_type endpoint_msg_manager_type;
97
98     typedef core::alog_type alog_type;
99     typedef core::elog_type elog_type;
100
101     typedef websocketpp::random::none::int_generator<uint32_t> rng_type;
102
103     struct transport_config {
104         typedef type::concurrency_type concurrency_type;
105         typedef type::elog_type elog_type;
106         typedef type::alog_type alog_type;
107         typedef type::request_type request_type;
108         typedef type::response_type response_type;
109
110         /// Controls compile time enabling/disabling of thread syncronization
111         /// code Disabling can provide a minor performance improvement to single
112         /// threaded applications
113         static bool const enable_multithreading = true;
114
115         /// Default timer values (in ms)
116         static const long timeout_socket_pre_init = 5000;
117         static const long timeout_proxy = 5000;
118         static const long timeout_socket_post_init = 5000;
119         static const long timeout_connect = 5000;
120         static const long timeout_socket_shutdown = 5000;
121     };
122
123     /// Transport Endpoint Component
124     typedef websocketpp::transport::debug::endpoint<transport_config>
125         transport_type;
126
127     typedef core::endpoint_base endpoint_base;
128     typedef connection_extension connection_base;
129     
130     static const websocketpp::log::level elog_level = websocketpp::log::elevel::none;
131     static const websocketpp::log::level alog_level = websocketpp::log::alevel::none;
132 };
133
134 struct connection_setup {
135     connection_setup(bool p_is_server) : c(p_is_server, "", alog, elog, rng) {}
136
137     websocketpp::lib::error_code ec;
138     stub_config::alog_type alog;
139     stub_config::elog_type elog;
140     stub_config::rng_type rng;
141     websocketpp::connection<stub_config> c;
142 };
143
144 typedef websocketpp::client<debug_config_client> debug_client;
145 typedef websocketpp::server<debug_config_client> debug_server;
146
147 /*void echo_func(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
148     s->send(hdl, msg->get_payload(), msg->get_opcode());
149 }*/
150
151 void validate_func(server* s, websocketpp::connection_hdl hdl, message_ptr msg) {
152     s->send(hdl, msg->get_payload(), msg->get_opcode());
153 }
154
155 bool validate_set_ua(server* s, websocketpp::connection_hdl hdl) {
156     server::connection_ptr con = s->get_con_from_hdl(hdl);
157     con->replace_header("Server","foo");
158     return true;
159 }
160
161 void http_func(server* s, websocketpp::connection_hdl hdl) {
162     using namespace websocketpp::http;
163
164     server::connection_ptr con = s->get_con_from_hdl(hdl);
165
166     std::string res = con->get_resource();
167
168     con->set_body(res);
169     con->set_status(status_code::ok);
170
171     BOOST_CHECK_EQUAL(con->get_response_code(), status_code::ok);
172     BOOST_CHECK_EQUAL(con->get_response_msg(), status_code::get_string(status_code::ok));
173 }
174
175 void defer_http_func(server* s, bool * deferred, websocketpp::connection_hdl hdl) {
176     *deferred = true;
177     
178     server::connection_ptr con = s->get_con_from_hdl(hdl);
179     
180     websocketpp::lib::error_code ec = con->defer_http_response();
181     BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
182 }
183
184 void check_on_fail(server* s, websocketpp::lib::error_code ec, bool & called, 
185     websocketpp::connection_hdl hdl)
186 {
187     server::connection_ptr con = s->get_con_from_hdl(hdl);
188
189     BOOST_CHECK_EQUAL(ec, con->get_ec());
190     called = true;
191 }
192
193 void on_open_print(server* s, websocketpp::connection_hdl hdl)
194 {
195     server::connection_ptr con = s->get_con_from_hdl(hdl);
196
197     std::cout << con->get_uri() << std::endl;
198 }
199
200 void fail_on_open(websocketpp::connection_hdl) {
201     BOOST_CHECK(false);
202 }
203 void fail_on_http(websocketpp::connection_hdl) {
204     BOOST_CHECK(false);
205 }
206
207 BOOST_AUTO_TEST_CASE( connection_extensions ) {
208     connection_setup env(true);
209
210     BOOST_CHECK( env.c.extension_value == 5 );
211     BOOST_CHECK( env.c.extension_method() == 5 );
212
213     BOOST_CHECK( env.c.is_server() == true );
214 }
215
216 BOOST_AUTO_TEST_CASE( basic_websocket_request ) {
217     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";
218     std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: ";
219     output+=websocketpp::user_agent;
220     output+="\r\nUpgrade: websocket\r\n\r\n";
221
222     server s;
223     s.set_message_handler(bind(&echo_func,&s,::_1,::_2));
224
225     BOOST_CHECK(run_server_test(s,input) == output);
226 }
227
228 BOOST_AUTO_TEST_CASE( http_request ) {
229     std::string input = "GET /foo/bar HTTP/1.1\r\nHost: www.example.com\r\nOrigin: http://www.example.com\r\n\r\n";
230     std::string output = "HTTP/1.1 200 OK\r\nContent-Length: 8\r\nServer: ";
231     output+=websocketpp::user_agent;
232     output+="\r\n\r\n/foo/bar";
233
234     server s;
235     s.set_http_handler(bind(&http_func,&s,::_1));
236
237     BOOST_CHECK_EQUAL(run_server_test(s,input), output);
238 }
239
240 BOOST_AUTO_TEST_CASE( deferred_http_request ) {
241     std::string input = "GET /foo/bar HTTP/1.1\r\nHost: www.example.com\r\nOrigin: http://www.example.com\r\n\r\n";
242     std::string output = "HTTP/1.1 200 OK\r\nContent-Length: 8\r\nServer: ";
243     output+=websocketpp::user_agent;
244     output+="\r\n\r\n/foo/bar";
245
246     server s;
247     server::connection_ptr con;
248     bool deferred = false;
249     s.set_http_handler(bind(&defer_http_func,&s, &deferred,::_1));
250
251     s.clear_access_channels(websocketpp::log::alevel::all);
252     s.clear_error_channels(websocketpp::log::elevel::all);
253     
254     std::stringstream ostream;
255     s.register_ostream(&ostream);
256
257     con = s.get_connection();
258     con->start();
259     
260     BOOST_CHECK(!deferred);
261     BOOST_CHECK_EQUAL(ostream.str(), "");
262     con->read_some(input.data(),input.size());
263     BOOST_CHECK(deferred);
264     BOOST_CHECK_EQUAL(ostream.str(), "");
265
266     con->set_body(con->get_resource());
267     con->set_status(websocketpp::http::status_code::ok);
268     
269     websocketpp::lib::error_code ec;
270     s.send_http_response(con->get_handle(),ec);
271     BOOST_CHECK_EQUAL(ec, websocketpp::lib::error_code());
272     BOOST_CHECK_EQUAL(ostream.str(), output);
273     con->send_http_response(ec);
274     BOOST_CHECK_EQUAL(ec, make_error_code(websocketpp::error::invalid_state));
275     
276 }
277
278 BOOST_AUTO_TEST_CASE( request_no_server_header ) {
279     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";
280     std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nUpgrade: websocket\r\n\r\n";
281
282     server s;
283     s.set_user_agent("");
284     s.set_message_handler(bind(&echo_func,&s,::_1,::_2));
285
286     BOOST_CHECK_EQUAL(run_server_test(s,input), output);
287 }
288
289 BOOST_AUTO_TEST_CASE( request_no_server_header_override ) {
290     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";
291     std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: foo\r\nUpgrade: websocket\r\n\r\n";
292
293     server s;
294     s.set_user_agent("");
295     s.set_message_handler(bind(&echo_func,&s,::_1,::_2));
296     s.set_validate_handler(bind(&validate_set_ua,&s,::_1));
297
298     BOOST_CHECK_EQUAL(run_server_test(s,input), output);
299 }
300
301 BOOST_AUTO_TEST_CASE( basic_client_websocket ) {
302     std::string uri = "ws://localhost";
303
304     //std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: foo\r\nUpgrade: websocket\r\n\r\n";
305
306     std::string ref = "GET / HTTP/1.1\r\nConnection: Upgrade\r\nFoo: Bar\r\nHost: localhost\r\nSec-WebSocket-Key: AAAAAAAAAAAAAAAAAAAAAA==\r\nSec-WebSocket-Version: 13\r\nUpgrade: websocket\r\nUser-Agent: foo\r\n\r\n";
307
308     std::stringstream output;
309
310     client e;
311     e.set_access_channels(websocketpp::log::alevel::none);
312     e.set_error_channels(websocketpp::log::elevel::none);
313     e.set_user_agent("foo");
314     e.register_ostream(&output);
315
316     client::connection_ptr con;
317     websocketpp::lib::error_code ec;
318     con = e.get_connection(uri, ec);
319     con->append_header("Foo","Bar");
320     e.connect(con);
321
322     BOOST_CHECK_EQUAL(ref, output.str());
323 }
324
325 BOOST_AUTO_TEST_CASE( set_max_message_size ) {
326     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\n\r\n";
327     
328     // After the handshake, add a single frame with a message that is too long.
329     char frame0[10] = {char(0x82), char(0x83), 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01};
330     input.append(frame0, 10);
331     
332     std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: foo\r\nUpgrade: websocket\r\n\r\n";
333
334     // After the handshake, add a single frame with a close message with message too big
335     // error code.
336     char frame1[4] = {char(0x88), 0x19, 0x03, char(0xf1)};
337     output.append(frame1, 4);
338     output.append("A message was too large");
339
340     server s;
341     s.set_user_agent("");
342     s.set_validate_handler(bind(&validate_set_ua,&s,::_1));
343     s.set_max_message_size(2);
344
345     BOOST_CHECK_EQUAL(run_server_test(s,input), output);
346 }
347
348 BOOST_AUTO_TEST_CASE( websocket_fail_parse_error ) {
349     std::string input = "asdf\r\n\r\n";
350
351     server s;
352     websocketpp::lib::error_code ec = make_error_code(websocketpp::error::http_parse_error);
353     bool called = false;
354     s.set_fail_handler(bind(&check_on_fail,&s,ec,websocketpp::lib::ref(called),::_1));
355
356     run_server_test(s,input,false);
357     BOOST_CHECK(called);
358 }
359
360 BOOST_AUTO_TEST_CASE( websocket_fail_invalid_version ) {
361     std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: foo\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
362
363     server s;
364     websocketpp::lib::error_code ec = make_error_code(websocketpp::error::invalid_version);
365     bool called = false;
366     s.set_fail_handler(bind(&check_on_fail,&s,ec,websocketpp::lib::ref(called),::_1));
367
368     run_server_test(s,input,false);
369     BOOST_CHECK(called);
370 }
371
372 BOOST_AUTO_TEST_CASE( websocket_fail_unsupported_version ) {
373     std::string input = "GET / HTTP/1.1\r\nHost: www.example.com\r\nConnection: upgrade\r\nUpgrade: websocket\r\nSec-WebSocket-Version: 12\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nOrigin: http://www.example.com\r\n\r\n";
374
375     server s;
376     websocketpp::lib::error_code ec = make_error_code(websocketpp::error::unsupported_version);
377     bool called = false;
378     s.set_fail_handler(bind(&check_on_fail,&s,ec,websocketpp::lib::ref(called),::_1));
379
380     run_server_test(s,input,false);
381     BOOST_CHECK(called);
382 }
383
384 // BOOST_AUTO_TEST_CASE( websocket_fail_invalid_uri ) {
385 //     std::string input = "GET http://345.123.123.123/foo 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";
386
387 //     server s;
388 //     websocketpp::lib::error_code ec = make_error_code(websocketpp::error::unsupported_version);
389 //     bool called = false;
390 //     s.set_fail_handler(bind(&check_on_fail,&s,ec,websocketpp::lib::ref(called),::_1));
391 //     s.set_open_handler(bind(&on_open_print,&s,::_1));
392
393 //     std::cout << run_server_test(s,input,true) << std::endl;
394 //     BOOST_CHECK(called);
395 // }
396
397 // BOOST_AUTO_TEST_CASE( websocket_fail_invalid_uri_http ) {
398 //     std::string input = "GET http://345.123.123.123/foo HTTP/1.1\r\nHost: www.example.com\r\nOrigin: http://www.example.com\r\n\r\n";
399
400 //     server s;
401 //     websocketpp::lib::error_code ec = make_error_code(websocketpp::error::unsupported_version);
402 //     bool called = false;
403 //     s.set_fail_handler(bind(&check_on_fail,&s,ec,websocketpp::lib::ref(called),::_1));
404 //     s.set_open_handler(bind(&on_open_print,&s,::_1));
405
406 //     std::cout << run_server_test(s,input,true) << std::endl;
407 //     BOOST_CHECK(called);
408 // }
409
410 BOOST_AUTO_TEST_CASE( websocket_fail_upgrade_required ) {
411     std::string input = "GET /foo/bar HTTP/1.1\r\nHost: www.example.com\r\nOrigin: http://www.example.com\r\n\r\n";
412
413     server s;
414     websocketpp::lib::error_code ec = make_error_code(websocketpp::error::upgrade_required);
415     bool called = false;
416     s.set_fail_handler(bind(&check_on_fail,&s,ec,websocketpp::lib::ref(called),::_1));
417
418     run_server_test(s,input,false);
419     BOOST_CHECK(called);
420 }
421
422 // TODO: set max message size in client endpoint test case
423 // TODO: set max message size mid connection test case
424 // TODO: [maybe] set max message size in open handler
425
426
427
428 // BOOST_AUTO_TEST_CASE( user_reject_origin ) {
429 //     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";
430 //     std::string output = "HTTP/1.1 403 Forbidden\r\nServer: "+websocketpp::USER_AGENT+"\r\n\r\n";
431
432 //     BOOST_CHECK(run_server_test(input) == output);
433 // }
434
435 // BOOST_AUTO_TEST_CASE( basic_text_message ) {
436 //     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";
437
438 //     unsigned char frames[8] = {0x82,0x82,0xFF,0xFF,0xFF,0xFF,0xD5,0xD5};
439 //     input.append(reinterpret_cast<char*>(frames),8);
440
441 //     std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\nServer: "+websocketpp::USER_AGENT+"\r\nUpgrade: websocket\r\n\r\n**";
442
443 //     BOOST_CHECK( run_server_test(input) == output);
444 // }
445
446
447
448
449
450
451 BOOST_AUTO_TEST_CASE( client_handshake_timeout_race1 ) {
452     debug_client c;
453
454     websocketpp::lib::error_code ec;
455     debug_client::connection_ptr con = c.get_connection("ws://localhost:9002", ec);
456
457     BOOST_CHECK(!ec);
458
459     // This test the case where a handshake times out immediately before the 
460     // handler that would have completed it gets invoked. This situation happens
461     // when clients are connecting to overloaded servers and on servers that are
462     // overloaded. 
463     c.connect(con);
464     
465     con->expire_timer(websocketpp::lib::error_code());
466     // Fullfil the write to simulate the write completing immediately after
467     // timer expires
468     con->fullfil_write();
469     
470     BOOST_CHECK_EQUAL(con->get_ec(), make_error_code(websocketpp::error::open_handshake_timeout));
471 }
472
473 BOOST_AUTO_TEST_CASE( client_handshake_timeout_race2 ) {
474     debug_client c;
475
476     websocketpp::lib::error_code ec;
477     debug_client::connection_ptr con = c.get_connection("ws://localhost:9002", ec);
478
479     BOOST_CHECK(!ec);
480
481     std::string output = "HTTP/1.1 101 Switching Protocols\r\nConnection: upgrade\r\nSec-WebSocket-Accept: ICX+Yqv66kxgM0FcWaLWlFLwTAI=\r\nServer: foo\r\nUpgrade: websocket\r\n\r\n";
482
483     // This test the case where a handshake times out immediately before the 
484     // handler that would have completed it gets invoked. This situation happens
485     // when clients are connecting to overloaded servers and on servers that are
486     // overloaded. 
487     c.connect(con);
488     con->fullfil_write();
489     
490     con->expire_timer(websocketpp::lib::error_code());
491     // Read valid handshake to simulate receiving the handshake response
492     // immediately after the timer expires
493     con->read_all(output.data(),output.size());
494     
495     BOOST_CHECK_EQUAL(con->get_ec(), make_error_code(websocketpp::error::open_handshake_timeout));
496 }
497
498 BOOST_AUTO_TEST_CASE( server_handshake_timeout_race1 ) {
499     debug_server s;
500
501     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: AAAAAAAAAAAAAAAAAAAAAA==\r\n\r\n";
502
503     debug_server::connection_ptr con = s.get_connection();
504     con->start();
505     
506     con->expire_timer(websocketpp::lib::error_code());
507     // Read handshake immediately after timer expire
508     con->read_all(input.data(), input.size());
509     
510     BOOST_CHECK_EQUAL(con->get_ec(), make_error_code(websocketpp::error::open_handshake_timeout));
511 }
512
513 BOOST_AUTO_TEST_CASE( server_handshake_timeout_race2 ) {
514     debug_server s;
515
516     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: AAAAAAAAAAAAAAAAAAAAAA==\r\n\r\n";
517
518     debug_server::connection_ptr con = s.get_connection();
519     con->start();
520     
521     con->read_all(input.data(), input.size());
522     
523     con->expire_timer(websocketpp::lib::error_code());
524     // Complete write immediately after timer expire
525     con->fullfil_write();
526     
527     BOOST_CHECK_EQUAL(con->get_ec(), make_error_code(websocketpp::error::open_handshake_timeout));
528 }
529
530