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 #ifndef BOOST_BEAST_HTTP_TEST_PARSER_HPP 11 #define BOOST_BEAST_HTTP_TEST_PARSER_HPP 12 13 #include <boost/beast/http/basic_parser.hpp> 14 #include <boost/beast/_experimental/test/fail_count.hpp> 15 #include <string> 16 #include <unordered_map> 17 18 namespace boost { 19 namespace beast { 20 namespace http { 21 22 template<bool isRequest> 23 class test_parser 24 : public basic_parser<isRequest> 25 { 26 test::fail_count* fc_ = nullptr; 27 28 public: 29 using mutable_buffers_type = 30 net::mutable_buffer; 31 32 int status = 0; 33 int version = 0; 34 std::string method; 35 std::string path; 36 std::string reason; 37 std::string body; 38 int got_on_begin = 0; 39 int got_on_field = 0; 40 int got_on_header = 0; 41 int got_on_body = 0; 42 int got_content_length = 0; 43 int got_on_chunk = 0; 44 int got_on_complete = 0; 45 std::unordered_map< 46 std::string, std::string> fields; 47 48 test_parser() = default; 49 50 explicit test_parser(test::fail_count & fc)51 test_parser(test::fail_count& fc) 52 : fc_(&fc) 53 { 54 } 55 56 void on_request_impl(verb,string_view method_str_,string_view path_,int version_,error_code & ec)57 on_request_impl(verb, string_view method_str_, 58 string_view path_, int version_, error_code& ec) 59 { 60 method = std::string( 61 method_str_.data(), method_str_.size()); 62 path = std::string( 63 path_.data(), path_.size()); 64 version = version_; 65 ++got_on_begin; 66 if(fc_) 67 fc_->fail(ec); 68 } 69 70 void on_response_impl(int code,string_view reason_,int version_,error_code & ec)71 on_response_impl(int code, 72 string_view reason_, 73 int version_, error_code& ec) 74 { 75 status = code; 76 reason = std::string( 77 reason_.data(), reason_.size()); 78 version = version_; 79 ++got_on_begin; 80 if(fc_) 81 fc_->fail(ec); 82 } 83 84 void on_field_impl(field,string_view name,string_view value,error_code & ec)85 on_field_impl(field, string_view name, 86 string_view value, error_code& ec) 87 { 88 ++got_on_field; 89 if(fc_) 90 fc_->fail(ec); 91 fields[std::string(name)] = std::string(value); 92 } 93 94 void on_header_impl(error_code & ec)95 on_header_impl(error_code& ec) 96 { 97 ++got_on_header; 98 if(fc_) 99 fc_->fail(ec); 100 } 101 102 void on_body_init_impl(boost::optional<std::uint64_t> const & content_length_,error_code & ec)103 on_body_init_impl( 104 boost::optional<std::uint64_t> const& content_length_, 105 error_code& ec) 106 { 107 ++got_on_body; 108 got_content_length = 109 static_cast<bool>(content_length_); 110 if(fc_) 111 fc_->fail(ec); 112 } 113 114 std::size_t on_body_impl(string_view s,error_code & ec)115 on_body_impl(string_view s, 116 error_code& ec) 117 { 118 body.append(s.data(), s.size()); 119 if(fc_) 120 fc_->fail(ec); 121 return s.size(); 122 } 123 124 void on_chunk_header_impl(std::uint64_t,string_view,error_code & ec)125 on_chunk_header_impl( 126 std::uint64_t, 127 string_view, 128 error_code& ec) 129 { 130 ++got_on_chunk; 131 if(fc_) 132 fc_->fail(ec); 133 } 134 135 std::size_t on_chunk_body_impl(std::uint64_t,string_view s,error_code & ec)136 on_chunk_body_impl( 137 std::uint64_t, 138 string_view s, 139 error_code& ec) 140 { 141 body.append(s.data(), s.size()); 142 if(fc_) 143 fc_->fail(ec); 144 return s.size(); 145 } 146 147 148 void on_finish_impl(error_code & ec)149 on_finish_impl(error_code& ec) 150 { 151 ++got_on_complete; 152 if(fc_) 153 fc_->fail(ec); 154 } 155 }; 156 157 } // http 158 } // beast 159 } // boost 160 161 #endif 162