diff --git a/TODO.txt b/TODO.txt index 5de1e6c0..290ae4ce 100644 --- a/TODO.txt +++ b/TODO.txt @@ -49,10 +49,10 @@ HTTP: * Fix prepare() calling content_length() without init() * Use construct,destroy allocator routines in basic_headers * Complete allocator testing in basic_streambuf, basic_headers -* Fix http::async_write op, case 3 should break at the end. * Add tests for writer using the resume function / coros * Custom HTTP error codes for various situations * Make empty_body write-only, remove reader nested type * Add concepts WritableBody ReadableBody with type checks, check them in read and write functions * Branch prediction hints in parser +* Check basic_parser_v1 against rfc7230 for leading message whitespace diff --git a/examples/file_body.hpp b/examples/file_body.hpp index dbcd34f8..300444ac 100644 --- a/examples/file_body.hpp +++ b/examples/file_body.hpp @@ -1,21 +1,9 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== +// +// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// #ifndef BEAST_EXAMPLE_FILE_BODY_H_INCLUDED #define BEAST_EXAMPLE_FILE_BODY_H_INCLUDED diff --git a/examples/http_async_server.hpp b/examples/http_async_server.hpp index 9abeae9a..bcb088d1 100644 --- a/examples/http_async_server.hpp +++ b/examples/http_async_server.hpp @@ -1,21 +1,9 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== +// +// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// #ifndef BEAST_EXAMPLE_HTTP_ASYNC_SERVER_H_INCLUDED #define BEAST_EXAMPLE_HTTP_ASYNC_SERVER_H_INCLUDED diff --git a/examples/http_crawl.cpp b/examples/http_crawl.cpp index 2eb46aad..b995c201 100644 --- a/examples/http_crawl.cpp +++ b/examples/http_crawl.cpp @@ -1,21 +1,9 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== +// +// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// #include "http_stream.hpp" #include "urls_large_data.hpp" diff --git a/examples/http_server.cpp b/examples/http_server.cpp index 26aca29f..32d1b13b 100644 --- a/examples/http_server.cpp +++ b/examples/http_server.cpp @@ -1,21 +1,9 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== +// +// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// #include "http_async_server.hpp" #include "http_sync_server.hpp" diff --git a/examples/http_stream.hpp b/examples/http_stream.hpp index f02d9284..4bf275d2 100644 --- a/examples/http_stream.hpp +++ b/examples/http_stream.hpp @@ -1,21 +1,9 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== +// +// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// #ifndef BEAST_HTTP_STREAM_H_INCLUDED #define BEAST_HTTP_STREAM_H_INCLUDED diff --git a/examples/http_stream.ipp b/examples/http_stream.ipp index c9a23719..4e9df6e7 100644 --- a/examples/http_stream.ipp +++ b/examples/http_stream.ipp @@ -1,21 +1,9 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== +// +// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// #ifndef BEAST_HTTP_STREAM_IPP_INCLUDED #define BEAST_HTTP_STREAM_IPP_INCLUDED diff --git a/examples/http_sync_server.hpp b/examples/http_sync_server.hpp index d07c0d0c..af3f1d19 100644 --- a/examples/http_sync_server.hpp +++ b/examples/http_sync_server.hpp @@ -1,21 +1,9 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== +// +// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// #ifndef BEAST_EXAMPLE_HTTP_SYNC_SERVER_H_INCLUDED #define BEAST_EXAMPLE_HTTP_SYNC_SERVER_H_INCLUDED diff --git a/examples/urls_large_data.cpp b/examples/urls_large_data.cpp index 885754a7..819694f5 100644 --- a/examples/urls_large_data.cpp +++ b/examples/urls_large_data.cpp @@ -1,21 +1,9 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== +// +// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// #include "urls_large_data.hpp" diff --git a/examples/urls_large_data.hpp b/examples/urls_large_data.hpp index 5918d7c0..399644f0 100644 --- a/examples/urls_large_data.hpp +++ b/examples/urls_large_data.hpp @@ -1,21 +1,9 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== +// +// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// #ifndef URLS_LARGE_DATA_H_INCLUDED #define URLS_LARGE_DATA_H_INCLUDED diff --git a/extras/beast/test/fail_counter.hpp b/extras/beast/test/fail_counter.hpp new file mode 100644 index 00000000..06500461 --- /dev/null +++ b/extras/beast/test/fail_counter.hpp @@ -0,0 +1,69 @@ +// +// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#ifndef BEAST_TEST_FAIL_COUNTER_HPP +#define BEAST_TEST_FAIL_COUNTER_HPP + +#include + +namespace beast { +namespace test { + +/** A countdown to simulated failure. + + On the Nth operation, the class will fail with the specified + error code, or the default error code of invalid_argument. +*/ +class fail_counter +{ + std::size_t n_; + error_code ec_; + +public: + fail_counter(fail_counter&&) = default; + + /** Construct a counter. + + @param The 0-based index of the operation to fail on or after. + */ + explicit + fail_counter(std::size_t n = 0) + : n_(n) + , ec_(boost::system::errc::make_error_code( + boost::system::errc::errc_t::invalid_argument)) + { + } + + /// Throw an exception on the Nth failure + void + fail() + { + if(n_ > 0) + --n_; + if(! n_) + throw system_error{ec_}; + } + + /// Set an error code on the Nth failure + bool + fail(error_code& ec) + { + if(n_ > 0) + --n_; + if(! n_) + { + ec = ec_; + return true; + } + return false; + } +}; + +} // test +} // beast + +#endif diff --git a/extras/beast/test/fail_stream.hpp b/extras/beast/test/fail_stream.hpp index 44081f75..594bc709 100644 --- a/extras/beast/test/fail_stream.hpp +++ b/extras/beast/test/fail_stream.hpp @@ -1,21 +1,9 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== +// +// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// #ifndef BEAST_TEST_FAIL_STREAM_HPP #define BEAST_TEST_FAIL_STREAM_HPP @@ -25,6 +13,7 @@ #include #include #include +#include namespace beast { namespace test { @@ -37,32 +26,10 @@ namespace test { template class fail_stream { - error_code ec_; - std::size_t n_ = 0; + fail_counter* pfc_; + fail_counter fc_; NextLayer next_layer_; - void - fail() - { - if(n_ > 0) - --n_; - if(! n_) - throw system_error{ec_}; - } - - bool - fail(error_code& ec) - { - if(n_ > 0) - --n_; - if(! n_) - { - ec = ec_; - return true; - } - return false; - } - public: using next_layer_type = typename std::remove_reference::type; @@ -71,15 +38,24 @@ public: typename beast::detail::get_lowest_layer< next_layer_type>::type; - fail_stream(fail_stream&&) = default; - fail_stream& operator=(fail_stream&&) = default; + fail_stream(fail_stream&&) = delete; + fail_stream(fail_stream const&) = delete; + fail_stream& operator=(fail_stream&&) = delete; + fail_stream& operator=(fail_stream const&) = delete; template explicit fail_stream(std::size_t n, Args&&... args) - : ec_(boost::system::errc::make_error_code( - boost::system::errc::errc_t::invalid_argument)) - , n_(n) + : pfc_(&fc_) + , fc_(n) + , next_layer_(std::forward(args)...) + { + } + + template + explicit + fail_stream(fail_counter& fc, Args&&... args) + : pfc_(&fc) , next_layer_(std::forward(args)...) { } @@ -112,7 +88,7 @@ public: std::size_t read_some(MutableBufferSequence const& buffers) { - fail(); + pfc_->fail(); return next_layer_.read_some(buffers); } @@ -120,7 +96,7 @@ public: std::size_t read_some(MutableBufferSequence const& buffers, error_code& ec) { - if(fail(ec)) + if(pfc_->fail(ec)) return 0; return next_layer_.read_some(buffers, ec); } @@ -132,7 +108,7 @@ public: ReadHandler&& handler) { error_code ec; - if(fail(ec)) + if(pfc_->fail(ec)) { async_completion< ReadHandler, void(error_code, std::size_t) @@ -149,7 +125,7 @@ public: std::size_t write_some(ConstBufferSequence const& buffers) { - fail(); + pfc_->fail(); return next_layer_.write_some(buffers); } @@ -157,7 +133,7 @@ public: std::size_t write_some(ConstBufferSequence const& buffers, error_code& ec) { - if(fail(ec)) + if(pfc_->fail(ec)) return 0; return next_layer_.write_some(buffers, ec); } @@ -169,7 +145,7 @@ public: WriteHandler&& handler) { error_code ec; - if(fail(ec)) + if(pfc_->fail(ec)) { async_completion< WriteHandler, void(error_code, std::size_t) diff --git a/extras/beast/test/string_stream.hpp b/extras/beast/test/string_stream.hpp index 5f44af14..fcf77aae 100644 --- a/extras/beast/test/string_stream.hpp +++ b/extras/beast/test/string_stream.hpp @@ -60,7 +60,10 @@ public: { auto const n = boost::asio::buffer_copy( buffers, boost::asio::buffer(s_)); - s_.erase(0, n); + if(n > 0) + s_.erase(0, n); + else + ec = boost::asio::error::eof; return n; } @@ -72,11 +75,15 @@ public: { auto const n = boost::asio::buffer_copy( buffers, boost::asio::buffer(s_)); - s_.erase(0, n); + error_code ec; + if(n > 0) + s_.erase(0, n); + else + ec = boost::asio::error::eof; async_completion completion(handler); ios_.post(bind_handler( - completion.handler, error_code{}, n)); + completion.handler, ec, n)); return completion.result.get(); } diff --git a/extras/beast/test/yield_to.hpp b/extras/beast/test/yield_to.hpp index 0bd897ed..114efe7e 100644 --- a/extras/beast/test/yield_to.hpp +++ b/extras/beast/test/yield_to.hpp @@ -37,7 +37,7 @@ private: std::condition_variable cv_; bool running_ = false;; -protected: +public: /// The type of yield context passed to functions. using yield_context = boost::asio::yield_context; @@ -58,6 +58,13 @@ protected: thread_.join(); } + /// Return the `io_service` associated with the object + boost::asio::io_service& + get_io_service() + { + return ios_; + } + /** Run a function in a coroutine. This call will block until the coroutine terminates. diff --git a/extras/beast/unit_test/main.cpp b/extras/beast/unit_test/main.cpp index 8695cf06..8cdf803e 100644 --- a/extras/beast/unit_test/main.cpp +++ b/extras/beast/unit_test/main.cpp @@ -1,21 +1,9 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== +// +// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// #include #include diff --git a/include/beast/core/detail/buffer_cat.hpp b/include/beast/core/detail/buffer_cat.hpp index 388dd1ff..65ca2214 100644 --- a/include/beast/core/detail/buffer_cat.hpp +++ b/include/beast/core/detail/buffer_cat.hpp @@ -197,7 +197,6 @@ private: void move(C, const_iterator&&) { - return; } template @@ -216,7 +215,6 @@ private: void copy(C, const_iterator const&) { - return; } template diff --git a/include/beast/core/impl/streambuf_readstream.ipp b/include/beast/core/impl/streambuf_readstream.ipp index f65f85f7..8a0506d6 100644 --- a/include/beast/core/impl/streambuf_readstream.ipp +++ b/include/beast/core/impl/streambuf_readstream.ipp @@ -110,7 +110,7 @@ read_some_op::operator()( if(d.srs.sb_.size() == 0) { d.state = - d.srs.size_ > 0 ? 2 : 1; + d.srs.capacity_ > 0 ? 2 : 1; break; } d.state = 4; @@ -129,7 +129,7 @@ read_some_op::operator()( // read d.state = 3; d.srs.next_layer_.async_read_some( - d.srs.sb_.prepare(d.srs.size_), + d.srs.sb_.prepare(d.srs.capacity_), std::move(*this)); return; @@ -217,14 +217,12 @@ read_some(MutableBufferSequence const& buffers, "MutableBufferSequence requirements not met"); using boost::asio::buffer_size; using boost::asio::buffer_copy; - if(buffer_size(buffers) == 0) - return 0; - if(size_ == 0) - return next_layer_.read_some(buffers, ec); if(sb_.size() == 0) { + if(capacity_ == 0) + return next_layer_.read_some(buffers, ec); sb_.commit(next_layer_.read_some( - sb_.prepare(size_), ec)); + sb_.prepare(capacity_), ec)); if(ec) return 0; } diff --git a/include/beast/core/static_string.hpp b/include/beast/core/static_string.hpp index dbf2158a..911abcce 100644 --- a/include/beast/core/static_string.hpp +++ b/include/beast/core/static_string.hpp @@ -1,21 +1,9 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== +// +// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// #ifndef BEAST_WEBSOCKET_STATIC_STRING_HPP #define BEAST_WEBSOCKET_STATIC_STRING_HPP diff --git a/include/beast/core/streambuf_readstream.hpp b/include/beast/core/streambuf_readstream.hpp index 7557fcc3..383f9511 100644 --- a/include/beast/core/streambuf_readstream.hpp +++ b/include/beast/core/streambuf_readstream.hpp @@ -99,7 +99,7 @@ class streambuf_readstream class read_some_op; Streambuf sb_; - std::size_t size_ = 0; + std::size_t capacity_ = 0; Stream next_layer_; public: @@ -211,9 +211,9 @@ public: than the amount of data in the buffer, no bytes are discarded. */ void - reserve(std::size_t size) + capacity(std::size_t size) { - size_ = size; + capacity_ = size; } /// Write the given data to the stream. Returns the number of bytes written. diff --git a/include/beast/http/detail/chunk_encode.hpp b/include/beast/http/detail/chunk_encode.hpp index 07106822..db38ee88 100644 --- a/include/beast/http/detail/chunk_encode.hpp +++ b/include/beast/http/detail/chunk_encode.hpp @@ -8,7 +8,9 @@ #ifndef BEAST_HTTP_DETAIL_CHUNK_ENCODE_HPP #define BEAST_HTTP_DETAIL_CHUNK_ENCODE_HPP +#include #include +#include #include #include #include @@ -20,244 +22,94 @@ namespace beast { namespace http { namespace detail { -template -class chunk_encoded_buffers +class chunk_encode_text { -private: - using const_buffer = boost::asio::const_buffer; - - Buffers buffers_; - const_buffer head_; - const_buffer tail_; + boost::asio::const_buffer cb_; // Storage for the longest hex string we might need, plus delimiters. - std::array data_; + std::array buf_; + + template + static + OutIter + to_hex(OutIter last, std::size_t n) + { + if(n == 0) + { + *--last = '0'; + return last; + } + while(n) + { + *--last = "0123456789abcdef"[n&0xf]; + n>>=4; + } + return last; + } public: using value_type = boost::asio::const_buffer; - class const_iterator; + using const_iterator = value_type const*; - chunk_encoded_buffers() = delete; - chunk_encoded_buffers (chunk_encoded_buffers const&) = default; - chunk_encoded_buffers& operator= (chunk_encoded_buffers const&) = default; + chunk_encode_text(chunk_encode_text const& other) + { + auto const n = + boost::asio::buffer_size(other.cb_); + buf_ = other.buf_; + cb_ = boost::asio::const_buffer( + &buf_[buf_.size() - n], n); + } - chunk_encoded_buffers (Buffers const& buffers, bool final_chunk); + explicit + chunk_encode_text(std::size_t n) + { + buf_[buf_.size() - 2] = '\r'; + buf_[buf_.size() - 1] = '\n'; + auto it = to_hex(buf_.end() - 2, n); + cb_ = boost::asio::const_buffer{&*it, + static_cast( + std::distance(it, buf_.end()))}; + } const_iterator begin() const { - return const_iterator(*this, false); + return &cb_; } const_iterator end() const { - return const_iterator(*this, true); + return begin() + 1; } - -private: - // Unchecked conversion of unsigned to hex string - template - static - typename std::enable_if< - std::is_unsigned::value, OutIter>::type - to_hex(OutIter const first, OutIter const last, Unsigned n); }; -template -class chunk_encoded_buffers::const_iterator - : public std::iterator -{ -private: - using iterator = typename Buffers::const_iterator; - enum class Where { head, input, end }; - chunk_encoded_buffers const* buffers_; - Where where_; - iterator iter_; +/** Returns a chunk-encoded ConstBufferSequence. -public: - const_iterator(); - const_iterator (const_iterator const&) = default; - const_iterator& operator= (const_iterator const&) = default; - bool operator== (const_iterator const& other) const; - bool operator!= (const_iterator const& other) const; - const_iterator& operator++(); - const_iterator& operator--(); - const_iterator operator++(int) const; - const_iterator operator--(int) const; - const_buffer operator*() const; - -private: - friend class chunk_encoded_buffers; - const_iterator(chunk_encoded_buffers const& buffers, bool past_the_end); -}; - -//------------------------------------------------------------------------------ - -template -chunk_encoded_buffers::chunk_encoded_buffers ( - Buffers const& buffers, bool final_chunk) - : buffers_(buffers) -{ - auto const size = boost::asio::buffer_size(buffers); - data_[data_.size() - 2] = '\r'; - data_[data_.size() - 1] = '\n'; - auto pos = to_hex(data_.begin(), data_.end() - 2, size); - head_ = const_buffer(&*pos, - std::distance(pos, data_.end())); - if (size > 0 && final_chunk) - tail_ = const_buffer("\r\n0\r\n\r\n", 7); - else - tail_ = const_buffer("\r\n", 2); -} - -template -template -typename std::enable_if< - std::is_unsigned::value, OutIter>::type -chunk_encoded_buffers::to_hex( - OutIter const first, OutIter const last, Unsigned n) -{ - assert(first != last); - OutIter iter = last; - if(n == 0) - { - *--iter = '0'; - return iter; - } - while(n) - { - assert(iter != first); - *--iter = "0123456789abcdef"[n&0xf]; - n>>=4; - } - return iter; -} - -template -chunk_encoded_buffers::const_iterator::const_iterator() - : buffers_(nullptr) - , where_(Where::end) -{ -} - -template -bool -chunk_encoded_buffers::const_iterator::operator==( - const_iterator const& other) const -{ - return buffers_ == other.buffers_ && - where_ == other.where_ && iter_ == other.iter_; -} - -template -bool -chunk_encoded_buffers::const_iterator::operator!=( - const_iterator const& other) const -{ - return buffers_ != other.buffers_ || - where_ != other.where_ || iter_ != other.iter_; -} - -template -auto -chunk_encoded_buffers::const_iterator::operator++() -> - const_iterator& -{ - assert(buffers_); - assert(where_ != Where::end); - if (where_ == Where::head) - where_ = Where::input; - else if (iter_ != buffers_->buffers_.end()) - ++iter_; - else - where_ = Where::end; - return *this; -} - -template -auto -chunk_encoded_buffers::const_iterator::operator--() -> - const_iterator& -{ - assert(buffers_); - assert(where_ != Where::head); - if (where_ == Where::end) - where_ = Where::input; - else if (iter_ != buffers_->buffers_.begin()) - --iter_; - else - where_ = Where::head; - return *this; -} - -template -auto -chunk_encoded_buffers::const_iterator::operator++(int) const -> - const_iterator -{ - auto iter = *this; - ++iter; - return iter; -} - -template -auto -chunk_encoded_buffers::const_iterator::operator--(int) const -> - const_iterator -{ - auto iter = *this; - --iter; - return iter; -} - -template -auto -chunk_encoded_buffers::const_iterator::operator*() const -> - const_buffer -{ - assert(buffers_); - assert(where_ != Where::end); - if (where_ == Where::head) - return buffers_->head_; - if (iter_ != buffers_->buffers_.end()) - return *iter_; - return buffers_->tail_; -} - -template -chunk_encoded_buffers::const_iterator::const_iterator( - chunk_encoded_buffers const& buffers, bool past_the_end) - : buffers_(&buffers) - , where_(past_the_end ? Where::end : Where::head) - , iter_(past_the_end ? buffers_->buffers_.end() : - buffers_->buffers_.begin()) -{ -} - -/* Returns a chunk-encoded BufferSequence. - - See: - http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1 + This returns a buffer sequence representing the + first chunk of a chunked transfer coded body. @param buffers The input buffer sequence. - @param final_chunk `true` If this should include a final-chunk. - @return A chunk-encoded ConstBufferSequence representing the input. + + @see rfc7230 section 4.1.3 */ template #if GENERATING_DOCS implementation_defined #else -detail::chunk_encoded_buffers +beast::detail::buffer_cat_helper #endif -chunk_encode(ConstBufferSequence const& buffers, - bool final_chunk = false) +chunk_encode(ConstBufferSequence const& buffers) { - return detail::chunk_encoded_buffers< - ConstBufferSequence>{buffers, final_chunk}; + using boost::asio::buffer_size; + return buffer_cat( + chunk_encode_text{buffer_size(buffers)}, + buffers, + boost::asio::const_buffers_1{"\r\n", 2}); } /// Returns a chunked encoding final chunk. diff --git a/include/beast/http/impl/write.ipp b/include/beast/http/impl/write.ipp index 9af2a0ef..72408558 100644 --- a/include/beast/http/impl/write.ipp +++ b/include/beast/http/impl/write.ipp @@ -148,13 +148,13 @@ class write_op } }; - class writef0 + class writef0_lambda { write_op& self_; public: explicit - writef0(write_op& self) + writef0_lambda(write_op& self) : self_(self) { } @@ -176,13 +176,13 @@ class write_op } }; - class writef + class writef_lambda { write_op& self_; public: explicit - writef(write_op& self) + writef_lambda(write_op& self) : self_(self) { } @@ -300,7 +300,7 @@ operator()(error_code ec, std::size_t, bool again) case 1: { auto const result = d.wp.w( - std::move(d.copy), ec, writef0{*this}); + std::move(d.copy), ec, writef0_lambda{*this}); if(ec) { // call handler @@ -331,7 +331,7 @@ operator()(error_code ec, std::size_t, bool again) case 3: { auto const result = d.wp.w( - std::move(d.copy), ec, writef{*this}); + std::move(d.copy), ec, writef_lambda{*this}); if(ec) { // call handler @@ -378,7 +378,7 @@ operator()(error_code ec, std::size_t, bool again) } template -class writef0_write +class writef0_lambda { Streambuf const& sb_; SyncWriteStream& stream_; @@ -386,7 +386,7 @@ class writef0_write error_code& ec_; public: - writef0_write(SyncWriteStream& stream, + writef0_lambda(SyncWriteStream& stream, Streambuf const& sb, bool chunked, error_code& ec) : sb_(sb) , stream_(stream) @@ -409,14 +409,14 @@ public: }; template -class writef_write +class writef_lambda { SyncWriteStream& stream_; bool chunked_; error_code& ec_; public: - writef_write(SyncWriteStream& stream, + writef_lambda(SyncWriteStream& stream, bool chunked, error_code& ec) : stream_(stream) , chunked_(chunked) @@ -478,45 +478,43 @@ write(SyncWriteStream& stream, cv.notify_one(); }}; auto copy = resume; - for(;;) + boost::tribool result; + result = wp.w(std::move(copy), ec, + detail::writef0_lambda{ + stream, wp.sb, wp.chunked, ec}); + if(ec) + return; + if(boost::indeterminate(result)) { + copy = resume; { - auto result = wp.w(std::move(copy), ec, - detail::writef0_write{ - stream, wp.sb, wp.chunked, ec}); - if(ec) - return; - if(result) - break; - if(boost::indeterminate(result)) - { - boost::asio::write(stream, wp.sb.data(), ec); - if(ec) - return; - wp.sb.consume(wp.sb.size()); - copy = resume; - std::unique_lock lock(m); - cv.wait(lock, [&]{ return ready; }); - ready = false; - } + std::unique_lock lock(m); + cv.wait(lock, [&]{ return ready; }); + ready = false; } - wp.sb.consume(wp.sb.size()); + boost::asio::write(stream, wp.sb.data(), ec); + if(ec) + return; + result = false; + } + wp.sb.consume(wp.sb.size()); + if(! result) + { for(;;) { - auto result = wp.w(std::move(copy), ec, - detail::writef_write{ + result = wp.w(std::move(copy), ec, + detail::writef_lambda{ stream, wp.chunked, ec}); if(ec) return; if(result) break; - if(boost::indeterminate(result)) - { - copy = resume; - std::unique_lock lock(m); - cv.wait(lock, [&]{ return ready; }); - ready = false; - } + if(! result) + continue; + copy = resume; + std::unique_lock lock(m); + cv.wait(lock, [&]{ return ready; }); + ready = false; } } if(wp.chunked) diff --git a/include/beast/http/parse_error.hpp b/include/beast/http/parse_error.hpp index 71e1831a..c60d3a7c 100644 --- a/include/beast/http/parse_error.hpp +++ b/include/beast/http/parse_error.hpp @@ -34,7 +34,9 @@ enum class parse_error invalid_chunk_size, - short_read + short_read, + + general }; class parse_error_category : public boost::system::error_category @@ -97,7 +99,7 @@ public: return "unexpected end of data"; default: - return "beast::http::parser error"; + return "parse error"; } } diff --git a/include/beast/websocket.hpp b/include/beast/websocket.hpp index 84622e79..d6eac448 100644 --- a/include/beast/websocket.hpp +++ b/include/beast/websocket.hpp @@ -1,21 +1,9 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== +// +// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// #ifndef BEAST_WEBSOCKET_HPP #define BEAST_WEBSOCKET_HPP diff --git a/include/beast/websocket/error.hpp b/include/beast/websocket/error.hpp index d2265833..9af24b1c 100644 --- a/include/beast/websocket/error.hpp +++ b/include/beast/websocket/error.hpp @@ -44,7 +44,10 @@ enum class error request_invalid, /// Upgrade request denied - request_denied + request_denied, + + /// General WebSocket error + general }; #if ! GENERATING_DOCS diff --git a/include/beast/websocket/impl/stream.ipp b/include/beast/websocket/impl/stream.ipp index 7b733033..ddc3f7aa 100644 --- a/include/beast/websocket/impl/stream.ipp +++ b/include/beast/websocket/impl/stream.ipp @@ -861,6 +861,7 @@ build_response(http::request_v1 const& req) res.version = req.version; res.body = text; // VFALCO TODO respect keep-alive here + prepare(res); return res; }; if(req.version < 11) diff --git a/include/beast/websocket/stream.hpp b/include/beast/websocket/stream.hpp index a868a88f..76bf03f1 100644 --- a/include/beast/websocket/stream.hpp +++ b/include/beast/websocket/stream.hpp @@ -202,7 +202,7 @@ public: void set_option(read_buffer_size const& o) { - stream_.reserve(o.value); + stream_.capacity(o.value); } /// Set the maximum incoming message size allowed @@ -217,7 +217,7 @@ public: set_option(write_buffer_size const& o) { wr_buf_size_ = std::max(o.value, 1024); - stream_.reserve(o.value); + stream_.capacity(o.value); } /** Get the io_service associated with the stream. diff --git a/include/beast/websocket/teardown.hpp b/include/beast/websocket/teardown.hpp index 5eab8ca0..ecb6dba3 100644 --- a/include/beast/websocket/teardown.hpp +++ b/include/beast/websocket/teardown.hpp @@ -1,21 +1,9 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== +// +// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// #ifndef BEAST_WEBSOCKET_TEARDOWN_HPP #define BEAST_WEBSOCKET_TEARDOWN_HPP diff --git a/scripts/run-with-gdb.sh b/scripts/run-with-gdb.sh index c422ea51..f7ff0bc7 100755 --- a/scripts/run-with-gdb.sh +++ b/scripts/run-with-gdb.sh @@ -3,6 +3,7 @@ set -e gdb --silent \ --batch \ --return-child-result \ + -ex="set print thread-events off" \ -ex=run \ -ex="thread apply all bt full" \ --args $@ diff --git a/test/Jamfile b/test/Jamfile index 0c597c81..f44e7c61 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -59,6 +59,7 @@ unit-test http-tests : http/string_body.cpp http/type_check.cpp http/write.cpp + http/detail/chunk_encode.cpp ; unit-test bench-tests : diff --git a/test/core/buffer_cat.cpp b/test/core/buffer_cat.cpp index 7cb6b54a..25d7490a 100644 --- a/test/core/buffer_cat.cpp +++ b/test/core/buffer_cat.cpp @@ -81,7 +81,15 @@ public: const_buffer{buf+4, 2}, const_buffer{buf+6, 3}}}; auto bs = buffer_cat(b1, b2); - + for(int n = 0; + n <= std::distance(bs.begin(), bs.end()); ++n) + { + auto it = std::next(bs.begin(), n); + decltype(it) it2(std::move(it)); + it = std::move(it2); + auto pit = ⁢ + it = std::move(*pit); + } try { std::size_t n = 0; diff --git a/test/core/streambuf_readstream.cpp b/test/core/streambuf_readstream.cpp index b7d17fab..9481cb51 100644 --- a/test/core/streambuf_readstream.cpp +++ b/test/core/streambuf_readstream.cpp @@ -9,15 +9,22 @@ #include #include +#include +#include +#include #include #include namespace beast { -class streambuf_readstream_test : public beast::unit_test::suite +class streambuf_readstream_test + : public unit_test::suite + , public test::enable_yield_to { + using self = streambuf_readstream_test; + public: - void testSpecial() + void testSpecialMembers() { using socket_type = boost::asio::ip::tcp::socket; boost::asio::io_service ios; @@ -33,12 +40,100 @@ public: streambuf_readstream srs(sock); streambuf_readstream srs2(std::move(srs)); } - pass(); + } + + void testRead(yield_context do_yield) + { + using boost::asio::buffer; + using boost::asio::buffer_copy; + static std::size_t constexpr limit = 100; + std::size_t n; + std::string s; + s.resize(13); + + for(n = 0; n < limit; ++n) + { + test::fail_stream< + test::string_stream> fs(n, ios_, ", world!"); + streambuf_readstream< + decltype(fs)&, streambuf> srs(fs); + srs.buffer().commit(buffer_copy( + srs.buffer().prepare(5), buffer("Hello", 5))); + boost::system::error_code ec; + boost::asio::read(srs, buffer(&s[0], s.size()), ec); + if(! ec) + { + expect(s == "Hello, world!"); + break; + } + } + expect(n < limit); + + for(n = 0; n < limit; ++n) + { + test::fail_stream< + test::string_stream> fs(n, ios_, ", world!"); + streambuf_readstream< + decltype(fs)&, streambuf> srs(fs); + srs.capacity(3); + srs.buffer().commit(buffer_copy( + srs.buffer().prepare(5), buffer("Hello", 5))); + boost::system::error_code ec; + boost::asio::read(srs, buffer(&s[0], s.size()), ec); + if(! ec) + { + expect(s == "Hello, world!"); + break; + } + } + expect(n < limit); + + for(n = 0; n < limit; ++n) + { + test::fail_stream< + test::string_stream> fs(n, ios_, ", world!"); + streambuf_readstream< + decltype(fs)&, streambuf> srs(fs); + srs.buffer().commit(buffer_copy( + srs.buffer().prepare(5), buffer("Hello", 5))); + boost::system::error_code ec; + boost::asio::async_read( + srs, buffer(&s[0], s.size()), do_yield[ec]); + if(! ec) + { + expect(s == "Hello, world!"); + break; + } + } + expect(n < limit); + + for(n = 0; n < limit; ++n) + { + test::fail_stream< + test::string_stream> fs(n, ios_, ", world!"); + streambuf_readstream< + decltype(fs)&, streambuf> srs(fs); + srs.capacity(3); + srs.buffer().commit(buffer_copy( + srs.buffer().prepare(5), buffer("Hello", 5))); + boost::system::error_code ec; + boost::asio::async_read( + srs, buffer(&s[0], s.size()), do_yield[ec]); + if(! ec) + { + expect(s == "Hello, world!"); + break; + } + } + expect(n < limit); } void run() override { - testSpecial(); + testSpecialMembers(); + + yield_to(std::bind(&self::testRead, + this, std::placeholders::_1)); } }; diff --git a/test/http/CMakeLists.txt b/test/http/CMakeLists.txt index ccbacbbe..420bf509 100644 --- a/test/http/CMakeLists.txt +++ b/test/http/CMakeLists.txt @@ -26,6 +26,7 @@ add_executable (http-tests string_body.cpp type_check.cpp write.cpp + detail/chunk_encode.cpp ) if (NOT WIN32) diff --git a/test/http/basic_headers.cpp b/test/http/basic_headers.cpp index cfde613c..09f8c4a3 100644 --- a/test/http/basic_headers.cpp +++ b/test/http/basic_headers.cpp @@ -58,5 +58,5 @@ public: BEAST_DEFINE_TESTSUITE(basic_headers,http,beast); -} // asio +} // http } // beast diff --git a/test/http/basic_parser_v1.cpp b/test/http/basic_parser_v1.cpp index 29cf7173..c10fcf47 100644 --- a/test/http/basic_parser_v1.cpp +++ b/test/http/basic_parser_v1.cpp @@ -573,11 +573,14 @@ public: parse_ev("GET / HTTP/1.1\r\nf :", parse_error::bad_field); } - void testCorrupt() + void testInvalidMatrix() { using boost::asio::buffer; + static std::size_t constexpr limit = 200; std::string s; - for(std::size_t n = 0;;++n) + std::size_t n; + + for(n = 0; n < limit; ++n) { // Create a request and set one octet to an invalid char s = @@ -607,6 +610,41 @@ public: expect(ec); } } + expect(n < limit); + + for(n = 0; n < limit; ++n) + { + // Create a response and set one octet to an invalid char + s = + "HTTP/1.1 200 OK\r\n" + "Server: test\r\n" + "Transer-Encoding: chunked\r\n" + "\r\n" + "10\r\n" + "****************\r\n" + "0\r\n\r\n"; + auto const len = s.size(); + if(n >= s.size()) + { + pass(); + break; + } + s[n] = 0; + for(std::size_t m = 1; m < len - 1; ++m) + { + null_parser p; + error_code ec; + p.write(buffer(s.data(), m), ec); + if(ec) + { + pass(); + continue; + } + p.write(buffer(s.data() + m, len - m), ec); + expect(ec); + } + } + expect(n < limit); } void @@ -758,7 +796,7 @@ public: testFlags(); testUpgrade(); testBad(); - testCorrupt(); + testInvalidMatrix(); testRandomReq(100); testRandomResp(100); testBody(); diff --git a/test/http/detail/chunk_encode.cpp b/test/http/detail/chunk_encode.cpp new file mode 100644 index 00000000..a952df79 --- /dev/null +++ b/test/http/detail/chunk_encode.cpp @@ -0,0 +1,132 @@ +// +// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include +#include + +namespace beast { +namespace http { +namespace detail { + +class chunk_encode_test : public beast::unit_test::suite +{ +public: + struct final_chunk + { + std::string s; + + final_chunk() = default; + + explicit + final_chunk(std::string s_) + : s(std::move(s_)) + { + } + }; + + static + void + encode1(std::string& s, final_chunk const& fc) + { + using boost::asio::buffer; + if(! fc.s.empty()) + s.append(to_string( + chunk_encode(buffer(fc.s.data(), fc.s.size())))); + s.append(to_string(chunk_encode_final())); + } + + static + void + encode1(std::string& s, std::string const& piece) + { + using boost::asio::buffer; + s.append(to_string( + chunk_encode(buffer(piece.data(), piece.size())))); + } + + static + inline + void + encode(std::string&) + { + } + + template + static + void + encode(std::string& s, Arg const& arg, Args const&... args) + { + encode1(s, arg); + encode(s, args...); + } + + template + void + check(std::string const& answer, Args const&... args) + { + std::string s; + encode(s, args...); + expect(s == answer); + } + + void run() override + { + check( + "0\r\n\r\n" + "0\r\n\r\n", + "", final_chunk{}); + + check( + "1\r\n" + "*\r\n" + "0\r\n\r\n", + final_chunk("*")); + + check( + "2\r\n" + "**\r\n" + "0\r\n\r\n", + final_chunk("**")); + + check( + "1\r\n" + "*\r\n" + "1\r\n" + "*\r\n" + "0\r\n\r\n", + "*", final_chunk("*")); + + check( + "5\r\n" + "*****\r\n" + "7\r\n" + "*******\r\n" + "0\r\n\r\n", + "*****", final_chunk("*******")); + + check( + "1\r\n" + "*\r\n" + "1\r\n" + "*\r\n" + "0\r\n\r\n", + "*", "*", final_chunk{}); + + check( + "4\r\n" + "****\r\n" + "0\r\n\r\n", + "****", final_chunk{}); + } +}; + +BEAST_DEFINE_TESTSUITE(chunk_encode,http,beast); + +} // detail +} // http +} // beast diff --git a/test/http/parse_error.cpp b/test/http/parse_error.cpp index 235d9abe..69a46dd7 100644 --- a/test/http/parse_error.cpp +++ b/test/http/parse_error.cpp @@ -47,6 +47,7 @@ public: check("http", parse_error::bad_on_headers_rv); check("http", parse_error::invalid_chunk_size); check("http", parse_error::short_read); + check("http", parse_error::general); } }; diff --git a/test/http/read.cpp b/test/http/read.cpp index e8e07e2e..c53329f3 100644 --- a/test/http/read.cpp +++ b/test/http/read.cpp @@ -27,7 +27,8 @@ public: { static std::size_t constexpr limit = 100; std::size_t n; - for(n = 1; n < limit; ++n) + + for(n = 0; n < limit; ++n) { streambuf sb; test::fail_stream fs(n, ios_, @@ -48,7 +49,8 @@ public: } } expect(n < limit); - for(n = 1; n < limit; ++n) + + for(n = 0; n < limit; ++n) { streambuf sb; test::fail_stream fs(n, ios_, @@ -65,11 +67,8 @@ public: break; } expect(n < limit); - ios_.post( - [&]{ - n = 1; - }); - for(n = 1; n < limit; ++n) + + for(n = 0; n < limit; ++n) { streambuf sb; test::fail_stream fs(n, ios_, diff --git a/test/http/write.cpp b/test/http/write.cpp index 00a47f1b..883e1903 100644 --- a/test/http/write.cpp +++ b/test/http/write.cpp @@ -16,20 +16,40 @@ #include #include #include +#include +#include #include #include +#include #include namespace beast { namespace http { -class write_test : public beast::unit_test::suite +class write_test + : public beast::unit_test::suite + , public test::enable_yield_to { public: - struct string_SyncStream + class string_write_stream { + boost::asio::io_service& ios_; + + public: std::string str; - + + explicit + string_write_stream(boost::asio::io_service& ios) + : ios_(ios) + { + } + + boost::asio::io_service& + get_io_service() + { + return ios_; + } + template std::size_t write_some(ConstBufferSequence const& buffers) @@ -42,7 +62,8 @@ public: } template - std::size_t write_some( + std::size_t + write_some( ConstBufferSequence const& buffers, error_code& ec) { auto const n = buffer_size(buffers); @@ -54,9 +75,25 @@ public: buffer_size(buffer)); return n; } + + template + typename async_completion< + WriteHandler, void(error_code)>::result_type + async_write_some(ConstBufferSequence const& buffers, + WriteHandler&& handler) + { + error_code ec; + auto const bytes_transferred = write_some(buffers, ec); + async_completion< + WriteHandler, void(error_code, std::size_t) + > completion(handler); + get_io_service().post( + bind_handler(completion.handler, ec, bytes_transferred)); + return completion.result.get(); + } }; - struct fail_body + struct unsized_body { using value_type = std::string; @@ -64,6 +101,70 @@ public: { value_type const& body_; + public: + template + explicit + writer(message const& msg) + : body_(msg.body) + { + } + + void + init(error_code& ec) + { + } + + template + boost::tribool + operator()(resume_context&&, error_code&, Write&& write) + { + write(boost::asio::buffer(body_)); + return true; + } + }; + }; + + struct fail_body + { + class writer; + + class value_type + { + friend class writer; + + std::string s_; + test::fail_counter& fc_; + boost::asio::io_service& ios_; + + public: + value_type(test::fail_counter& fc, + boost::asio::io_service& ios) + : fc_(fc) + , ios_(ios) + { + } + + boost::asio::io_service& + get_io_service() const + { + return ios_; + } + + value_type& + operator=(std::string s) + { + s_ = std::move(s); + return *this; + } + }; + + class writer + { + std::size_t n_ = 0; + value_type const& body_; + bool suspend_ = false; + enable_yield_to yt_; + public: template explicit @@ -75,48 +176,44 @@ public: void init(error_code& ec) { - ec = boost::system::errc::make_error_code( - boost::system::errc::errc_t::invalid_argument); + body_.fc_.fail(ec); } + class do_resume + { + resume_context rc_; + + public: + explicit + do_resume(resume_context&& rc) + : rc_(std::move(rc)) + { + } + + void + operator()() + { + rc_(); + } + }; + template boost::tribool - operator()(resume_context&&, error_code&, Write&& write) + operator()(resume_context&& rc, error_code& ec, Write&& write) { - write(boost::asio::buffer(body_)); - return true; - } - }; - }; - - struct test_body - { - using value_type = std::string; - - class writer - { - std::size_t pos_ = 0; - value_type const& body_; - - public: - template - explicit - writer(message const& msg) - : body_(msg.body) - { - } - - void - init(error_code& ec) - { - } - - template - boost::tribool - operator()(resume_context&&, error_code&, Write&& write) - { - write(boost::asio::buffer(body_)); - return true; + if(body_.fc_.fail(ec)) + return false; + suspend_ = ! suspend_; + if(suspend_) + { + yt_.get_io_service().post(do_resume{std::move(rc)}); + return boost::indeterminate; + } + if(n_ >= body_.s_.size()) + return true; + write(boost::asio::buffer(body_.s_.data() + n_, 1)); + ++n_; + return n_ == body_.s_.size(); } }; }; @@ -125,13 +222,228 @@ public: std::string str(message_v1 const& m) { - string_SyncStream ss; + string_write_stream ss(ios_); write(ss, m); return ss.str; } void - testWrite() + testAsyncWrite(yield_context do_yield) + { + { + message_v1 m; + m.version = 10; + m.status = 200; + m.reason = "OK"; + m.headers.insert("Server", "test"); + m.headers.insert("Content-Length", "5"); + m.body = "*****"; + error_code ec; + string_write_stream ss(ios_); + async_write(ss, m, do_yield[ec]); + if(expect(! ec, ec.message())) + expect(ss.str == + "HTTP/1.0 200 OK\r\n" + "Server: test\r\n" + "Content-Length: 5\r\n" + "\r\n" + "*****"); + } + { + message_v1 m; + m.version = 11; + m.status = 200; + m.reason = "OK"; + m.headers.insert("Server", "test"); + m.headers.insert("Transfer-Encoding", "chunked"); + m.body = "*****"; + error_code ec; + string_write_stream ss(ios_); + async_write(ss, m, do_yield[ec]); + if(expect(! ec, ec.message())) + expect(ss.str == + "HTTP/1.1 200 OK\r\n" + "Server: test\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + "5\r\n" + "*****\r\n" + "0\r\n\r\n"); + } + } + + void + testFailures(yield_context do_yield) + { + static std::size_t constexpr limit = 100; + std::size_t n; + + for(n = 0; n < limit; ++n) + { + test::fail_counter fc(n); + test::fail_stream< + string_write_stream> fs(fc, ios_); + message_v1 m( + std::piecewise_construct, + std::forward_as_tuple(fc, ios_)); + m.method = "GET"; + m.url = "/"; + m.version = 10; + m.headers.insert("User-Agent", "test"); + m.headers.insert("Content-Length", "5"); + m.body = "*****"; + try + { + write(fs, m); + expect(fs.next_layer().str == + "GET / HTTP/1.0\r\n" + "User-Agent: test\r\n" + "Content-Length: 5\r\n" + "\r\n" + "*****" + ); + pass(); + break; + } + catch(std::exception const&) + { + } + } + expect(n < limit); + + for(n = 0; n < limit; ++n) + { + test::fail_counter fc(n); + test::fail_stream< + string_write_stream> fs(fc, ios_); + message_v1 m( + std::piecewise_construct, + std::forward_as_tuple(fc, ios_)); + m.method = "GET"; + m.url = "/"; + m.version = 10; + m.headers.insert("User-Agent", "test"); + m.headers.insert("Transfer-Encoding", "chunked"); + m.body = "*****"; + error_code ec; + write(fs, m, ec); + if(ec == boost::asio::error::eof) + { + expect(fs.next_layer().str == + "GET / HTTP/1.0\r\n" + "User-Agent: test\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + "1\r\n*\r\n" + "1\r\n*\r\n" + "1\r\n*\r\n" + "1\r\n*\r\n" + "1\r\n*\r\n" + "0\r\n\r\n" + ); + break; + } + } + expect(n < limit); + + for(n = 0; n < limit; ++n) + { + test::fail_counter fc(n); + test::fail_stream< + string_write_stream> fs(fc, ios_); + message_v1 m( + std::piecewise_construct, + std::forward_as_tuple(fc, ios_)); + m.method = "GET"; + m.url = "/"; + m.version = 10; + m.headers.insert("User-Agent", "test"); + m.headers.insert("Transfer-Encoding", "chunked"); + m.body = "*****"; + error_code ec; + async_write(fs, m, do_yield[ec]); + if(ec == boost::asio::error::eof) + { + expect(fs.next_layer().str == + "GET / HTTP/1.0\r\n" + "User-Agent: test\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + "1\r\n*\r\n" + "1\r\n*\r\n" + "1\r\n*\r\n" + "1\r\n*\r\n" + "1\r\n*\r\n" + "0\r\n\r\n" + ); + break; + } + } + expect(n < limit); + + for(n = 0; n < limit; ++n) + { + test::fail_counter fc(n); + test::fail_stream< + string_write_stream> fs(fc, ios_); + message_v1 m( + std::piecewise_construct, + std::forward_as_tuple(fc, ios_)); + m.method = "GET"; + m.url = "/"; + m.version = 10; + m.headers.insert("User-Agent", "test"); + m.headers.insert("Content-Length", "5"); + m.body = "*****"; + error_code ec; + write(fs, m, ec); + if(! ec) + { + expect(fs.next_layer().str == + "GET / HTTP/1.0\r\n" + "User-Agent: test\r\n" + "Content-Length: 5\r\n" + "\r\n" + "*****" + ); + break; + } + } + expect(n < limit); + + for(n = 0; n < limit; ++n) + { + test::fail_counter fc(n); + test::fail_stream< + string_write_stream> fs(fc, ios_); + message_v1 m( + std::piecewise_construct, + std::forward_as_tuple(fc, ios_)); + m.method = "GET"; + m.url = "/"; + m.version = 10; + m.headers.insert("User-Agent", "test"); + m.headers.insert("Content-Length", "5"); + m.body = "*****"; + error_code ec; + async_write(fs, m, do_yield[ec]); + if(! ec) + { + expect(fs.next_layer().str == + "GET / HTTP/1.0\r\n" + "User-Agent: test\r\n" + "Content-Length: 5\r\n" + "\r\n" + "*****" + ); + break; + } + } + expect(n < limit); + } + + void + testOutput() { // auto content-length HTTP/1.0 { @@ -188,14 +500,14 @@ public: } // no content-length HTTP/1.0 { - message_v1 m; + message_v1 m; m.method = "GET"; m.url = "/"; m.version = 10; m.headers.insert("User-Agent", "test"); m.body = "*"; prepare(m); - string_SyncStream ss; + string_write_stream ss(ios_); error_code ec; write(ss, m, ec); expect(ec == boost::asio::error::eof); @@ -232,7 +544,7 @@ public: m.headers.insert("User-Agent", "test"); m.body = "*"; prepare(m, connection::close); - string_SyncStream ss; + string_write_stream ss(ios_); error_code ec; write(ss, m, ec); expect(ec == boost::asio::error::eof); @@ -262,14 +574,14 @@ public: } // no content-length HTTP/1.1 { - message_v1 m; + message_v1 m; m.method = "GET"; m.url = "/"; m.version = 11; m.headers.insert("User-Agent", "test"); m.body = "*"; prepare(m); - string_SyncStream ss; + string_write_stream ss(ios_); error_code ec; write(ss, m, ec); expect(ss.str == @@ -297,10 +609,38 @@ public: "GET / HTTP/1.1\r\nUser-Agent: test\r\nContent-Length: 1\r\n\r\n*"); } + void testOstream() + { + message_v1 m; + m.method = "GET"; + m.url = "/"; + m.version = 11; + m.headers.insert("User-Agent", "test"); + m.body = "*"; + prepare(m); + std::stringstream ss; + ss.setstate(ss.rdstate() | + std::stringstream::failbit); + try + { + ss << m; + fail(); + } + catch(std::exception const&) + { + pass(); + } + } + void run() override { - testWrite(); + yield_to(std::bind(&write_test::testAsyncWrite, + this, std::placeholders::_1)); + yield_to(std::bind(&write_test::testFailures, + this, std::placeholders::_1)); + testOutput(); testConvert(); + testOstream(); } }; diff --git a/test/websocket/detail/frame.cpp b/test/websocket/detail/frame.cpp index 237316a0..a1320341 100644 --- a/test/websocket/detail/frame.cpp +++ b/test/websocket/detail/frame.cpp @@ -154,6 +154,14 @@ public: check(fh); fh.rsv1 = false; + fh.rsv2 = true; + check(fh); + fh.rsv2 = false; + + fh.rsv3 = true; + check(fh); + fh.rsv3 = false; + fh.op = opcode::rsv3; check(fh); fh.op = opcode::text; diff --git a/test/websocket/error.cpp b/test/websocket/error.cpp index 36af8658..0e5ebf6b 100644 --- a/test/websocket/error.cpp +++ b/test/websocket/error.cpp @@ -42,6 +42,7 @@ public: check("websocket", error::request_malformed); check("websocket", error::request_invalid); check("websocket", error::request_denied); + check("websocket", error::general); } }; diff --git a/test/websocket/stream.cpp b/test/websocket/stream.cpp index 7a1c45e0..06250215 100644 --- a/test/websocket/stream.cpp +++ b/test/websocket/stream.cpp @@ -33,6 +33,13 @@ public: using address_type = boost::asio::ip::address; using socket_type = boost::asio::ip::tcp::socket; + void testClamp() + { + expect(detail::clamp( + std::numeric_limits::max()) == + std::numeric_limits::max()); + } + void testSpecialMembers() { stream ws(ios_); @@ -304,7 +311,7 @@ public: std::size_t n; // synchronous, exceptions - for(n = 1; n < limit; ++n) + for(n = 0; n < limit; ++n) { error_code ec; socket_type sock(ios_); @@ -343,7 +350,7 @@ public: expect(n < limit); // synchronous, error codes - for(n = 1; n < limit; ++n) + for(n = 0; n < limit; ++n) { error_code ec; socket_type sock(ios_); @@ -378,7 +385,7 @@ public: expect(n < limit); // asynchronous - for(n = 1; n < limit; ++n) + for(n = 0; n < limit; ++n) { error_code ec; socket_type sock(ios_); @@ -470,8 +477,35 @@ public: } } + void testWriteFrame(endpoint_type const& ep) + { + for(;;) + { + boost::asio::io_service ios; + error_code ec; + socket_type sock(ios); + sock.connect(ep, ec); + if(! expect(! ec, ec.message())) + break; + stream ws(sock); + ws.handshake("localhost", "/", ec); + if(! expect(! ec, ec.message())) + break; + ws.async_write_frame(false, + boost::asio::null_buffers{}, + [](error_code){ }); + // + // Destruction of the io_service will cause destruction + // of the write_frame_op without invoking the final handler. + // + break; + } + } + void run() override { + testClamp(); + testSpecialMembers(); testOptions(); @@ -483,33 +517,31 @@ public: address_type::from_string("127.0.0.1"), 0}; { sync_echo_peer server(true, any); + auto const ep = server.local_endpoint(); yield_to(std::bind(&stream_test::testHandshake, - this, server.local_endpoint(), - std::placeholders::_1)); + this, ep, std::placeholders::_1)); yield_to(std::bind(&stream_test::testErrorHandling, - this, server.local_endpoint(), - std::placeholders::_1)); + this, ep, std::placeholders::_1)); yield_to(std::bind(&stream_test::testMask, - this, server.local_endpoint(), - std::placeholders::_1)); + this, ep, std::placeholders::_1)); + + testWriteFrame(ep); } { async_echo_peer server(true, any, 1); + auto const ep = server.local_endpoint(); yield_to(std::bind(&stream_test::testHandshake, - this, server.local_endpoint(), - std::placeholders::_1)); + this, ep, std::placeholders::_1)); yield_to(std::bind(&stream_test::testErrorHandling, - this, server.local_endpoint(), - std::placeholders::_1)); + this, ep, std::placeholders::_1)); yield_to(std::bind(&stream_test::testMask, - this, server.local_endpoint(), - std::placeholders::_1)); + this, ep, std::placeholders::_1)); } pass(); diff --git a/test/websocket/websocket_async_echo_peer.hpp b/test/websocket/websocket_async_echo_peer.hpp index 90ff8697..1efa9ed7 100644 --- a/test/websocket/websocket_async_echo_peer.hpp +++ b/test/websocket/websocket_async_echo_peer.hpp @@ -1,21 +1,9 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== +// +// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// #ifndef BEAST_WEBSOCKET_ASYNC_ECHO_PEER_H_INCLUDED #define BEAST_WEBSOCKET_ASYNC_ECHO_PEER_H_INCLUDED diff --git a/test/websocket/websocket_echo.cpp b/test/websocket/websocket_echo.cpp index 0b4195df..98b8c896 100644 --- a/test/websocket/websocket_echo.cpp +++ b/test/websocket/websocket_echo.cpp @@ -1,21 +1,9 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== +// +// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// #include "websocket_async_echo_peer.hpp" #include "websocket_sync_echo_peer.hpp" diff --git a/test/websocket/websocket_sync_echo_peer.hpp b/test/websocket/websocket_sync_echo_peer.hpp index 14e9c6c9..d45a67fc 100644 --- a/test/websocket/websocket_sync_echo_peer.hpp +++ b/test/websocket/websocket_sync_echo_peer.hpp @@ -1,21 +1,9 @@ -//------------------------------------------------------------------------------ -/* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== +// +// Copyright (c) 2013-2016 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// #ifndef BEAST_WEBSOCKET_SYNC_ECHO_PEER_H_INCLUDED #define BEAST_WEBSOCKET_SYNC_ECHO_PEER_H_INCLUDED