Commit 64551788 authored by Ian Roddis's avatar Ian Roddis

Making buffer size a run-time constraint.

parent 57112589
......@@ -9,11 +9,6 @@ option(PISTACHE_BUILD_EXAMPLES "build examples alongside the project" OFF)
option(PISTACHE_INSTALL "add pistache as install target (recommended)" ON)
# Allow redefining the max payload size
if (NOT PISTACHE_MAX_PAYLOAD)
set(PISTACHE_MAX_PAYLOAD 4096)
endif()
add_definitions( -DMAX_PAYLOAD=${PISTACHE_MAX_PAYLOAD} )
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
......
......@@ -58,7 +58,6 @@ Some other CMAKE defines:
|---------------------------|-------------|-------------------------------------------------------------|
| PISTACHE_BUILD_EXAMPLES | False | Build all of the example apps |
| PISTACHE_BUILD_TESTS | False | Build all of the unit tests |
| PISTACHE_MAX_PAYLOAD | 4096 | Maximum size of requests, in bytes (including HTTP headers) |
# Example
......
......@@ -177,11 +177,15 @@ int main(int argc, char *argv[]) {
auto server = std::make_shared<Http::Endpoint>(addr);
auto handler = Http::make_handler<MyHandler>();
// Adjust maximum payload size. Default is 4096 Const::DefaultMaxPayload
// handler->setMaxPayload(65536);
auto opts = Http::Endpoint::options()
.threads(thr)
.flags(Tcp::Options::InstallSignalHandler);
server->init(opts);
server->setHandler(Http::make_handler<MyHandler>());
server->setHandler(handler);
server->serve();
std::cout << "Shutdowning server" << std::endl;
......
......@@ -52,10 +52,6 @@
// Until we require C++17 compiler with [[maybe_unused]]
#define UNUSED(x) (void)(x);
#ifndef MAX_PAYLOAD
#define MAX_PAYLOAD 4096
#endif
// Allow compile-time overload
namespace Pistache {
namespace Const {
......@@ -65,7 +61,7 @@ namespace Const {
static constexpr size_t MaxBuffer = 4096;
// Defined from CMakeLists.txt in project root
static constexpr size_t MaxPayload = MAX_PAYLOAD;
static constexpr size_t DefaultMaxPayload = 4096;
static constexpr size_t ChunkSize = 1024;
} // namespace Const
} // namespace Pistache
......@@ -690,13 +690,15 @@ namespace Private {
class ParserBase {
public:
ParserBase()
: cursor(&buffer)
: buffer(Const::DefaultMaxPayload)
, cursor(&buffer)
, currentStep(0)
{
}
ParserBase(const char* data, size_t len)
: cursor(&buffer)
: buffer(len > Const::DefaultMaxPayload ? len : Const::DefaultMaxPayload)
, cursor(&buffer)
, currentStep(0)
{
UNUSED(data)
......@@ -709,11 +711,13 @@ 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();
ArrayStreamBuf<Const::MaxPayload, char> buffer;
ArrayStreamBuf<char> buffer;
StreamCursor cursor;
protected:
......@@ -787,9 +791,11 @@ namespace Private {
class Handler : public Tcp::Handler {
public:
void Handler() : max_payload_(Const::MaxPayload) {}
void Handler(size_t max_payload) {
}
Handler() : max_payload_(Const::DefaultMaxPayload) {}
Handler(size_t max_payload) : max_payload_(max_payload) { }
size_t getMaxPayload() { return max_payload_; }
void setMaxPayload(size_t sz) { max_payload_ = sz; }
void onInput(const char* buffer, size_t len, const std::shared_ptr<Tcp::Peer>& peer);
......@@ -804,6 +810,8 @@ public:
private:
Private::Parser<Http::Request>& getParser(const std::shared_ptr<Tcp::Peer>& peer) const;
protected:
size_t max_payload_;
};
template<typename H, typename... Args>
......
......@@ -77,12 +77,13 @@ public:
};
// Make the buffer dynamic
template<size_t MAX_SIZE, typename CharT = char>
template<typename CharT = char>
class ArrayStreamBuf : public StreamBuf<CharT> {
public:
typedef StreamBuf<CharT> Base;
ArrayStreamBuf()
ArrayStreamBuf(size_t max_size)
: max_size_(max_size)
{
bytes.clear();
Base::setg(bytes.data(), bytes.data(), bytes.data() + bytes.size());
......@@ -95,8 +96,10 @@ 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 > max_size_) { 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));
......@@ -114,6 +117,7 @@ public:
private:
std::vector<CharT> bytes;
size_t max_size_;
};
struct Buffer {
......
......@@ -355,7 +355,7 @@ Transport::handleIncoming(const std::shared_ptr<Connection>& connection) {
else {
totalBytes += bytes;
if (totalBytes > Const::MaxBuffer) {
if (static_cast<size_t>(totalBytes) > Const::MaxBuffer) {
std::cerr << "Client: Too long packet" << std::endl;
break;
}
......
......@@ -812,7 +812,9 @@ Timeout::onTimeout(uint64_t numWakeup) {
Private::Parser<Http::Request>&
Handler::getParser(const std::shared_ptr<Tcp::Peer>& peer) const {
return *peer->getData<Private::Parser<Http::Request>>(ParserData);
auto & parser = *peer->getData<Private::Parser<Http::Request>>(ParserData);
parser.setMaxSize(max_payload_);
return parser;
}
......
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