Skip to content

Commit ee5de74

Browse files
authored
Merge pull request etr#95 from wlandry/large_POST
Handle POST's larger than 1024 bytes correctly.
2 parents e396fe4 + 1fe733f commit ee5de74

File tree

4 files changed

+43
-14
lines changed

4 files changed

+43
-14
lines changed

src/httpserver/create_webserver.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class create_webserver
5252
_max_threads(0),
5353
_max_connections(0),
5454
_memory_limit(0),
55+
_content_size_limit(static_cast<size_t>(-1)),
5556
_connection_timeout(DEFAULT_WS_TIMEOUT),
5657
_per_IP_connection_limit(0),
5758
_log_access(0x0),
@@ -93,6 +94,7 @@ class create_webserver
9394
_max_threads(0),
9495
_max_connections(0),
9596
_memory_limit(0),
97+
_content_size_limit(static_cast<size_t>(-1)),
9698
_connection_timeout(DEFAULT_WS_TIMEOUT),
9799
_per_IP_connection_limit(0),
98100
_log_access(0x0),
@@ -147,6 +149,10 @@ class create_webserver
147149
{
148150
_memory_limit = memory_limit; return *this;
149151
}
152+
create_webserver& content_size_limit(size_t content_size_limit)
153+
{
154+
_content_size_limit = content_size_limit; return *this;
155+
}
150156
create_webserver& connection_timeout(int connection_timeout)
151157
{
152158
_connection_timeout = connection_timeout; return *this;
@@ -333,6 +339,7 @@ class create_webserver
333339
int _max_threads;
334340
int _max_connections;
335341
int _memory_limit;
342+
size_t _content_size_limit;
336343
int _connection_timeout;
337344
int _per_IP_connection_limit;
338345
log_access_ptr _log_access;

src/httpserver/http_request.hpp

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,18 @@ class http_request
310310
{
311311
result = this->content;
312312
}
313+
/**
314+
* Method to check whether the size of the content reached or exceeded content_size_limit.
315+
* @return boolean
316+
**/
317+
bool content_too_large() const
318+
{
319+
return content.size()>=content_size_limit;
320+
}
321+
/**
322+
* Method used to get the content of the query string..
323+
* @return the query string in string representation
324+
**/
313325
const std::string get_querystring() const
314326
{
315327
return this->querystring;
@@ -361,7 +373,7 @@ class http_request
361373
* Default constructor of the class. It is a specific responsibility of apis to initialize this type of objects.
362374
**/
363375
http_request():
364-
content("")
376+
content(""), content_size_limit(static_cast<size_t>(-1))
365377
{
366378
}
367379
/**
@@ -381,6 +393,7 @@ class http_request
381393
args(b.args),
382394
querystring(b.querystring),
383395
content(b.content),
396+
content_size_limit(b.content_size_limit),
384397
version(b.version),
385398
requestor(b.requestor),
386399
underlying_connection(b.underlying_connection)
@@ -398,6 +411,7 @@ class http_request
398411
std::map<std::string, std::string, http::arg_comparator> args;
399412
std::string querystring;
400413
std::string content;
414+
size_t content_size_limit;
401415
std::string version;
402416
std::string requestor;
403417

@@ -442,11 +456,7 @@ class http_request
442456
**/
443457
void set_arg(const std::string& key, const std::string& value)
444458
{
445-
if (this->args[key].empty()) {
446-
this->args[key] = value;
447-
} else {
448-
this->args[key].append(value);
449-
}
459+
this->args[key] = value.substr(0,content_size_limit);
450460
}
451461
/**
452462
* Method used to set an argument value by key.
@@ -456,19 +466,24 @@ class http_request
456466
**/
457467
void set_arg(const char* key, const char* value, size_t size)
458468
{
459-
if (this->args[key].empty()) {
460-
this->args[key] = std::string(value, size);
461-
} else {
462-
this->args[key].append(value, size);
463-
}
469+
this->args[key] = std::string(value,
470+
std::min(size, content_size_limit));
464471
}
465472
/**
466473
* Method used to set the content of the request
467474
* @param content The content to set.
468475
**/
469476
void set_content(const std::string& content)
470477
{
471-
this->content = content;
478+
this->content = content.substr(0,content_size_limit);
479+
}
480+
/**
481+
* Method used to set the maximum size of the content
482+
* @param content_size_limit The limit on the maximum size of the content and arg's.
483+
**/
484+
void set_content_size_limit(size_t content_size_limit)
485+
{
486+
this->content_size_limit = content_size_limit;
472487
}
473488
/**
474489
* Method used to append content to the request preserving the previous inserted content
@@ -478,6 +493,10 @@ class http_request
478493
void grow_content(const char* content, size_t size)
479494
{
480495
this->content.append(content, size);
496+
if (this->content.size() > content_size_limit)
497+
{
498+
this->content.resize (content_size_limit);
499+
}
481500
}
482501
/**
483502
* Method used to set the path requested.
@@ -568,7 +587,7 @@ class http_request
568587
{
569588
std::map<std::string, std::string>::const_iterator it;
570589
for(it = args.begin(); it != args.end(); ++it)
571-
this->args[it->first] = it->second;
590+
this->args[it->first] = it->second.substr(0,content_size_limit);
572591
}
573592
/**
574593
* Method used to set the username of the request.

src/httpserver/webserver.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ class webserver
179179
const int max_threads;
180180
const int max_connections;
181181
const int memory_limit;
182+
const size_t content_size_limit;
182183
const int connection_timeout;
183184
const int per_IP_connection_limit;
184185
log_access_ptr log_access;

src/webserver.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ webserver::webserver(const create_webserver& params):
141141
max_threads(params._max_threads),
142142
max_connections(params._max_connections),
143143
memory_limit(params._memory_limit),
144+
content_size_limit(params._content_size_limit),
144145
connection_timeout(params._connection_timeout),
145146
per_IP_connection_limit(params._per_IP_connection_limit),
146147
log_access(params._log_access),
@@ -594,7 +595,7 @@ int webserver::post_iterator (void *cls, enum MHD_ValueKind kind,
594595
)
595596
{
596597
struct details::modded_request* mr = (struct details::modded_request*) cls;
597-
mr->dhr->set_arg(key, data, size);
598+
mr->dhr->set_arg(key, mr->dhr->get_arg(key) + std::string(data, size));
598599
return MHD_YES;
599600
}
600601

@@ -654,6 +655,7 @@ int webserver::bodyfull_requests_answer_first_step(
654655
{
655656
mr->second = true;
656657
mr->dhr = new http_request();
658+
mr->dhr->set_content_size_limit(content_size_limit);
657659
const char *encoding = MHD_lookup_connection_value (
658660
connection,
659661
MHD_HEADER_KIND,

0 commit comments

Comments
 (0)