// // Copyright (c) 2013-2017 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_IMPL_MESSAGE_IPP #define BEAST_HTTP_IMPL_MESSAGE_IPP #include #include #include #include #include #include namespace beast { namespace http { template template header:: header(Arg1&& arg1, ArgN&&... argn) : Fields(std::forward(arg1), std::forward(argn)...) { } template inline verb header:: method() const { return method_; } template void header:: method(verb v) { if(v == verb::unknown) BOOST_THROW_EXCEPTION( std::invalid_argument{"unknown method"}); method_ = v; this->set_method_impl({}); } template string_view header:: method_string() const { if(method_ != verb::unknown) return to_string(method_); return this->get_method_impl(); } template void header:: method_string(string_view s) { method_ = string_to_verb(s); if(method_ != verb::unknown) this->set_method_impl({}); else this->set_method_impl(s); } template inline string_view header:: target() const { return this->get_target_impl(); } template inline void header:: target(string_view s) { this->set_target_impl(s); } template void swap( header& h1, header& h2) { using std::swap; swap( static_cast(h1), static_cast(h2)); swap(h1.version, h2.version); swap(h1.method_, h2.method_); } //------------------------------------------------------------------------------ template template header:: header(Arg1&& arg1, ArgN&&... argn) : Fields(std::forward(arg1), std::forward(argn)...) { } template inline status header:: result() const { return int_to_status( static_cast(result_)); } template inline void header:: result(status v) { result_ = v; } template inline void header:: result(unsigned v) { if(v > 999) BOOST_THROW_EXCEPTION( std::invalid_argument{ "invalid status-code"}); result_ = static_cast(v); } template inline unsigned header:: result_int() const { return static_cast(result_); } template string_view header:: reason() const { auto const s = this->get_reason_impl(); if(! s.empty()) return s; return obsolete_reason(result_); } template inline void header:: reason(string_view s) { this->set_reason_impl(s); } template void swap( header& h1, header& h2) { using std::swap; swap( static_cast(h1), static_cast(h2)); swap(h1.version, h2.version); swap(h1.result_, h2.result_); } //------------------------------------------------------------------------------ template template message:: message(header_type&& base, Args&&... args) : header_type(std::move(base)) , body(std::forward(args)...) { } template template message:: message(header_type const& base, Args&&... args) : header_type(base) , body(std::forward(args)...) { } template template message:: message(U&& u) : body(std::forward(u)) { } template template message:: message(U&& u, V&& v) : header_type(std::forward(v)) , body(std::forward(u)) { } template template message:: message(std::piecewise_construct_t, std::tuple un) : message(std::piecewise_construct, un, beast::detail::make_index_sequence{}) { } template template message:: message(std::piecewise_construct_t, std::tuple&& un, std::tuple&& vn) : message(std::piecewise_construct, un, vn, beast::detail::make_index_sequence{}, beast::detail::make_index_sequence{}) { } template inline bool message:: has_close() const { return this->has_close_impl(); } template inline bool message:: has_chunked() const { return this->has_chunked_impl(); } template inline bool message:: has_content_length() const { return this->has_content_length_impl(); } template boost::optional message:: size() const { static_assert(is_body_reader::value, "BodyReader requirements not met"); return size(detail::is_body_sized< Body, decltype(*this)>{}); } template void message:: content_length(std::uint64_t n) { this->content_length_impl(n); } template void message:: prepare() { prepare(typename header< isRequest, Fields>::is_request{}); } template inline void message:: prepare(std::true_type) { auto const n = size(); if(this->method_ == verb::trace && ( ! n || *n > 0)) BOOST_THROW_EXCEPTION(std::invalid_argument{ "invalid request body"}); if(n) { if(*n > 0 || this->method_ == verb::options || this->method_ == verb::put || this->method_ == verb::post ) { this->content_length_impl(*n); } } else if(this->version >= 11) { this->set_chunked_impl(true); } } template inline void message:: prepare(std::false_type) { auto const n = size(); if((status_class(this->result_) == status_class::informational || this->result_ == status::no_content || this->result_ == status::not_modified)) { if(! n || *n > 0) // The response body MUST BE empty for this case BOOST_THROW_EXCEPTION(std::invalid_argument{ "invalid response body"}); } if(n) this->content_length_impl(*n); else if(this->version >= 11) this->set_chunked_impl(true); } //------------------------------------------------------------------------------ template void swap( message& m1, message& m2) { using std::swap; swap( static_cast&>(m1), static_cast&>(m2)); swap(m1.body, m2.body); } } // http } // beast #endif