diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2016-03-01 19:56:02 +0300 |
---|---|---|
committer | Karen Arutyunov <karen@codesynthesis.com> | 2016-03-02 17:34:20 +0300 |
commit | 0f9c65e489a7b59f76ccbf2ca6e76ab0a1012932 (patch) | |
tree | 4de95bfa0a76b838474176e8bb308e43368353b3 /web | |
parent | 4fec7e73201ed50e4a4157cb1ea1f1c63566dd89 (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.cxx | 6 | ||||
-rw-r--r-- | web/apache/request.ixx | 35 |
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); + } } } |