mirror of
https://github.com/CrowCpp/Crow.git
synced 2024-06-07 21:10:44 +00:00
increasing unittest coverage; fix crash bug while parsing headers
This commit is contained in:
parent
dd74354a7b
commit
89bfe52f09
@ -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_--;
|
||||
|
47
json.h
47
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<std::vector<wvalue>> 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 <typename T>
|
||||
wvalue& operator[](const std::vector<T>& v)
|
||||
{
|
||||
if (t != type::List)
|
||||
if (t_ != type::List)
|
||||
reset();
|
||||
t = type::List;
|
||||
t_ = type::List;
|
||||
if (!l)
|
||||
l = std::move(std::unique_ptr<std::vector<wvalue>>(new std::vector<wvalue>{}));
|
||||
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<std::vector<wvalue>>(new std::vector<wvalue>{}));
|
||||
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;
|
||||
|
9
parser.h
9
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<HTTPParser*>(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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
41
unittest.cpp
41
unittest.cpp
@ -1,3 +1,4 @@
|
||||
//#define FLASK_ENABLE_LOGGING
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include "routing.h"
|
||||
@ -217,6 +218,35 @@ TEST(simple_response_routing_params)
|
||||
ASSERT_EQUAL("hello", rp.get<string>(0));
|
||||
}
|
||||
|
||||
TEST(server_handling_error_request)
|
||||
{
|
||||
static char buf[2048];
|
||||
Flask app;
|
||||
FLASK_ROUTE(app, "/")([]{return "A";});
|
||||
Server<Flask> 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<<')'<<std::endl;
|
||||
c.send(asio::buffer(buf));
|
||||
}
|
||||
|
||||
size_t recved = c.receive(asio::buffer(buf, 2048));
|
||||
ASSERT_EQUAL('B', buf[recved-1]);
|
||||
|
Loading…
Reference in New Issue
Block a user