Commit bfb7bddd authored by Ian Roddis's avatar Ian Roddis

Migrating to a static member variable for ArrayStreamBuf, fixing payload test.

parent 0d2e65a1
......@@ -66,7 +66,6 @@ private:
if (!handler_)
throw std::runtime_error("Must call setHandler() prior to serve()");
handler_->setMaxPayload(maxPayload_);
listener.setHandler(handler_);
if (listener.bind()) {
......@@ -77,7 +76,6 @@ private:
std::shared_ptr<Handler> handler_;
Tcp::Listener listener;
size_t maxPayload_;
};
template<typename Handler>
......
......@@ -690,15 +690,13 @@ namespace Private {
class ParserBase {
public:
ParserBase()
: buffer(Const::DefaultMaxPayload)
, cursor(&buffer)
: cursor(&buffer)
, currentStep(0)
{
}
ParserBase(const char* data, size_t len)
: buffer(len > Const::DefaultMaxPayload ? len : Const::DefaultMaxPayload)
, cursor(&buffer)
: cursor(&buffer)
, currentStep(0)
{
UNUSED(data)
......@@ -711,8 +709,6 @@ namespace Private {
bool feed(const char* data, size_t len);
virtual void reset();
void setMaxSize(size_t sz) { buffer.setMaxSize(sz); }
virtual ~ParserBase() { }
State parse();
......
......@@ -81,9 +81,9 @@ template<typename CharT = char>
class ArrayStreamBuf : public StreamBuf<CharT> {
public:
typedef StreamBuf<CharT> Base;
static size_t maxSize;
ArrayStreamBuf(size_t max_size)
: max_size_(max_size)
ArrayStreamBuf()
{
bytes.clear();
Base::setg(bytes.data(), bytes.data(), bytes.data() + bytes.size());
......@@ -96,10 +96,8 @@ public:
Base::setg(bytes.data(), bytes.data(), bytes.data() + bytes.size());
}
void setMaxSize(size_t sz) { max_size_ = sz; }
bool feed(const char* data, size_t len) {
if (bytes.size() + len > max_size_) { return false; }
if (bytes.size() + len > maxSize) { return false; }
// persist current offset
size_t readOffset = static_cast<size_t>(this->gptr() - this->eback());
std::copy(data, data + len, std::back_inserter(bytes));
......@@ -117,9 +115,11 @@ public:
private:
std::vector<CharT> bytes;
size_t max_size_;
};
template<typename CharT>
size_t ArrayStreamBuf<CharT>::maxSize = Const::DefaultMaxPayload;
struct Buffer {
Buffer()
: data(nullptr)
......
......@@ -37,12 +37,8 @@ public:
friend class Transport;
Handler();
Handler(const Handler & rhs);
~Handler();
size_t getMaxPayload() { return maxPayload_; }
void setMaxPayload(size_t sz) { maxPayload_ = sz; }
virtual void onInput(const char *buffer, size_t len, const std::shared_ptr<Tcp::Peer>& peer) = 0;
virtual void onConnection(const std::shared_ptr<Tcp::Peer>& peer);
......@@ -58,8 +54,6 @@ protected:
throw std::logic_error("Orphaned handler");
return transport_;
}
size_t maxPayload_;
};
} // namespace Tcp
......
......@@ -812,9 +812,7 @@ Timeout::onTimeout(uint64_t numWakeup) {
Private::Parser<Http::Request>&
Handler::getParser(const std::shared_ptr<Tcp::Peer>& peer) const {
auto & parser = *peer->getData<Private::Parser<Http::Request>>(ParserData);
parser.setMaxSize(maxPayload_);
return parser;
return *peer->getData<Private::Parser<Http::Request>>(ParserData);
}
......
......@@ -12,15 +12,9 @@ namespace Tcp {
Handler::Handler()
: transport_(nullptr)
, maxPayload_(Const::DefaultMaxPayload)
{
}
Handler::Handler(const Handler & rhs)
: transport_(nullptr)
, maxPayload_(rhs.maxPayload_)
{ }
Handler::~Handler()
{ }
......
......@@ -14,7 +14,6 @@ namespace Http {
Endpoint::Options::Options()
: threads_(1)
, maxPayload_(Const::DefaultMaxPayload)
{ }
Endpoint::Options&
......@@ -51,7 +50,7 @@ Endpoint::Endpoint(const Address& addr)
void
Endpoint::init(const Endpoint::Options& options) {
listener.init(options.threads_, options.flags_);
maxPayload_ = options.maxPayload_;
ArrayStreamBuf<char>::maxSize = options.maxPayload_;
}
void
......
......@@ -244,9 +244,7 @@ Router::fromDescription(const Rest::Description& desc) {
std::shared_ptr<Private::RouterHandler>
Router::handler() const {
auto handler = std::make_shared<Private::RouterHandler>(*this);
handler->setMaxPayload(maxPayload_);
return std::move(handler);
return std::make_shared<Private::RouterHandler>(*this);
}
void
......
......@@ -8,39 +8,55 @@
using namespace std;
using namespace Pistache;
struct TestParameter {
size_t payloadBytes;
Http::Code expectedResponseCode;
struct TestSet {
TestSet()
: bytes(0)
, expectedCode(Http::Code::Ok)
, actualCode(Http::Code::Ok)
{ }
TestSet(size_t b, Http::Code c)
: bytes(b)
, expectedCode(c)
, actualCode(Http::Code::Ok)
{ }
size_t bytes;
Http::Code expectedCode;
Http::Code actualCode;
};
typedef std::vector<TestParameter> PayloadTestSizes;
typedef std::vector<TestSet> PayloadTestSets;
void testPayloads(std::string url, PayloadTestSizes & testPayloads) {
void testPayloads(std::string url, PayloadTestSets & testPayloads) {
// Client tests to make sure the payload is enforced
std::vector<Async::Promise<Http::Response> > responses;
PayloadTestSets test_results;
for (size_t times = 0; times < 10; ++times) {
Http::Client client;
auto client_opts = Http::Client::options().threads(1).maxConnectionsPerHost(1);
client.init(client_opts);
std::vector<Async::Promise<Http::Response>> responses;
size_t tests_passed = 0;
for (auto & t : testPayloads) {
auto rb = client.post(url);
std::string payload(t.payloadBytes, 'A');
std::string payload(t.bytes, 'A');
auto response = rb.body(payload).send();
response.then([t,&tests_passed](Http::Response rsp) {
if (rsp.code() == t.expectedResponseCode)
++tests_passed;
response.then([t,&test_results](Http::Response rsp) {
TestSet res(t);
res.actualCode = rsp.code();
test_results.push_back(res);
}, Async::IgnoreException);
responses.push_back(std::move(response));
}
auto sync = Async::whenAll(responses.begin(), responses.end());
Async::Barrier<std::vector<Http::Response>> barrier(sync);
barrier.wait_for(std::chrono::seconds(5));
client.shutdown();
}
ASSERT_TRUE(tests_passed == testPayloads.size());
for (auto & result : test_results) {
ASSERT_EQ(result.expectedCode, result.actualCode);
}
}
void handleEcho(const Rest::Request&req, Http::ResponseWriter response) {
......@@ -51,7 +67,7 @@ TEST(payload_test, from_description)
{
Address addr(Ipv4::any(), 9084);
const size_t threads = 2;
const size_t max_payload = 1024; // very small
const size_t maxPayload = 1024; // very small
std::shared_ptr<Http::Endpoint> endpoint;
Rest::Description desc("Rest Description Test", "v1");
......@@ -63,23 +79,24 @@ TEST(payload_test, from_description)
.response(Http::Code::Ok, "Response to the /ready call");
router.initFromDescription(desc);
router.setMaxPayload(max_payload);
auto flags = Tcp::Options::InstallSignalHandler | Tcp::Options::ReuseAddr;
auto opts = Http::Endpoint::options()
.threads(threads)
.flags(flags);
.flags(flags)
.maxPayload(maxPayload);
;
endpoint = std::make_shared<Pistache::Http::Endpoint>(addr);
endpoint->init(opts);
endpoint->setHandler(router.handler());
ASSERT_EQ(router.handler()->getMaxPayload(), max_payload);
endpoint->serveThreaded();
PayloadTestSizes payloads{
{1024, Http::Code::Ok}
PayloadTestSets payloads{
{800, Http::Code::Ok}
, {1024, Http::Code::Request_Entity_Too_Large}
,{2048, Http::Code::Request_Entity_Too_Large}
};
......@@ -91,7 +108,6 @@ TEST(payload_test, manual_construction) {
class MyHandler : public Http::Handler {
HTTP_PROTOTYPE(MyHandler)
void onRequest(
const Http::Request& req,
Http::ResponseWriter response)
......@@ -108,28 +124,29 @@ TEST(payload_test, manual_construction) {
}
private:
tag garbage;
tag placeholder;
};
Port port(9080);
int thr = 2;
Address addr(Ipv4::any(), port);
auto server = std::make_shared<Http::Endpoint>(addr);
auto endpoint = std::make_shared<Http::Endpoint>(addr);
size_t maxPayload = 2048;
auto opts = Http::Endpoint::options()
.threads(thr)
.flags(Tcp::Options::InstallSignalHandler)
.maxPayload(maxPayload);
server->init(opts);
server->setHandler(Http::make_handler<MyHandler>());
server->serveThreaded();
PayloadTestSizes payloads{
endpoint->init(opts);
endpoint->setHandler(Http::make_handler<MyHandler>());
endpoint->serveThreaded();
PayloadTestSets payloads{
{1024, Http::Code::Ok}
, {1800, Http::Code::Ok}
, {2048, Http::Code::Request_Entity_Too_Large}
, {4096, Http::Code::Request_Entity_Too_Large}
};
testPayloads("127.0.0.1:9080/echo", payloads);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment