aboutsummaryrefslogtreecommitdiff
path: root/web
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2016-03-01 19:56:02 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2016-03-02 17:34:20 +0300
commit0f9c65e489a7b59f76ccbf2ca6e76ab0a1012932 (patch)
tree4de95bfa0a76b838474176e8bb308e43368353b3 /web
parent4fec7e73201ed50e4a4157cb1ea1f1c63566dd89 (diff)
Fix web server responding with internal server error on POST request with empty body
Diffstat (limited to 'web')
-rw-r--r--web/apache/request.cxx6
-rw-r--r--web/apache/request.ixx35
2 files changed, 25 insertions, 16 deletions
diff --git a/web/apache/request.cxx b/web/apache/request.cxx
index cf3c888..2e03190 100644
--- a/web/apache/request.cxx
+++ b/web/apache/request.cxx
@@ -97,7 +97,7 @@ namespace web
for (auto h (reinterpret_cast<const apr_table_entry_t *> (ha->elts));
n--; ++h)
{
- if (::strcasecmp (h->key, "Cookie") == 0)
+ if (strcasecmp (h->key, "Cookie") == 0)
{
for (const char* n (h->val); n != nullptr; )
{
@@ -136,8 +136,8 @@ namespace web
content (status_code status, const string& type, bool buffer)
{
if (out_ && status == rec_->status && buffer == buffer_ &&
- ::strcasecmp (rec_->content_type ? rec_->content_type : "",
- type.c_str ()) == 0)
+ strcasecmp (rec_->content_type ? rec_->content_type : "",
+ type.c_str ()) == 0)
{
return *out_;
}
diff --git a/web/apache/request.ixx b/web/apache/request.ixx
index b3528d7..8a3b32b 100644
--- a/web/apache/request.ixx
+++ b/web/apache/request.ixx
@@ -2,7 +2,7 @@
// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
-#include <strings.h> // strcasecmp()
+#include <strings.h> // strncasecmp()
#include <iomanip>
#include <sstream>
@@ -53,22 +53,31 @@ namespace web
if (!form_data_)
{
form_data_.reset (new std::string ());
- const char* ct (apr_table_get (rec_->headers_in, "Content-Type"));
- if (ct &&
- strncasecmp ("application/x-www-form-urlencoded", ct, 33) == 0)
+ if (rec_->method_number == M_POST)
{
- std::istream& istr (content ());
- std::getline (istr, *form_data_);
+ const char* ct (apr_table_get (rec_->headers_in, "Content-Type"));
- // Make request data still be available.
- //
- std::unique_ptr<std::streambuf> in_buf (
- new std::stringbuf (*form_data_));
+ if (ct != nullptr &&
+ strncasecmp ("application/x-www-form-urlencoded", ct, 33) == 0)
+ {
+ std::istream& istr (content ());
+
+ // Do not throw when eofbit is set (end of stream reached), and
+ // when failbit is set (getline() failed to extract any character).
+ //
+ istr.exceptions (std::ios::badbit);
+ std::getline (istr, *form_data_);
- in_.reset (new std::istream (in_buf.get ()));
- in_buf_ = std::move (in_buf);
- in_->exceptions (std::ios::failbit | std::ios::badbit);
+ // Make this data the content of the input stream.
+ //
+ std::unique_ptr<std::streambuf> in_buf (
+ new std::stringbuf (*form_data_));
+
+ in_.reset (new std::istream (in_buf.get ()));
+ in_buf_ = std::move (in_buf);
+ in_->exceptions (std::ios::failbit | std::ios::badbit);
+ }
}
}