diff --git a/http_connection.h b/http_connection.h index 6338c6fc6..d486d0121 100644 --- a/http_connection.h +++ b/http_connection.h @@ -72,7 +72,6 @@ namespace flask std::cerr << "HTTP/" << parser_.http_major << "." << parser_.http_minor << ' '; std::cerr << method_name(req.method); std::cerr << " " << res.code << std::endl; - std::cerr << "res body: " << res.body << std::endl; #endif static std::string seperator = ": "; @@ -81,7 +80,7 @@ namespace flask buffers_.clear(); buffers_.reserve(4*(res.headers.size()+4)+3); - if (res.body.empty() && res.json_value.t == json::type::Object) + if (res.body.empty() && res.json_value.t() == json::type::Object) { res.body = json::dump(res.json_value); } @@ -161,6 +160,7 @@ namespace flask do_read(); else { + socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both); socket_.close(); life_--; diff --git a/json.h b/json.h index 705a9bcd2..395cef11e 100644 --- a/json.h +++ b/json.h @@ -936,8 +936,9 @@ namespace flask class wvalue { public: - type t{type::Null}; + type t() { return t_; } private: + type t_{type::Null}; double d; std::string s; std::unique_ptr> l; @@ -953,7 +954,7 @@ namespace flask wvalue& operator = (wvalue&& r) { - t = r.t; + t_ = r.t_; d = r.d; s = std::move(r.s); l = std::move(r.l); @@ -963,14 +964,14 @@ namespace flask void clear() { - t = type::Null; + t_ = type::Null; l.reset(); o.reset(); } void reset() { - t = type::Null; + t_ = type::Null; l.reset(); o.reset(); } @@ -984,16 +985,16 @@ namespace flask { reset(); if (value) - t = type::True; + t_ = type::True; else - t = type::False; + t_ = type::False; return *this; } wvalue& operator = (double value) { reset(); - t = type::Number; + t_ = type::Number; d = value; return *this; } @@ -1001,7 +1002,7 @@ namespace flask wvalue& operator = (uint16_t value) { reset(); - t = type::Number; + t_ = type::Number; d = (double)value; return *this; } @@ -1009,7 +1010,7 @@ namespace flask wvalue& operator = (int16_t value) { reset(); - t = type::Number; + t_ = type::Number; d = (double)value; return *this; } @@ -1017,7 +1018,7 @@ namespace flask wvalue& operator = (uint32_t value) { reset(); - t = type::Number; + t_ = type::Number; d = (double)value; return *this; } @@ -1025,7 +1026,7 @@ namespace flask wvalue& operator = (int32_t value) { reset(); - t = type::Number; + t_ = type::Number; d = (double)value; return *this; } @@ -1033,7 +1034,7 @@ namespace flask wvalue& operator = (uint64_t value) { reset(); - t = type::Number; + t_ = type::Number; d = (double)value; return *this; } @@ -1041,7 +1042,7 @@ namespace flask wvalue& operator = (int64_t value) { reset(); - t = type::Number; + t_ = type::Number; d = (double)value; return *this; } @@ -1049,7 +1050,7 @@ namespace flask wvalue& operator=(const char* str) { reset(); - t = type::String; + t_ = type::String; s = str; return *this; } @@ -1057,7 +1058,7 @@ namespace flask wvalue& operator=(const std::string& str) { reset(); - t = type::String; + t_ = type::String; s = str; return *this; } @@ -1065,9 +1066,9 @@ namespace flask template wvalue& operator[](const std::vector& v) { - if (t != type::List) + if (t_ != type::List) reset(); - t = type::List; + t_ = type::List; if (!l) l = std::move(std::unique_ptr>(new std::vector{})); l->clear(); @@ -1082,9 +1083,9 @@ namespace flask wvalue& operator[](unsigned index) { - if (t != type::List) + if (t_ != type::List) reset(); - t = type::List; + t_ = type::List; if (!l) l = std::move(std::unique_ptr>(new std::vector{})); if (l->size() < index+1) @@ -1094,9 +1095,9 @@ namespace flask wvalue& operator[](const std::string& str) { - if (t != type::Object) + if (t_ != type::Object) reset(); - t = type::Object; + t_ = type::Object; if (!o) o = std::move( std::unique_ptr< @@ -1108,7 +1109,7 @@ namespace flask size_t estimate_length() const { - switch(t) + switch(t_) { case type::Null: return 4; case type::False: return 5; @@ -1160,7 +1161,7 @@ namespace flask } void dump_internal(const wvalue& v, std::string& out) { - switch(v.t) + switch(v.t_) { case type::Null: out += "null"; break; case type::False: out += "false"; break; diff --git a/parser.h b/parser.h index f6dc8ae27..3e28603f4 100644 --- a/parser.h +++ b/parser.h @@ -23,11 +23,6 @@ namespace flask self->url.insert(self->url.end(), at, at+length); return 0; } - static int on_status(http_parser* self_, const char* at, size_t length) - { - // will not call while parsing request - return 0; - } static int on_header_field(http_parser* self_, const char* at, size_t length) { HTTPParser* self = static_cast(self_); @@ -43,7 +38,7 @@ namespace flask self->header_building_state = 1; break; case 1: - self->header_field.insert(self->header_value.end(), at, at+length); + self->header_field.insert(self->header_field.end(), at, at+length); break; } return 0; @@ -89,7 +84,7 @@ namespace flask settings_ { on_message_begin, on_url, - on_status, + nullptr, on_header_field, on_header_value, on_headers_complete, diff --git a/routing.h b/routing.h index d3601a2be..9adf604bf 100644 --- a/routing.h +++ b/routing.h @@ -586,8 +586,7 @@ public: if (rule_index >= rules_.size()) throw std::runtime_error("Trie internal structure corrupted!"); #ifdef FLASK_ENABLE_LOGGING - std::cerr << req.url << std::endl; - std::cerr << rules_[rule_index]->rule_ << std::endl; + std::cerr << req.url << ' ' << rules_[rule_index]->rule_ << std::endl; #endif return rules_[rule_index]->handle(req, found.second); } diff --git a/unittest.cpp b/unittest.cpp index d10c2e3f7..ddd69a392 100644 --- a/unittest.cpp +++ b/unittest.cpp @@ -1,3 +1,4 @@ +//#define FLASK_ENABLE_LOGGING #include #include #include "routing.h" @@ -217,6 +218,35 @@ TEST(simple_response_routing_params) ASSERT_EQUAL("hello", rp.get(0)); } +TEST(server_handling_error_request) +{ + static char buf[2048]; + Flask app; + FLASK_ROUTE(app, "/")([]{return "A";}); + Server server(&app, 45451); + auto _ = async(launch::async, [&]{server.run();}); + std::string sendmsg = "POX"; + asio::io_service is; + { + asio::ip::tcp::socket c(is); + c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 45451)); + + + c.send(asio::buffer(sendmsg)); + + try + { + c.receive(asio::buffer(buf, 2048)); + fail(); + } + catch(std::exception& e) + { + std::cerr << e.what() << std::endl; + } + } + server.stop(); +} + TEST(multi_server) { static char buf[2048]; @@ -230,12 +260,12 @@ TEST(multi_server) auto _ = async(launch::async, [&]{server1.run();}); auto _2 = async(launch::async, [&]{server2.run();}); + std::string sendmsg = "POST /\r\nContent-Length:3\r\nX-HeaderTest: 123\r\n\r\nA=B\r\n"; asio::io_service is; { asio::ip::tcp::socket c(is); c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 45451)); - std::string sendmsg = "GET /\r\n\r\n"; c.send(asio::buffer(sendmsg)); @@ -247,9 +277,12 @@ TEST(multi_server) asio::ip::tcp::socket c(is); c.connect(asio::ip::tcp::endpoint(asio::ip::address::from_string("127.0.0.1"), 45452)); - std::string sendmsg = "GET /\r\n\r\n"; - - c.send(asio::buffer(sendmsg)); + for(auto ch:sendmsg) + { + char buf[1] = {ch}; + std::cerr << ch << '(' << (int)ch<<')'<