| 1 | // |
| 2 | // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com) |
| 3 | // |
| 4 | // Distributed under the Boost Software License, Version 1.0. (See accompanying |
| 5 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| 6 | // |
| 7 | // Official repository: https://github.com/boostorg/beast |
| 8 | // |
| 9 | |
| 10 | // Test that header file is self-contained. |
| 11 | #include <boost/beast/websocket/stream.hpp> |
| 12 | |
| 13 | #include "test.hpp" |
| 14 | |
| 15 | #include <boost/asio/buffer.hpp> |
| 16 | #include <boost/asio/io_context.hpp> |
| 17 | #include <boost/asio/strand.hpp> |
| 18 | #include <boost/asio/write.hpp> |
| 19 | |
| 20 | namespace boost { |
| 21 | namespace beast { |
| 22 | namespace websocket { |
| 23 | |
| 24 | class read3_test : public websocket_test_suite |
| 25 | { |
| 26 | public: |
| 27 | void |
| 28 | testSuspend() |
| 29 | { |
| 30 | // suspend on read block |
| 31 | doFailLoop(f: [&](test::fail_count& fc) |
| 32 | { |
| 33 | echo_server es{log}; |
| 34 | net::io_context ioc; |
| 35 | stream<test::stream> ws{ioc, fc}; |
| 36 | ws.next_layer().connect(remote&: es.stream()); |
| 37 | ws.handshake(host: "localhost" , target: "/" ); |
| 38 | std::size_t count = 0; |
| 39 | ws.async_close(cr: {}, |
| 40 | handler: [&](error_code ec) |
| 41 | { |
| 42 | if(ec) |
| 43 | BOOST_THROW_EXCEPTION( |
| 44 | system_error{ec}); |
| 45 | BEAST_EXPECT(++count == 1); |
| 46 | }); |
| 47 | while(! ws.impl_->rd_block.is_locked()) |
| 48 | ioc.run_one(); |
| 49 | multi_buffer b; |
| 50 | ws.async_read(buffer&: b, |
| 51 | handler: [&](error_code ec, std::size_t) |
| 52 | { |
| 53 | if(ec != net::error::operation_aborted) |
| 54 | BOOST_THROW_EXCEPTION( |
| 55 | system_error{ec}); |
| 56 | BEAST_EXPECT(++count == 2); |
| 57 | }); |
| 58 | ioc.run(); |
| 59 | BEAST_EXPECT(count == 2); |
| 60 | }); |
| 61 | |
| 62 | // suspend on release read block |
| 63 | doFailLoop(f: [&](test::fail_count& fc) |
| 64 | { |
| 65 | echo_server es{log}; |
| 66 | net::io_context ioc; |
| 67 | stream<test::stream> ws{ioc, fc}; |
| 68 | ws.next_layer().connect(remote&: es.stream()); |
| 69 | ws.handshake(host: "localhost" , target: "/" ); |
| 70 | std::size_t count = 0; |
| 71 | multi_buffer b; |
| 72 | ws.async_read(buffer&: b, |
| 73 | handler: [&](error_code ec, std::size_t) |
| 74 | { |
| 75 | if(ec != net::error::operation_aborted) |
| 76 | BOOST_THROW_EXCEPTION( |
| 77 | system_error{ec}); |
| 78 | BEAST_EXPECT(++count == 2); |
| 79 | }); |
| 80 | BOOST_ASSERT(ws.impl_->rd_block.is_locked()); |
| 81 | ws.async_close(cr: {}, |
| 82 | handler: [&](error_code ec) |
| 83 | { |
| 84 | if(ec) |
| 85 | BOOST_THROW_EXCEPTION( |
| 86 | system_error{ec}); |
| 87 | BEAST_EXPECT(++count == 1); |
| 88 | }); |
| 89 | ioc.run(); |
| 90 | BEAST_EXPECT(count == 2); |
| 91 | }); |
| 92 | |
| 93 | // suspend on write pong |
| 94 | doFailLoop(f: [&](test::fail_count& fc) |
| 95 | { |
| 96 | echo_server es{log}; |
| 97 | net::io_context ioc; |
| 98 | stream<test::stream> ws{ioc, fc}; |
| 99 | ws.next_layer().connect(remote&: es.stream()); |
| 100 | ws.handshake(host: "localhost" , target: "/" ); |
| 101 | // insert a ping |
| 102 | ws.next_layer().append(s: string_view( |
| 103 | "\x89\x00" , 2)); |
| 104 | std::size_t count = 0; |
| 105 | std::string const s = "Hello, world" ; |
| 106 | multi_buffer b; |
| 107 | ws.async_read(buffer&: b, |
| 108 | handler: [&](error_code ec, std::size_t) |
| 109 | { |
| 110 | if(ec) |
| 111 | BOOST_THROW_EXCEPTION( |
| 112 | system_error{ec}); |
| 113 | BEAST_EXPECT(buffers_to_string(b.data()) == s); |
| 114 | ++count; |
| 115 | }); |
| 116 | BEAST_EXPECT(ws.impl_->rd_block.is_locked()); |
| 117 | ws.async_write(bs: net::buffer(data: s), |
| 118 | handler: [&](error_code ec, std::size_t n) |
| 119 | { |
| 120 | if(ec) |
| 121 | BOOST_THROW_EXCEPTION( |
| 122 | system_error{ec}); |
| 123 | BEAST_EXPECT(n == s.size()); |
| 124 | ++count; |
| 125 | }); |
| 126 | BEAST_EXPECT(ws.impl_->wr_block.is_locked()); |
| 127 | ioc.run(); |
| 128 | BEAST_EXPECT(count == 2); |
| 129 | }); |
| 130 | |
| 131 | // Ignore ping when closing |
| 132 | doFailLoop(f: [&](test::fail_count& fc) |
| 133 | { |
| 134 | echo_server es{log}; |
| 135 | net::io_context ioc; |
| 136 | stream<test::stream> ws{ioc, fc}; |
| 137 | ws.next_layer().connect(remote&: es.stream()); |
| 138 | ws.handshake(host: "localhost" , target: "/" ); |
| 139 | std::size_t count = 0; |
| 140 | // insert fragmented message with |
| 141 | // a ping in between the frames. |
| 142 | ws.next_layer().append(s: string_view( |
| 143 | "\x01\x01*" |
| 144 | "\x89\x00" |
| 145 | "\x80\x01*" , 8)); |
| 146 | multi_buffer b; |
| 147 | ws.async_read(buffer&: b, |
| 148 | handler: [&](error_code ec, std::size_t) |
| 149 | { |
| 150 | if(ec) |
| 151 | BOOST_THROW_EXCEPTION( |
| 152 | system_error{ec}); |
| 153 | BEAST_EXPECT(buffers_to_string(b.data()) == "**" ); |
| 154 | BEAST_EXPECT(++count == 1); |
| 155 | b.consume(n: b.size()); |
| 156 | ws.async_read(buffer&: b, |
| 157 | handler: [&](error_code ec, std::size_t) |
| 158 | { |
| 159 | if(ec != net::error::operation_aborted) |
| 160 | BOOST_THROW_EXCEPTION( |
| 161 | system_error{ec}); |
| 162 | BEAST_EXPECT(++count == 3); |
| 163 | }); |
| 164 | }); |
| 165 | BEAST_EXPECT(ws.impl_->rd_block.is_locked()); |
| 166 | ws.async_close(cr: {}, |
| 167 | handler: [&](error_code ec) |
| 168 | { |
| 169 | if(ec) |
| 170 | BOOST_THROW_EXCEPTION( |
| 171 | system_error{ec}); |
| 172 | BEAST_EXPECT(++count == 2); |
| 173 | }); |
| 174 | BEAST_EXPECT(ws.impl_->wr_block.is_locked()); |
| 175 | ioc.run(); |
| 176 | BEAST_EXPECT(count == 3); |
| 177 | }); |
| 178 | |
| 179 | // See if we are already closing |
| 180 | doFailLoop(f: [&](test::fail_count& fc) |
| 181 | { |
| 182 | echo_server es{log}; |
| 183 | net::io_context ioc; |
| 184 | stream<test::stream> ws{ioc, fc}; |
| 185 | ws.next_layer().connect(remote&: es.stream()); |
| 186 | ws.handshake(host: "localhost" , target: "/" ); |
| 187 | std::size_t count = 0; |
| 188 | // insert fragmented message with |
| 189 | // a close in between the frames. |
| 190 | ws.next_layer().append(s: string_view( |
| 191 | "\x01\x01*" |
| 192 | "\x88\x00" |
| 193 | "\x80\x01*" , 8)); |
| 194 | multi_buffer b; |
| 195 | ws.async_read(buffer&: b, |
| 196 | handler: [&](error_code ec, std::size_t) |
| 197 | { |
| 198 | if(ec != net::error::operation_aborted) |
| 199 | BOOST_THROW_EXCEPTION( |
| 200 | system_error{ec}); |
| 201 | BEAST_EXPECT(++count == 2); |
| 202 | }); |
| 203 | BEAST_EXPECT(ws.impl_->rd_block.is_locked()); |
| 204 | ws.async_close(cr: {}, |
| 205 | handler: [&](error_code ec) |
| 206 | { |
| 207 | if(ec) |
| 208 | BOOST_THROW_EXCEPTION( |
| 209 | system_error{ec}); |
| 210 | BEAST_EXPECT(++count == 1); |
| 211 | }); |
| 212 | BEAST_EXPECT(ws.impl_->wr_block.is_locked()); |
| 213 | ioc.run(); |
| 214 | BEAST_EXPECT(count == 2); |
| 215 | }); |
| 216 | } |
| 217 | |
| 218 | void |
| 219 | testParseFrame() |
| 220 | { |
| 221 | auto const bad = |
| 222 | [&](string_view s) |
| 223 | { |
| 224 | echo_server es{log}; |
| 225 | net::io_context ioc; |
| 226 | stream<test::stream> ws{ioc}; |
| 227 | ws.next_layer().connect(remote&: es.stream()); |
| 228 | ws.handshake(host: "localhost" , target: "/" ); |
| 229 | ws.next_layer().append(s); |
| 230 | error_code ec; |
| 231 | multi_buffer b; |
| 232 | ws.read(buffer&: b, ec); |
| 233 | BEAST_EXPECT(ec); |
| 234 | }; |
| 235 | |
| 236 | // chopped frame header |
| 237 | { |
| 238 | echo_server es{log}; |
| 239 | net::io_context ioc; |
| 240 | stream<test::stream> ws{ioc}; |
| 241 | ws.next_layer().connect(remote&: es.stream()); |
| 242 | ws.handshake(host: "localhost" , target: "/" ); |
| 243 | ws.next_layer().append( |
| 244 | s: "\x81\x7e\x01" ); |
| 245 | std::size_t count = 0; |
| 246 | std::string const s(257, '*'); |
| 247 | multi_buffer b; |
| 248 | ws.async_read(buffer&: b, |
| 249 | handler: [&](error_code ec, std::size_t) |
| 250 | { |
| 251 | ++count; |
| 252 | BEAST_EXPECTS(! ec, ec.message()); |
| 253 | BEAST_EXPECT(buffers_to_string(b.data()) == s); |
| 254 | }); |
| 255 | ioc.run_one(); |
| 256 | es.stream().write_some( |
| 257 | buffers: net::buffer(data: "\x01" + s)); |
| 258 | ioc.run(); |
| 259 | BEAST_EXPECT(count == 1); |
| 260 | } |
| 261 | |
| 262 | // new data frame when continuation expected |
| 263 | bad("\x01\x01*" "\x81\x01*" ); |
| 264 | |
| 265 | // reserved bits not cleared |
| 266 | bad("\xb1\x01*" ); |
| 267 | bad("\xc1\x01*" ); |
| 268 | bad("\xd1\x01*" ); |
| 269 | |
| 270 | // continuation without an active message |
| 271 | bad("\x80\x01*" ); |
| 272 | |
| 273 | // reserved bits not cleared (cont) |
| 274 | bad("\x01\x01*" "\xb0\x01*" ); |
| 275 | bad("\x01\x01*" "\xc0\x01*" ); |
| 276 | bad("\x01\x01*" "\xd0\x01*" ); |
| 277 | |
| 278 | // reserved opcode |
| 279 | bad("\x83\x01*" ); |
| 280 | |
| 281 | // fragmented control message |
| 282 | bad("\x09\x01*" ); |
| 283 | |
| 284 | // invalid length for control message |
| 285 | bad("\x89\x7e\x01\x01" ); |
| 286 | |
| 287 | // reserved bits not cleared (control) |
| 288 | bad("\xb9\x01*" ); |
| 289 | bad("\xc9\x01*" ); |
| 290 | bad("\xd9\x01*" ); |
| 291 | |
| 292 | // unmasked frame from client |
| 293 | { |
| 294 | echo_server es{log, kind::async_client}; |
| 295 | net::io_context ioc; |
| 296 | stream<test::stream> ws{ioc}; |
| 297 | ws.next_layer().connect(remote&: es.stream()); |
| 298 | es.async_handshake(); |
| 299 | ws.accept(); |
| 300 | ws.next_layer().append( |
| 301 | s: "\x81\x01*" ); |
| 302 | error_code ec; |
| 303 | multi_buffer b; |
| 304 | ws.read(buffer&: b, ec); |
| 305 | BEAST_EXPECT(ec); |
| 306 | } |
| 307 | |
| 308 | // masked frame from server |
| 309 | bad("\x81\x80\xff\xff\xff\xff" ); |
| 310 | |
| 311 | // chopped control frame payload |
| 312 | { |
| 313 | echo_server es{log}; |
| 314 | net::io_context ioc; |
| 315 | stream<test::stream> ws{ioc}; |
| 316 | ws.next_layer().connect(remote&: es.stream()); |
| 317 | ws.handshake(host: "localhost" , target: "/" ); |
| 318 | ws.next_layer().append( |
| 319 | s: "\x89\x02*" ); |
| 320 | std::size_t count = 0; |
| 321 | multi_buffer b; |
| 322 | ws.async_read(buffer&: b, |
| 323 | handler: [&](error_code ec, std::size_t) |
| 324 | { |
| 325 | ++count; |
| 326 | BEAST_EXPECTS(! ec, ec.message()); |
| 327 | BEAST_EXPECT(buffers_to_string(b.data()) == "**" ); |
| 328 | }); |
| 329 | ioc.run_one(); |
| 330 | es.stream().write_some( |
| 331 | buffers: net::buffer( |
| 332 | data: "*" "\x81\x02**" )); |
| 333 | ioc.run(); |
| 334 | BEAST_EXPECT(count == 1); |
| 335 | } |
| 336 | |
| 337 | // length not canonical |
| 338 | bad(string_view("\x81\x7e\x00\x7d" , 4)); |
| 339 | bad(string_view("\x81\x7f\x00\x00\x00\x00\x00\x00\xff\xff" , 10)); |
| 340 | } |
| 341 | |
| 342 | void |
| 343 | testIssue802() |
| 344 | { |
| 345 | for(std::size_t i = 0; i < 100; ++i) |
| 346 | { |
| 347 | echo_server es{log, kind::async}; |
| 348 | net::io_context ioc; |
| 349 | stream<test::stream> ws{ioc}; |
| 350 | ws.next_layer().connect(remote&: es.stream()); |
| 351 | ws.handshake(host: "localhost" , target: "/" ); |
| 352 | // too-big message frame indicates payload of 2^64-1 |
| 353 | net::write(s&: ws.next_layer(), buffers: sbuf( |
| 354 | s: "\x81\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" )); |
| 355 | multi_buffer b; |
| 356 | error_code ec; |
| 357 | ws.read(buffer&: b, ec); |
| 358 | BEAST_EXPECT(ec == error::closed); |
| 359 | BEAST_EXPECT(ws.reason().code == 1009); |
| 360 | } |
| 361 | } |
| 362 | |
| 363 | void |
| 364 | testIssue807() |
| 365 | { |
| 366 | echo_server es{log}; |
| 367 | net::io_context ioc; |
| 368 | stream<test::stream> ws{ioc}; |
| 369 | ws.next_layer().connect(remote&: es.stream()); |
| 370 | ws.handshake(host: "localhost" , target: "/" ); |
| 371 | ws.write(buffers: sbuf(s: "Hello, world!" )); |
| 372 | char buf[4]; |
| 373 | net::mutable_buffer b{buf, 0}; |
| 374 | auto const n = ws.read_some(buffers: b); |
| 375 | BEAST_EXPECT(n == 0); |
| 376 | } |
| 377 | |
| 378 | /* |
| 379 | When the internal read buffer contains a control frame and |
| 380 | stream::async_read_some is called, it is possible for the control |
| 381 | callback to be invoked on the caller's stack instead of through |
| 382 | the executor associated with the final completion handler. |
| 383 | */ |
| 384 | void |
| 385 | testIssue954() |
| 386 | { |
| 387 | echo_server es{log}; |
| 388 | multi_buffer b; |
| 389 | net::io_context ioc; |
| 390 | stream<test::stream> ws{ioc}; |
| 391 | ws.next_layer().connect(remote&: es.stream()); |
| 392 | ws.handshake(host: "localhost" , target: "/" ); |
| 393 | // message followed by ping |
| 394 | ws.next_layer().append(s: { |
| 395 | "\x81\x00" |
| 396 | "\x89\x00" , |
| 397 | 4}); |
| 398 | bool called_cb = false; |
| 399 | bool called_handler = false; |
| 400 | ws.control_callback( |
| 401 | cb: [&called_cb](frame_type, string_view) |
| 402 | { |
| 403 | called_cb = true; |
| 404 | }); |
| 405 | ws.async_read(buffer&: b, |
| 406 | handler: [&](error_code, std::size_t) |
| 407 | { |
| 408 | called_handler = true; |
| 409 | }); |
| 410 | BEAST_EXPECT(! called_cb); |
| 411 | BEAST_EXPECT(! called_handler); |
| 412 | ioc.run(); |
| 413 | BEAST_EXPECT(! called_cb); |
| 414 | BEAST_EXPECT(called_handler); |
| 415 | ws.async_read(buffer&: b, |
| 416 | handler: [&](error_code, std::size_t) |
| 417 | { |
| 418 | }); |
| 419 | BEAST_EXPECT(! called_cb); |
| 420 | } |
| 421 | |
| 422 | /* Bishop Fox Hybrid Assessment issue 1 |
| 423 | |
| 424 | Happens with permessage-deflate enabled and a |
| 425 | compressed frame with the FIN bit set ends with an |
| 426 | invalid prefix. |
| 427 | */ |
| 428 | void |
| 429 | testIssueBF1() |
| 430 | { |
| 431 | permessage_deflate pmd; |
| 432 | pmd.client_enable = true; |
| 433 | pmd.server_enable = true; |
| 434 | |
| 435 | // read |
| 436 | #if 0 |
| 437 | { |
| 438 | echo_server es{log}; |
| 439 | net::io_context ioc; |
| 440 | stream<test::stream> ws{ioc}; |
| 441 | ws.set_option(pmd); |
| 442 | ws.next_layer().connect(es.stream()); |
| 443 | ws.handshake("localhost" , "/" ); |
| 444 | // invalid 1-byte deflate block in frame |
| 445 | net::write(ws.next_layer(), sbuf( |
| 446 | "\xc1\x81\x3a\xa1\x74\x3b\x49" )); |
| 447 | } |
| 448 | #endif |
| 449 | { |
| 450 | net::io_context ioc; |
| 451 | stream<test::stream> wsc{ioc}; |
| 452 | stream<test::stream> wss{ioc}; |
| 453 | wsc.set_option(pmd); |
| 454 | wss.set_option(pmd); |
| 455 | wsc.next_layer().connect(remote&: wss.next_layer()); |
| 456 | wsc.async_handshake( |
| 457 | host: "localhost" , target: "/" , handler: [](error_code){}); |
| 458 | wss.async_accept(handler: [](error_code){}); |
| 459 | ioc.run(); |
| 460 | ioc.restart(); |
| 461 | BEAST_EXPECT(wsc.is_open()); |
| 462 | BEAST_EXPECT(wss.is_open()); |
| 463 | // invalid 1-byte deflate block in frame |
| 464 | net::write(s&: wsc.next_layer(), buffers: sbuf( |
| 465 | s: "\xc1\x81\x3a\xa1\x74\x3b\x49" )); |
| 466 | error_code ec; |
| 467 | multi_buffer b; |
| 468 | wss.read(buffer&: b, ec); |
| 469 | BEAST_EXPECTS(ec == zlib::error::end_of_stream, ec.message()); |
| 470 | } |
| 471 | |
| 472 | // async read |
| 473 | #if 0 |
| 474 | { |
| 475 | echo_server es{log, kind::async}; |
| 476 | net::io_context ioc; |
| 477 | stream<test::stream> ws{ioc}; |
| 478 | ws.set_option(pmd); |
| 479 | ws.next_layer().connect(es.stream()); |
| 480 | ws.handshake("localhost" , "/" ); |
| 481 | // invalid 1-byte deflate block in frame |
| 482 | net::write(ws.next_layer(), sbuf( |
| 483 | "\xc1\x81\x3a\xa1\x74\x3b\x49" )); |
| 484 | } |
| 485 | #endif |
| 486 | { |
| 487 | net::io_context ioc; |
| 488 | stream<test::stream> wsc{ioc}; |
| 489 | stream<test::stream> wss{ioc}; |
| 490 | wsc.set_option(pmd); |
| 491 | wss.set_option(pmd); |
| 492 | wsc.next_layer().connect(remote&: wss.next_layer()); |
| 493 | wsc.async_handshake( |
| 494 | host: "localhost" , target: "/" , handler: [](error_code){}); |
| 495 | wss.async_accept(handler: [](error_code){}); |
| 496 | ioc.run(); |
| 497 | ioc.restart(); |
| 498 | BEAST_EXPECT(wsc.is_open()); |
| 499 | BEAST_EXPECT(wss.is_open()); |
| 500 | // invalid 1-byte deflate block in frame |
| 501 | net::write(s&: wsc.next_layer(), buffers: sbuf( |
| 502 | s: "\xc1\x81\x3a\xa1\x74\x3b\x49" )); |
| 503 | error_code ec; |
| 504 | flat_buffer b; |
| 505 | wss.async_read(buffer&: b, |
| 506 | handler: [&ec](error_code ec_, std::size_t){ ec = ec_; }); |
| 507 | ioc.run(); |
| 508 | BEAST_EXPECTS(ec == zlib::error::end_of_stream, ec.message()); |
| 509 | } |
| 510 | } |
| 511 | |
| 512 | /* Bishop Fox Hybrid Assessment issue 2 |
| 513 | |
| 514 | Happens with permessage-deflate enabled, |
| 515 | and a deflate block with the BFINAL bit set |
| 516 | is encountered in a compressed payload. |
| 517 | */ |
| 518 | void |
| 519 | testIssueBF2() |
| 520 | { |
| 521 | permessage_deflate pmd; |
| 522 | pmd.client_enable = true; |
| 523 | pmd.server_enable = true; |
| 524 | |
| 525 | // read |
| 526 | { |
| 527 | net::io_context ioc; |
| 528 | stream<test::stream> wsc{ioc}; |
| 529 | stream<test::stream> wss{ioc}; |
| 530 | wsc.set_option(pmd); |
| 531 | wss.set_option(pmd); |
| 532 | wsc.next_layer().connect(remote&: wss.next_layer()); |
| 533 | wsc.async_handshake( |
| 534 | host: "localhost" , target: "/" , handler: [](error_code){}); |
| 535 | wss.async_accept(handler: [](error_code){}); |
| 536 | ioc.run(); |
| 537 | ioc.restart(); |
| 538 | BEAST_EXPECT(wsc.is_open()); |
| 539 | BEAST_EXPECT(wss.is_open()); |
| 540 | // contains a deflate block with BFINAL set |
| 541 | net::write(s&: wsc.next_layer(), buffers: sbuf( |
| 542 | s: "\xc1\xf8\xd1\xe4\xcc\x3e\xda\xe4\xcc\x3e" |
| 543 | "\x2b\x1e\x36\xc4\x2b\x1e\x36\xc4\x2b\x1e" |
| 544 | "\x36\x3e\x35\xae\x4f\x54\x18\xae\x4f\x7b" |
| 545 | "\xd1\xe4\xcc\x3e\xd1\xe4\xcc\x3e\xd1\xe4" |
| 546 | "\xcc\x3e\xd1\xe4\xcc\x3e\xd1\xe4\xcc\x3e" |
| 547 | "\xd1\x1e\x36\xc4\x2b\x1e\x36\xc4\x2b\xe4" |
| 548 | "\x28\x74\x52\x8e\x05\x74\x52\xa1\xcc\x3e" |
| 549 | "\xd1\xe4\xcc\x3e\xd1\xe4\xcc\x3e\xd1\xe4" |
| 550 | "\xcc\x3e\xd1\xe4\xcc\x3e\xd1\xe4\xcc\x3e" |
| 551 | "\xd1\xe4\xcc\x3e\xd1\xe4\xcc\x3e\xd1\xe4" |
| 552 | "\xcc\x3e\xd1\xe4\xcc\x3e\xd1\xe4\x36\x3e" |
| 553 | "\xd1\xec\xcc\x3e\xd1\xe4\xcc\x3e\xd1\xe4" |
| 554 | "\xcc\x3e\xd1\xe4\xcc\x3e" )); |
| 555 | error_code ec; |
| 556 | flat_buffer b; |
| 557 | wss.read(buffer&: b, ec); |
| 558 | BEAST_EXPECTS(ec == zlib::error::end_of_stream, ec.message()); |
| 559 | } |
| 560 | |
| 561 | // async read |
| 562 | { |
| 563 | net::io_context ioc; |
| 564 | stream<test::stream> wsc{ioc}; |
| 565 | stream<test::stream> wss{ioc}; |
| 566 | wsc.set_option(pmd); |
| 567 | wss.set_option(pmd); |
| 568 | wsc.next_layer().connect(remote&: wss.next_layer()); |
| 569 | wsc.async_handshake( |
| 570 | host: "localhost" , target: "/" , handler: [](error_code){}); |
| 571 | wss.async_accept(handler: [](error_code){}); |
| 572 | ioc.run(); |
| 573 | ioc.restart(); |
| 574 | BEAST_EXPECT(wsc.is_open()); |
| 575 | BEAST_EXPECT(wss.is_open()); |
| 576 | // contains a deflate block with BFINAL set |
| 577 | net::write(s&: wsc.next_layer(), buffers: sbuf( |
| 578 | s: "\xc1\xf8\xd1\xe4\xcc\x3e\xda\xe4\xcc\x3e" |
| 579 | "\x2b\x1e\x36\xc4\x2b\x1e\x36\xc4\x2b\x1e" |
| 580 | "\x36\x3e\x35\xae\x4f\x54\x18\xae\x4f\x7b" |
| 581 | "\xd1\xe4\xcc\x3e\xd1\xe4\xcc\x3e\xd1\xe4" |
| 582 | "\xcc\x3e\xd1\xe4\xcc\x3e\xd1\xe4\xcc\x3e" |
| 583 | "\xd1\x1e\x36\xc4\x2b\x1e\x36\xc4\x2b\xe4" |
| 584 | "\x28\x74\x52\x8e\x05\x74\x52\xa1\xcc\x3e" |
| 585 | "\xd1\xe4\xcc\x3e\xd1\xe4\xcc\x3e\xd1\xe4" |
| 586 | "\xcc\x3e\xd1\xe4\xcc\x3e\xd1\xe4\xcc\x3e" |
| 587 | "\xd1\xe4\xcc\x3e\xd1\xe4\xcc\x3e\xd1\xe4" |
| 588 | "\xcc\x3e\xd1\xe4\xcc\x3e\xd1\xe4\x36\x3e" |
| 589 | "\xd1\xec\xcc\x3e\xd1\xe4\xcc\x3e\xd1\xe4" |
| 590 | "\xcc\x3e\xd1\xe4\xcc\x3e" )); |
| 591 | error_code ec; |
| 592 | flat_buffer b; |
| 593 | wss.async_read(buffer&: b, |
| 594 | handler: [&ec](error_code ec_, std::size_t){ ec = ec_; }); |
| 595 | ioc.run(); |
| 596 | BEAST_EXPECTS(ec == zlib::error::end_of_stream, ec.message()); |
| 597 | } |
| 598 | } |
| 599 | |
| 600 | /* |
| 601 | * Tests when a deflate block spans multiple multi_byte character arrays. |
| 602 | */ |
| 603 | void |
| 604 | testIssue1630() |
| 605 | { |
| 606 | permessage_deflate pmd; |
| 607 | pmd.client_enable = true; |
| 608 | pmd.server_enable = true; |
| 609 | |
| 610 | net::io_context ioc; |
| 611 | stream<test::stream> wsc{ioc}; |
| 612 | stream<test::stream> wss{ioc}; |
| 613 | wsc.set_option(pmd); |
| 614 | wss.set_option(pmd); |
| 615 | wsc.next_layer().connect(remote&: wss.next_layer()); |
| 616 | wsc.async_handshake( |
| 617 | host: "localhost" , target: "/" , handler: [](error_code){}); |
| 618 | wss.async_accept(handler: [](error_code){}); |
| 619 | ioc.run(); |
| 620 | ioc.restart(); |
| 621 | BEAST_EXPECT(wsc.is_open()); |
| 622 | BEAST_EXPECT(wss.is_open()); |
| 623 | |
| 624 | const asio::const_buffer packets[] = { |
| 625 | sbuf( |
| 626 | // websocket bytes |
| 627 | s: "\xc1\x2d" |
| 628 | |
| 629 | //deflated payload |
| 630 | "\xaa\x56\xca\x4b\x4d\xcf\x2f\xc9\x4c\x2c\x49" |
| 631 | "\x4d\x09\xc9\xcc\x4d\xcd\x2f\x2d\x51\xb2\x32" |
| 632 | "\x35\x30\x30\xd0\x51\x2a\xa9\x2c\x48\x55\xb2" |
| 633 | "\x52\x2a\x4f\xcd\x49\xce\xcf\x4d\x55\xaa\x05" |
| 634 | "\x00" |
| 635 | ), |
| 636 | // packet 2 |
| 637 | sbuf( |
| 638 | s: "\xc1\x7e\x0b\x89" |
| 639 | "\xd4\x5a\xdb\x8e\xdb\x48\x92\xfd\x15\xa1\x1e" |
| 640 | "\x17\x5b\xae\xbc\x5f\xb8\xf0\x43\x49\xa5\xc2" |
| 641 | "\xf6\xa2\xdd\x30\xfa\x36\x98\xd9\x19\x34\xf2" |
| 642 | "\x12\x29\xb1\x74\x2d\x92\x52\x5d\x0c\xff\xfb" |
| 643 | "\x1c\x4a\xb6\xdb\xa2\xc7\xd3\xe8\x92\x5f\x06" |
| 644 | "\x7e\x28\x93\x99\xc9\xc8\x8c\x38\x11\xe7\x04" |
| 645 | "\xa9\x77\x17\x71\x93\x9f\x2e\xaa\x77\x17\x7b" |
| 646 | "\x6a\xda\x7a\xb3\xbe\xa8\xc4\xa7\x59\x69\xb3" |
| 647 | "\x5e\x53\xc2\x43\x2e\xfe\xfb\x62\x4b\xd4\xfc" |
| 648 | "\xf6\xe1\x06\xa6\xb5\x17\xd5\xff\xbf\xbb\xa8" |
| 649 | "\x33\x66\x69\x9a\x46\xca\x21\xa4\xac\xcd\xf8" |
| 650 | "\xd6\x14\xaf\xb8\x4f\x79\x62\xb3\x1c\x3b\x3d" |
| 651 | "\xe1\x1e\x8b\x33\xb5\xa9\xa9\xb7\xdd\xe1\xf9" |
| 652 | "\xef\x3e\x3e\x3e\xac\xdb\x07\x6a\x30\xdc\xe6" |
| 653 | "\x2d\x2e\xf7\xaf\xd9\xdf\x9b\xbf\xaf\x37\xaf" |
| 654 | "\x2f\x47\xd2\x09\xa5\xad\x36\x52\x7d\xfe\xdf" |
| 655 | "\xef\x7e\x18\x7d\xf7\x56\x8d\xd8\xab\xc3\xbf" |
| 656 | "\x7e\x6e\xfb\xfa\xd7\x37\xc4\x44\x14\x26\x58" |
| 657 | "\x91\xb2\x30\x2c\x6a\x92\x32\x58\xed\x42\x0c" |
| 658 | "\x2c\x59\x8a\xb1\x9f\xd7\xbd\x66\xa3\xc3\x82" |
| 659 | "\xf0\xba\x4e\x74\xb9\xac\x3b\x3a\x5e\xad\xda" |
| 660 | "\x3a\x5f\xb6\xb4\x0a\xeb\xae\x4e\xd5\xe8\x2f" |
| 661 | "\x6f\x7e\x1a\xfd\xd7\x71\x64\xd6\x6c\x76\xdb" |
| 662 | "\x6a\xfc\xcb\x0f\x37\xdf\x4f\x47\x61\x97\xeb" |
| 663 | "\xcd\x68\x5f\x67\xda\xf4\xa3\xab\xd7\xc7\x1b" |
| 664 | "\xdc\x70\x2e\x46\xbf\xdc\xbc\xbd\xfa\xf9\xfb" |
| 665 | "\x9f\xae\x7e\xfc\xf9\xed\xd5\x4f\xd7\xbf\xbe" |
| 666 | "\xbd\x1d\x71\xce\x8f\xe6\xd2\xeb\x0f\x7b\xd6" |
| 667 | "\xea\x15\x37\xf2\x95\x32\xaf\x38\x37\x47\x03" |
| 668 | "\xf4\xd8\xad\xc2\xb6\xe2\xa3\x5d\xb3\xae\x6a" |
| 669 | "\xea\x4a\xb5\x0d\x4d\x58\xb5\x55\xd3\x6d\x2f" |
| 670 | "\xe7\xb9\xc1\x78\xd5\xb6\x4d\xba\x3c\xd8\xba" |
| 671 | "\x5c\xd2\x9e\x96\xc7\x95\x4d\x97\xb0\xee\x60" |
| 672 | "\xfb\xeb\x8f\xc7\x53\x0e\x8f\xc7\x56\x36\xdb" |
| 673 | "\x5d\x7b\xa5\x1c\xe2\x7f\x25\x4e\x06\xd9\xe8" |
| 674 | "\xed\xe4\xcd\x2f\x57\xfd\xc8\xf1\x7e\x59\x75" |
| 675 | "\xc7\x25\xab\x7a\x8d\x68\xad\xe8\x35\x67\xff" |
| 676 | "\xb3\x6b\xa9\x5e\xc7\xb0\xce\x85\xd2\x6b\x7e" |
| 677 | "\x9c\x98\x70\x59\x67\xe0\xab\x12\x23\xde\x7b" |
| 678 | "\x60\x24\x18\x97\xc2\x18\x25\xd9\xe9\x6e\x3e" |
| 679 | "\x38\x09\x21\x1f\xcd\x37\x6d\xf7\xe5\x72\x71" |
| 680 | "\xb2\x5c\xf8\x2f\x96\x3b\xad\x06\xcb\x7b\x07" |
| 681 | "\x5c\xae\x76\x8f\xc7\xab\x96\x3a\x44\x2a\x00" |
| 682 | "\x96\xfb\x8f\x51\xad\x73\x75\xf0\xda\x87\x90" |
| 683 | "\xaf\x3f\x1f\xec\x01\xb0\x2b\x4d\x98\x55\x7f" |
| 684 | "\x91\xe3\xd5\xef\xf7\xb6\x0f\xb9\xfa\xbf\xc9" |
| 685 | "\xf7\xe5\x6f\xbf\x88\xe4\x36\xfc\xfb\xbf\xbe" |
| 686 | "\xf9\xa1\xb9\x7e\x93\xfe\xf7\xe9\xbb\x0f\xbe" |
| 687 | "\xa9\xd7\x33\x6a\xb6\x4d\xbd\x46\x5c\xe6\xe1" |
| 688 | "\x52\x68\x33\xba\xbe\xa9\xac\xa8\xa6\x93\x4a" |
| 689 | "\x89\x8a\x4d\x2a\xc9\xaa\xa9\xad\x1c\xaf\x8c" |
| 690 | "\xad\xae\x27\x15\x9f\x56\xb7\xaa\x62\xbc\x9f" |
| 691 | "\xa3\x58\x35\xbe\xae\xa4\xab\xb8\xae\xac\xab" |
| 692 | "\xec\x4d\x25\x54\x75\x73\x53\xe9\x49\x7f\x67" |
| 693 | "\xcc\xab\x9b\xdb\xca\x4c\x2b\x31\xae\x24\xee" |
| 694 | "\x4f\xfb\xfb\x52\x1f\xb1\x76\x80\xdd\x57\xb1" |
| 695 | "\xe6\xe1\x22\x86\x20\x08\xfb\x47\x80\x3b\x78" |
| 696 | "\x0d\x39\xfe\x4c\x27\x00\x14\xa3\x79\x87\xa8" |
| 697 | "\x5f\x5d\x3d\x3c\x3c\xbc\x7a\xa0\x88\x69\xaf" |
| 698 | "\x36\xcd\xec\x8a\x1e\xb7\xd4\x00\x02\xeb\xae" |
| 699 | "\xbd\xfa\x1d\x92\x57\x21\xb6\x48\x98\x75\xbe" |
| 700 | "\xec\xe1\xf1\xe7\xf1\x88\xed\xfe\xfa\xd6\x5d" |
| 701 | "\x79\xf6\x09\x73\x1f\x81\x8a\x43\x34\x94\xff" |
| 702 | "\xd5\x88\xb0\xa3\xdd\x72\x0b\xf4\x9d\x0e\xe2" |
| 703 | "\x34\x25\xf6\x0f\x9c\x6d\x36\xb3\xcb\x86\x56" |
| 704 | "\xf1\x8b\x91\x94\x56\xa3\x52\x37\x5f\xdc\x07" |
| 705 | "\x20\x16\xff\xf2\xe6\x68\xbb\xac\xff\x53\x10" |
| 706 | "\xfe\xa9\x1c\xfd\x87\x23\x1c\x04\xd0\xd0\xbe" |
| 707 | "\x3e\x92\x0f\x7f\xff\xfe\x1f\x20\x84\x03\xb1" |
| 708 | "\xfc\xf8\x26\x4a\xad\xb2\x92\x96\x9c\x0d\x14" |
| 709 | "\x6d\xe1\x41\x48\x23\xbc\x29\x4a\xd8\xa0\x55" |
| 710 | "\xc2\xd2\x75\x58\xf5\x5c\xd2\x51\xdb\xfd\xb8" |
| 711 | "\xd9\xac\x78\x4f\x55\xa1\x41\x35\xaf\xb7\x28" |
| 712 | "\xea\x3d\xdb\x1c\x1f\xf6\xf6\xda\x07\x6e\x98" |
| 713 | "\xd6\x4c\xa9\x98\x5d\xe4\x31\x07\xe5\xb8\x35" |
| 714 | "\xcc\x5a\xb2\x9a\x97\x88\x95\xf0\x28\x88\xa0" |
| 715 | "\x03\x1f\x5e\xa8\xc5\x83\x6c\x1f\x1e\x14\x17" |
| 716 | "\x01\x03\x5d\x03\x70\xf4\x9c\xf7\x8f\x93\xcd" |
| 717 | "\x62\xa7\x1d\x62\x7c\x42\x95\xef\x4f\x36\x70" |
| 718 | "\xe4\xc9\x8f\x5b\x50\xc9\x0a\xc5\x48\x27\x6e" |
| 719 | "\x9d\xd1\xc1\x11\x27\x2a\xdc\x32\xe2\x9a\x7b" |
| 720 | "\x7b\xb0\xf4\xd9\x16\x9e\x42\xfd\x1c\xb5\xdf" |
| 721 | "\xdc\xcf\xfe\xec\x0e\x7e\xb7\xe8\x6c\xe4\x89" |
| 722 | "\x31\xee\x75\x24\x09\x6b\x8a\x60\x8c\x65\xa5" |
| 723 | "\x8b\x2f\x52\x65\x7e\x6a\x71\xbe\xb2\xdd\x7e" |
| 724 | "\x3d\x8b\x0f\xdb\x97\x5b\x14\x64\x43\x20\xc9" |
| 725 | "\x02\xf7\x4a\x38\xa1\x09\x8c\x2c\xa4\x73\x41" |
| 726 | "\x30\x11\x92\x33\xa7\x16\x1f\x9f\x77\x6c\xbe" |
| 727 | "\xb7\xba\xac\x4f\x4c\xbe\xbb\x58\xd4\xeb\xfe" |
| 728 | "\x79\x87\x32\xde\xc7\xb4\xa9\x37\xcd\x71\x09" |
| 729 | "\xcc\xaf\x73\x68\xf2\xe1\x41\xb8\x9e\xc4\x20" |
| 730 | "\xd4\x6d\x9a\x4e\xb9\x1f\x73\x91\x6f\xf9\xd4" |
| 731 | "\xfa\xb1\xb3\x53\x75\xe3\xfc\x58\xc8\x6b\xcc" |
| 732 | "\xa3\x75\x88\x4b\xec\xb3\xea\x9a\x1d\x7d\x84" |
| 733 | "\xd7\x9b\x9f\x59\x26\x15\x95\x4b\x91\x9b\x42" |
| 734 | "\xe4\x88\x22\xb6\x18\x12\xe5\x92\x99\x96\xe5" |
| 735 | "\x33\x78\x1d\xb6\xd1\x3b\xeb\xe3\xd9\x1b\x0a" |
| 736 | "\x90\x4d\xef\xff\xa4\x6b\xa4\xcd\x3a\xc9\x10" |
| 737 | "\xe0\x0d\x66\x45\xb1\xc5\x15\x0a\x0e\x7f\x1c" |
| 738 | "\x15\x16\xf4\xa9\x6b\xb6\xcb\xfc\x3c\x7f\x7e" |
| 739 | "\x6e\x82\x7b\x79\x30\x4a\x61\x52\x10\x03\xd4" |
| 740 | "\x11\x13\x32\x8a\x2b\x0b\x81\xa6\x2d\x67\x64" |
| 741 | "\x6c\xa4\x01\xe0\x9c\x7a\x5e\x6d\xd6\x4f\x33" |
| 742 | "\x7b\x86\x45\x29\xb3\x13\xdc\x05\x0f\x9f\x96" |
| 743 | "\x60\x88\xbc\x0c\x39\x51\x04\xe8\x45\x31\x7c" |
| 744 | "\x60\x71\xbf\x17\xcb\xd9\x4c\x3f\xab\xfb\xf8" |
| 745 | "\x72\x93\x54\x10\x45\x98\xd3\x46\x91\xe3\xc5" |
| 746 | "\x67\xe3\x78\x72\xd1\xb3\xe2\xb9\x04\xf2\x4e" |
| 747 | "\x4d\x2e\x6a\x73\x37\x33\xe6\x69\x7f\x77\x7f" |
| 748 | "\x86\x49\x99\x62\xcc\x49\x3a\x29\x54\x91\x92" |
| 749 | "\x21\x9f\x19\x59\x11\x93\xb5\x70\x36\xf9\x53" |
| 750 | "\x93\xcf\x49\x3c\x74\xeb\x55\x9a\xe9\x97\x62" |
| 751 | "\xdc\x8e\xbd\x4c\xc0\x8b\x08\xd7\x65\x12\x88" |
| 752 | "\x29\x76\x33\xf6\x88\xa7\xb9\xe5\x66\x32\x66" |
| 753 | "\xe6\xeb\x18\x2f\x36\x1a\x53\x5c\x2e\xdc\xbb" |
| 754 | "\x88\x24\x8c\x56\x81\x83\x94\x00\xf4\x82\xc8" |
| 755 | "\xd1\x7d\x6b\x8c\x67\x16\xb1\x53\x6f\x6d\xd4" |
| 756 | "\x2c\x3b\x16\x89\x39\xe1\xc9\x9b\xbe\x80\x1b" |
| 757 | "\x00\xe2\xd4\x33\x65\x66\xee\xb6\xcf\x0f\x4e" |
| 758 | "\x29\xf3\x52\xd7\xe4\x6b\xe7\x39\xbf\xa1\xa8" |
| 759 | "\x8c\x33\xe4\x99\xb8\x71\xc5\x0a\xeb\x43\x36" |
| 760 | "\x13\x19\xb4\xfb\xba\x6b\x28\x18\x99\x8d\x28" |
| 761 | "\x49\xea\x4c\x5a\x0b\xa9\x4a\x22\x1e\x5d\xc9" |
| 762 | "\xdc\x07\x55\xbe\xb9\x6b\xa2\x96\x46\x72\xa6" |
| 763 | "\x85\x8e\x46\x64\x50\x18\x2a\x30\x17\xe8\x57" |
| 764 | "\x94\xc9\x3c\x85\x01\x01\x2d\x5a\x24\xd1\xd3" |
| 765 | "\xc2\xad\xd9\xfc\x0c\x9c\x22\x1a\x21\xe4\x10" |
| 766 | "\xbd\x96\xde\x71\x27\x8b\x62\x20\x40\x27\x72" |
| 767 | "\xee\xb7\x30\x30\xa9\xbb\xd6\x7b\xbf\x8f\xfb" |
| 768 | "\xae\x9c\x51\xff\x59\x30\x3e\x5a\x9f\x35\x22" |
| 769 | "\xae\x72\x62\x9e\x64\xe6\x1c\x65\xd5\x19\xc1" |
| 770 | "\xe3\xa0\xc8\xb5\x6e\xb3\x69\x45\x3b\x67\x67" |
| 771 | "\x70\x5c\x4a\xbd\x28\xc8\x92\x2b\x9e\x2c\x7a" |
| 772 | "\x41\x69\xa8\x38\xc4\x4f\x4a\x6e\x75\x1e\x42" |
| 773 | "\x4e\x37\xdb\xc7\xed\xfe\xa9\x7e\xf4\x67\x98" |
| 774 | "\x54\x85\x83\x20\x14\x05\x1c\x0e\x96\xad\x0b" |
| 775 | "\x8a\xf3\x62\xb2\xd3\x01\x95\x5d\x0e\x68\x35" |
| 776 | "\xd7\xb6\x5d\x28\xf5\x94\xd5\x4b\x41\x7e\x33" |
| 777 | "\x9e\x06\xba\x4d\xd7\xb6\x8c\x7b\x01\x33\x65" |
| 778 | "\x13\x7d\x3b\x09\xce\x84\x58\x8c\xbe\xfd\x77" |
| 779 | "\xf9\x0f\x81\xa3\x9d\xb4\x5c\x1a\x28\x0c\xaf" |
| 780 | "\x28\x16\x8d\x7a\xec\x3c\x01\x7f\x42\x90\xfa" |
| 781 | "\xd6\x20\x2f\x59\xd9\xac\x10\x74\x4b\xc9\x2b" |
| 782 | "\x23\xb4\x48\xd2\xfb\xc4\xa3\xe1\xca\xcb\xa1" |
| 783 | "\xc4\x29\x6c\x7f\xcf\x3b\x7b\x87\x04\x7c\x79" |
| 784 | "\x30\xb4\x06\xcb\xe5\x98\xb3\x43\xa5\x8b\x05" |
| 785 | "\xa7\xcb\x7d\xa3\x20\x20\x06\xa0\xa9\x6c\x3e" |
| 786 | "\x35\x69\x15\x28\xc1\x77\x35\x70\xf7\x72\x93" |
| 787 | "\x28\x10\xc6\x6b\x21\x58\xce\x64\x7d\xca\x3c" |
| 788 | "\x6b\x6b\x74\xb4\x89\xf3\x64\x24\x1b\x80\x9c" |
| 789 | "\xb4\xcf\x77\x4f\x51\x24\x75\x06\xe5\x20\xa1" |
| 790 | "\x24\x8b\xde\xb8\xa0\x21\x7f\x0b\xca\x88\xa3" |
| 791 | "\x24\xc8\x69\xb2\xc9\x17\xaf\x06\x54\xce\xc0" |
| 792 | "\x87\x8b\x8d\xe8\x16\xf9\x1c\x94\x33\xa3\xbd" |
| 793 | "\x88\x92\x41\xb7\xa5\x22\x7d\x48\x06\x7a\x5c" |
| 794 | "\xf3\x04\xe6\x30\x43\xc5\xcc\x96\x9d\xae\xe7" |
| 795 | "\xa1\xd6\x85\x2f\xcf\x08\x26\x2a\x07\xa0\xe9" |
| 796 | "\xa3\x57\xc5\x3a\x5c\xf9\x08\xa7\x92\x56\x88" |
| 797 | "\xa7\x31\x76\xc0\xac\x82\x4c\x57\x5a\xb5\x62" |
| 798 | "\xcf\x2f\xcd\xac\x08\xed\x2d\x85\xe7\xf6\x7a" |
| 799 | "\x72\xdd\x87\x6e\x22\xd9\x58\x4b\x3b\x9e\x5e" |
| 800 | "\x6b\xe5\xc6\x53\xff\xf5\xcc\xf2\x94\x1c\x73" |
| 801 | "\xc8\x78\xe6\x25\xa9\xa0\x50\xce\x0b\x17\x89" |
| 802 | "\x07\x12\x51\xf0\x03\xec\xbe\xad\x7a\xcc\x26" |
| 803 | "\x07\xcd\x0c\xe3\x09\x6c\x0e\xba\x42\x95\x8d" |
| 804 | "\x29\x12\x1a\x24\xc1\x58\x11\x03\xf5\x58\x3f" |
| 805 | "\x85\xc7\x4d\xb1\x07\x8f\xbd\x58\xe5\x14\x70" |
| 806 | "\xab\xe3\x26\xf6\x2f\x0f\xa3\x89\x46\x8b\xec" |
| 807 | "\x3c\xf4\x0d\x2a\x2e\x2b\x03\xc8\x41\x68\x3e" |
| 808 | "\xee\xfd\x2a\xcf\xdb\xc5\xcb\x4d\x32\x74\xc4" |
| 809 | "\xc9\x68\xcb\xd0\x2a\x33\x1e\x20\x8a\x93\xb1" |
| 810 | "\xc5\xea\xc8\x8c\x09\x65\x78\xc8\xa7\xe2\xb6" |
| 811 | "\xe9\x7e\xbe\xdb\xbd\xb8\xb0\x2a\x88\xa7\x5b" |
| 812 | "\x75\x7d\x33\xd5\x37\x19\x9a\x65\x2c\x99\x74" |
| 813 | "\xe3\x34\x1d\x5f\xc7\x89\x98\x18\x16\xbe\x1e" |
| 814 | "\x7e\x21\x2c\xb7\x05\x8d\x23\x68\x2e\xa0\xfe" |
| 815 | "\x18\x0a\x0c\xd1\x4f\x5e\xa3\xf0\x45\xff\xcd" |
| 816 | "\xd5\x03\x11\x4b\xa0\x18\x86\x36\xd6\x2a\xab" |
| 817 | "\x60\x11\xea\x26\x65\x05\x3f\x81\xce\xf5\xc0" |
| 818 | "\x33\xcd\x12\xcd\xe5\xc2\xb9\xfb\xa7\xfa\x0c" |
| 819 | "\x62\x25\xa9\x24\x1a\x13\x69\x8d\xcb\x21\x43" |
| 820 | "\x60\x43\xc4\x43\xcb\x3b\xef\x91\x99\x21\x0f" |
| 821 | "\x4d\xf2\x9d\x70\x7b\x12\x67\x55\xb9\x82\x63" |
| 822 | "\xf1\x04\x77\xa2\x39\xf5\x26\x66\x54\x20\x97" |
| 823 | "\x24\x8f\x92\x52\x89\xce\x9e\x9a\x5c\xd7\x4a" |
| 824 | "\x2f\x96\x4d\x58\x75\x2f\x8d\xbf\x80\xc1\x88" |
| 825 | "\xfe\x54\x66\x81\x7e\xe8\x5a\x8c\xf3\x4d\x0c" |
| 826 | "\x13\x48\xf9\x9b\x71\x30\xec\x76\xf2\x6f\x9a" |
| 827 | "\x47\x42\xb0\x45\xd1\xce\x41\x8d\x17\xe1\x0c" |
| 828 | "\xaa\x15\x49\x13\x15\xd3\x11\xac\xf7\xcd\xe3" |
| 829 | "\xcf\xd0\xbd\x5b\x6d\xa1\xdf\x93\x46\x00\x7c" |
| 830 | "\x28\x9c\x02\xaa\x80\x40\x4b\xaf\x50\xec\x07" |
| 831 | "\x9e\x69\xd5\xbc\xbd\xdb\xda\x99\x3f\xa7\xfe" |
| 832 | "\xa3\x6b\x04\xc8\x23\xe3\x4c\x5a\x2b\x50\x6f" |
| 833 | "\xb2\x08\x05\x98\x4b\xac\x48\x32\x03\x61\x25" |
| 834 | "\xd9\x66\xe1\x54\x36\xfb\xbb\x33\x84\x15\x13" |
| 835 | "\x25\x2a\xc1\x55\xce\x90\x55\x46\x95\x08\x75" |
| 836 | "\xac\x4c\x42\x5b\x17\xb9\x14\x76\x60\x72\x89" |
| 837 | "\xe6\x71\x1e\x9a\xe6\xa9\x9c\xa1\x91\x21\x8d" |
| 838 | "\x20\x87\x99\xd5\xc6\x27\x05\x69\xee\x93\x83" |
| 839 | "\x2c\xe7\xb0\xcb\x89\xcb\x61\xc9\x11\x8f\xbb" |
| 840 | "\x0d\x7f\x94\xf3\x66\x25\x5f\x6e\xd2\x16\x43" |
| 841 | "\x82\xc9\xe8\x98\x8f\x32\x17\x54\xb8\x52\x28" |
| 842 | "\x5b\xe5\x0b\xca\x1e\x94\xd3\xe0\x1d\x49\x9c" |
| 843 | "\x2f\x56\x1b\x41\xeb\xd9\x19\xb1\x24\x88\x90" |
| 844 | "\x92\xb8\x62\x89\x60\xd4\x48\x95\x99\x77\x49" |
| 845 | "\x40\x27\x08\x19\xfd\x50\x24\xdf\xab\xf5\xec" |
| 846 | "\x7e\x1d\x9e\x66\x74\x46\x5f\x2e\x1d\x8a\x93" |
| 847 | "\x83\x5c\x40\xf4\x54\x41\x17\x58\x38\xb2\x59" |
| 848 | "\x05\x10\xab\x4b\x5c\x0c\xa8\xfc\xfe\xa1\x9d" |
| 849 | "\xdf\xdd\x6f\x1f\xdb\xc5\x19\x26\xb5\x46\x4a" |
| 850 | "\x90\x02\x91\x27\x4a\x56\xb3\x90\x82\x70\x96" |
| 851 | "\x34\x7a\x0f\x2a\x5a\x0c\x14\x4b\x11\x4d\x6a" |
| 852 | "\xbc\x9c\x69\x7d\x86\x60\xa1\xc8\xc1\xfa\xa6" |
| 853 | "\x7f\x9b\x16\x13\x9a\x0e\x83\x5e\x24\x59\x2f" |
| 854 | "\xac\x8a\x68\x77\xfd\xa0\x62\xdd\x89\x6d\xbd" |
| 855 | "\x60\x1d\xd9\xbb\x33\xd2\x32\x40\x05\x9a\xfe" |
| 856 | "\x2d\xa8\x43\xd7\xe8\x11\x41\xed\x83\xd0\xc1" |
| 857 | "\x16\x01\x0c\xbb\x32\xf0\xab\xdc\xb7\x16\x5a" |
| 858 | "\xe0\x41\x9d\xa1\x77\x21\x3d\x95\x44\x65\x87" |
| 859 | "\x9e\xb0\x31\xa0\xde\x59\x1b\x12\x72\x25\xa1" |
| 860 | "\x5a\x7b\x2e\x07\xc5\xa7\xf8\xc5\x96\xa7\xd6" |
| 861 | "\xdd\xdb\xcd\x19\x4c\x60\x81\x14\x99\x90\xfd" |
| 862 | "\xa5\x7f\x7f\x84\x4e\x27\x6b\x86\x8c\x81\x34" |
| 863 | "\xb0\x28\xda\x83\xb4\x94\x4f\xbe\x70\x7e\x9f" |
| 864 | "\xf7\xea\x8c\x1c\xd1\xc1\xa3\x9d\x82\xce\x4d" |
| 865 | "\xe0\x58\x1c\x58\x3a\xce\x73\x16\xae\x6f\x97" |
| 866 | "\x55\x09\x83\x50\xba\xa5\x5c\x74\x7c\x2f\x50" |
| 867 | "\x12\xcf\xa0\x58\x0f\x42\x47\x6e\xa2\x8e\x73" |
| 868 | "\xc6\x7d\x12\x3c\x28\x17\x4c\x80\xf4\x81\x86" |
| 869 | "\x18\x9e\x92\xb9\x36\x85\xc5\x92\x67\x1b\xce" |
| 870 | "\xf0\x6c\xdf\x2f\xf9\xe0\x55\xcc\x85\x65\xe5" |
| 871 | "\x72\x71\x56\x94\xe2\xb3\x4d\x21\x1b\x68\xfc" |
| 872 | "\x53\x9b\x3c\x3e\xec\xed\xbe\xcc\xeb\xd4\x9d" |
| 873 | "\x61\x32\x6a\x30\xad\xb7\xc5\x17\x65\x05\x79" |
| 874 | "\x6f\x38\x0a\x81\x4a\xde\xeb\xe8\x85\x92\x83" |
| 875 | "\xf7\x65\xeb\xf6\xfe\x49\x75\xbb\xe7\x17\xcb" |
| 876 | "\x3a\x06\x76\x1e\x4f\xc1\x20\x29\x38\x39\x9e" |
| 877 | "\x4c\x7a\x3a\x17\x60\x4f\xe2\xd7\x5a\xdc\x9a" |
| 878 | "\xf4\x75\x5a\xef\x9b\x0f\x85\x02\x49\xde\x80" |
| 879 | "\x12\xc8\xf9\x48\x2c\x6a\x8f\x52\x96\xb2\x06" |
| 880 | "\x00\xbf\x79\xbf\x6c\xd1\x43\x42\xab\x25\xd5" |
| 881 | "\x7f\x9d\x50\x46\x73\x21\x0d\x49\x9d\x6c\xf4" |
| 882 | "\x68\xf2\x06\xfd\xf2\x03\xbc\xb6\x5c\x47\x3b" |
| 883 | "\x13\x67\x50\x2c\x54\x2b\xa1\x19\x85\xb6\xd2" |
| 884 | "\x09\x0a\x3f\x87\x5e\x63\x99\xe0\xac\xe3\xe4" |
| 885 | "\x86\xed\xf2\x5e\xb3\x25\x37\x8b\x8d\x6f\xcf" |
| 886 | "\x78\x29\x8c\xd3\xf5\xe2\x05\x9a\x35\x14\xc8" |
| 887 | "\x7b\x54\x62\xc8\xe6\xec\x82\x30\xa4\x8d\xf4" |
| 888 | "\x83\xd7\x25\x89\x9a\xb6\xd3\x72\xc5\xba\x33" |
| 889 | "\x8a\xa4\x64\x60\x73\x74\x11\x94\xd0\xb8\x40" |
| 890 | "\x51\x58\x69\x23\x57\x04\xda\x29\xe0\x77\x36" |
| 891 | "\x40\xdc\x02\x4d\xdc\xbc\x7f\x63\xf4\x67\x31" |
| 892 | "\x7e\x98\x92\x36\x4d\xae\xd7\xb3\xfe\x63\xd3" |
| 893 | "\x27\x54\x95\xb0\x6c\x69\xb0\xbe\x6e\x7f\xfb" |
| 894 | "\x6c\xf2\x61\xc6\x7b\x3c\x75\x17\xfb\x5f\x47" |
| 895 | "\xc4\x7e\xd5\xbb\xcf\x16\xb0\xcf\x77\xd2\x7f" |
| 896 | "\x55\xda\xc5\x65\xdd\xce\x87\xd3\xf8\x60\x5a" |
| 897 | "\x4b\xed\x71\xe0\x42\xab\x83\xae\x61\x21\x78" |
| 898 | "\x70\xa2\x76\xc5\x23\x0e\x68\x1b\x7d\x08\xa0" |
| 899 | "\x61\x50\xc7\x1f\x7c\x5d\xfb\xa3\x0f\x66\x16" |
| 900 | "\x09\x0c\xa5\xa4\xa2\xce\x8c\x65\x23\x79\x36" |
| 901 | "\xa5\x58\x10\x93\x64\x42\xb9\x03\x29\x6c\xb6" |
| 902 | "\x1f\x7e\x2c\xf2\xee\x62\x45\xb9\x0e\x38\xff" |
| 903 | "\xec\xb8\xb9\x5d\x7b\x48\x9d\x7a\xb6\x0e\x4b" |
| 904 | "\xb8\xe3\x8b\x81\xe3\x29\x7e\xeb\x3e\xfe\x7c" |
| 905 | "\x45\xb2\xcf\x67\x53\x9e\x1d\x52\xb0\x9d\xc7" |
| 906 | "\x5d\xb3\xbe\x78\xff\xfe\xd3\x6f\x56\x56\xed" |
| 907 | "\xec\xe2\xfd\x3f\x01" |
| 908 | ), |
| 909 | |
| 910 | // packet 3 |
| 911 | sbuf( |
| 912 | s: "\xc1\x7e\x02\x73" |
| 913 | "\xec\x9a\xc1\x6e\xdc\x20\x10\x86\x5f\x25\xf2" |
| 914 | "\x7d\x24\x98\x1d\x83\xc9\xa9\xaf\x02\x36\x3e" |
| 915 | "\x45\x4d\xd4\x34\x95\x7a\xc8\xbb\xf7\xf7\xaa" |
| 916 | "\xf2\x42\xb5\xad\x41\xe9\x4a\xdd\x6a\x6e\x7b" |
| 917 | "\xd8\xf9\xc7\x06\xcc\xfc\x03\xdf\x1f\xa9\x96" |
| 918 | "\xb7\x97\xed\x5e\x76\xb8\x09\xd2\xf2\x0c\x1f" |
| 919 | "\xd7\x4c\xb4\x8c\x1f\x20\x5a\xf6\x8b\xfe\x22" |
| 920 | "\xf6\x56\x94\x4b\x13\xe1\x52\x3c\xc7\xad\xe1" |
| 921 | "\x93\x33\x6f\x10\xae\x0c\xde\x47\xa0\x9a\x7f" |
| 922 | "\xf2\xbe\xff\x25\xbe\xbe\x5e\x45\x5a\x36\x02" |
| 923 | "\x03\x5b\xc9\xb7\xbb\xbc\xf0\xc7\xe3\x63\x0a" |
| 924 | "\xf0\x27\x0c\x6d\x18\x31\x32\x0f\xf3\x56\x52" |
| 925 | "\x1f\x31\xd7\x5f\xb0\x51\xc3\x4e\xa2\x14\x85" |
| 926 | "\x4f\xdb\xe8\x10\x9c\x18\x3e\x06\x5e\xaf\xc7" |
| 927 | "\x6d\x0b\xfb\x71\xc9\x6b\x7c\x7b\xfa\xfa\x10" |
| 928 | "\x56\xb4\x53\x30\xfe\x24\x56\x98\xb0\x2b\x19" |
| 929 | "\x0a\x1c\x3c\xa1\xa8\x6e\x95\x34\xe0\x9b\x2a" |
| 930 | "\x65\x60\x9a\x27\x58\x2e\x6b\xa7\xbe\xf4\x45" |
| 931 | "\x5c\x95\x7e\x46\x23\xc5\x61\x74\xe4\xc3\x12" |
| 932 | "\x09\x2e\xc7\x11\xf6\xc0\x4c\x0b\x7a\x58\x9f" |
| 933 | "\xd2\x82\xdf\x4b\x29\x33\xf9\x33\x04\xc0\xa6" |
| 934 | "\x33\xfd\x25\xae\x4a\xcf\xe1\x34\x39\xc3\x33" |
| 935 | "\xa1\x95\x74\x84\x36\xdc\x52\xb2\x21\x51\xf0" |
| 936 | "\xd6\xc2\x46\xe7\x6c\xf3\x5c\xc8\x9c\xb0\x84" |
| 937 | "\x9d\x4c\xa3\xe3\xbe\xf4\x45\x5c\x95\xde\xa5" |
| 938 | "\x1c\xcd\x8a\x21\xb7\x12\x13\x89\x99\x84\x42" |
| 939 | "\x9e\x22\x39\x98\x1b\x19\x67\x4e\x4b\xf0\x95" |
| 940 | "\x8c\x20\x51\x40\x47\xdf\x9b\x7e\x8f\xab\xd2" |
| 941 | "\x8f\x28\x50\xc6\x4c\x4c\xc9\xb1\x25\x81\x99" |
| 942 | "\xa1\xed\x66\x84\x5c\xe4\x24\x78\x10\x4e\x59" |
| 943 | "\x4a\x19\xd4\x35\x73\x82\xdd\xea\x9c\xfb\x22" |
| 944 | "\xae\x7e\x7b\x37\xa1\x13\xf2\x91\x4c\x90\x13" |
| 945 | "\xd6\x9f\x77\x14\xd3\x6c\xb0\x14\x04\xb6\x0e" |
| 946 | "\x7b\x97\x49\xb5\x0c\xa3\x8f\x32\xe2\x7b\xdf" |
| 947 | "\xfe\x12\x57\xa5\x4f\x92\x38\x25\x83\xa5\x0e" |
| 948 | "\x1b\x47\x02\x37\x49\xe8\xeb\x85\x22\x2c\x50" |
| 949 | "\xf2\x28\xf9\x6b\x0e\x85\x0c\xf6\x24\xf6\x58" |
| 950 | "\xaa\x63\x5f\xf6\x4b\x58\x95\xdc\x66\xb1\x71" |
| 951 | "\x11\x64\x83\x7d\x20\x58\x87\x89\xe2\xcc\x81" |
| 952 | "\xe0\x5d\xe3\x92\x45\xd8\x2c\x5c\x81\x6c\xed" |
| 953 | "\x10\xdb\xb5\x9a\xf2\x57\x01\xb2\xdf\x54\x91" |
| 954 | "\x9b\x92\x72\xed\x08\x5a\x3f\xe2\x76\x07\x45" |
| 955 | "\xac\xa0\xd6\xb6\x02\xf6\xfc\xf9\xe9\xfb\x5d" |
| 956 | "\x16\xb1\xa1\xf4\xf6\xac\xd4\x9a\x52\x6b\x4a" |
| 957 | "\xad\x29\xb5\xa6\xd4\x9a\x52\x6b\x4a\xad\x29" |
| 958 | "\xb5\xa6\xd4\x9a\x52\x6b\x4a\xad\x29\xb5\xa6" |
| 959 | "\xd4\x9a\x52\x6b\x4a\xad\x29\xb5\xa6\xd4\x9a" |
| 960 | "\x52\x6b\x4a\xad\x29\xb5\xa6\xd4\x9a\x52\x6b" |
| 961 | "\x4a\xad\x29\xb5\xa6\xd4\x9a\x52\x6b\xff\x27" |
| 962 | "\xb5\x66\xab\xb5\x7f\x7e\xad\x96\x1b\xe2\xa1" |
| 963 | "\xe3\x7e\x63\x1b\xb0\x9f\x36\xf8\x98\x79\x18" |
| 964 | "\x3a\x3e\x92\x5d\xb8\x05\x27\x28\x84\x0f\x4f" |
| 965 | "\xab\x77\xe1\x16\x50\xa0\x10\x3e\xec\xd6\x2e" |
| 966 | "\xc2\x0d\xfc\xc5\xd0\xd1\x06\xec\xc2\x2d\x54" |
| 967 | "\x4d\x21\x7c\x78\xbc\xb0\x0b\xb7\x40\x0b\x85" |
| 968 | "\xf0\xe1\x89\xe0\x2e\xdc\x02\xe2\x14\xc2\x87" |
| 969 | "\xe7\xe9\xef\xcd\xf0\xe5\x2f\x14\xe2\x0f\x00" |
| 970 | ), |
| 971 | |
| 972 | // packet 4 |
| 973 | sbuf( |
| 974 | s: "\xc1\x45" |
| 975 | "\xec\xda\x31\x0d\x00\x00\x00\xc3\x20\xff\xae" |
| 976 | "\x67\xa1\xf7\x82\x0e\x68\x0b\x91\x1a\x53\x63" |
| 977 | "\x6a\x4c\x8d\xa9\x31\x35\xa6\xc6\xd4\x98\x1a" |
| 978 | "\x53\x63\x6a\x4c\x8d\xa9\x31\x35\xa6\xc6\xd4" |
| 979 | "\x98\x1a\x53\x63\x6a\x4c\x8d\xa9\x31\x35\xa6" |
| 980 | "\xc6\xd4\x98\x1a\x53\x63\x6a\x4c\x8d\xa9\xf1" |
| 981 | "\xa7\x1a\x0f" |
| 982 | ), |
| 983 | }; |
| 984 | |
| 985 | for (auto const packet : packets) { |
| 986 | net::write(s&: wss.next_layer(), buffers: packet); |
| 987 | multi_buffer buffer; |
| 988 | error_code ec; |
| 989 | wsc.async_read(buffer, handler: [&ec](error_code ec_, std::size_t) { ec = ec_; }); |
| 990 | ioc.run(); |
| 991 | ioc.restart(); |
| 992 | BEAST_EXPECTS(!ec, ec.message()); |
| 993 | } |
| 994 | } |
| 995 | |
| 996 | void |
| 997 | testMoveOnly() |
| 998 | { |
| 999 | net::io_context ioc; |
| 1000 | stream<test::stream> ws{ioc}; |
| 1001 | ws.async_read_some( |
| 1002 | buffers: net::mutable_buffer{}, |
| 1003 | handler: move_only_handler{}); |
| 1004 | } |
| 1005 | |
| 1006 | struct copyable_handler |
| 1007 | { |
| 1008 | template<class... Args> |
| 1009 | void |
| 1010 | operator()(Args&&...) const |
| 1011 | { |
| 1012 | } |
| 1013 | }; |
| 1014 | |
| 1015 | void |
| 1016 | testAsioHandlerInvoke() |
| 1017 | { |
| 1018 | // make sure things compile, also can set a |
| 1019 | // breakpoint in asio_handler_invoke to make sure |
| 1020 | // it is instantiated. |
| 1021 | { |
| 1022 | net::io_context ioc; |
| 1023 | net::strand< |
| 1024 | net::io_context::executor_type> s( |
| 1025 | ioc.get_executor()); |
| 1026 | stream<test::stream> ws{ioc}; |
| 1027 | flat_buffer b; |
| 1028 | ws.async_read(buffer&: b, handler: net::bind_executor( |
| 1029 | ex: s, t: copyable_handler{})); |
| 1030 | } |
| 1031 | } |
| 1032 | |
| 1033 | void |
| 1034 | run() override |
| 1035 | { |
| 1036 | testParseFrame(); |
| 1037 | testIssue802(); |
| 1038 | testIssue807(); |
| 1039 | testIssue954(); |
| 1040 | testIssue1630(); |
| 1041 | testIssueBF1(); |
| 1042 | testIssueBF2(); |
| 1043 | testMoveOnly(); |
| 1044 | testAsioHandlerInvoke(); |
| 1045 | } |
| 1046 | }; |
| 1047 | |
| 1048 | BEAST_DEFINE_TESTSUITE(beast,websocket,read3); |
| 1049 | |
| 1050 | } // websocket |
| 1051 | } // beast |
| 1052 | } // boost |
| 1053 | |