increasing unittest coverage; fix crash bug while parsing headers

This commit is contained in:
ipknHama 2014-04-22 20:19:03 +09:00
parent dd74354a7b
commit 89bfe52f09
5 changed files with 66 additions and 38 deletions

View File

@ -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
View File

@ -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;

View File

@ -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,

View File

@ -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);
}

View File

@ -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]);