Fix handling empty HTTP headers in parser_v1.hpp

This patch rectifies flush() of beast::http::parser_v1
to properly handle the case when an HTTP header has
empty value.

Without the fix an empty-valued HTTP header is being
concatenated with the header directly following it.
This situation can be replicated using eg. curl:

  curl <url> -H "X-First;" -H "X-Second: bla"

What Beast's client would see is a single header named
as "X-FirstX-Second".
This commit is contained in:
Radoslaw Zarzynski
2016-10-05 23:17:17 +02:00
committed by Vinnie Falco
parent 843d7a5a9c
commit bc665ee1ec
3 changed files with 12 additions and 7 deletions

View File

@@ -6,6 +6,7 @@
* Fix message_v1 constructor * Fix message_v1 constructor
* Tidy up DynamicBuffer requirements * Tidy up DynamicBuffer requirements
* Tidy up error types and headers * Tidy up error types and headers
* Fix handling empty HTTP headers in parser_v1
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------

View File

@@ -12,6 +12,7 @@
#include <beast/http/concepts.hpp> #include <beast/http/concepts.hpp>
#include <beast/http/message_v1.hpp> #include <beast/http/message_v1.hpp>
#include <beast/core/error.hpp> #include <beast/core/error.hpp>
#include <boost/assert.hpp>
#include <functional> #include <functional>
#include <string> #include <string>
#include <type_traits> #include <type_traits>
@@ -94,6 +95,7 @@ private:
message_type m_; message_type m_;
typename message_type::body_type::reader r_; typename message_type::body_type::reader r_;
std::uint8_t skip_body_ = 0; std::uint8_t skip_body_ = 0;
bool flush_ = false;
public: public:
parser_v1(parser_v1&&) = default; parser_v1(parser_v1&&) = default;
@@ -161,13 +163,14 @@ private:
void flush() void flush()
{ {
if(! value_.empty()) if(! flush_)
{ return;
flush_ = false;
BOOST_ASSERT(! field_.empty());
m_.headers.insert(field_, value_); m_.headers.insert(field_, value_);
field_.clear(); field_.clear();
value_.clear(); value_.clear();
} }
}
void on_start(error_code&) void on_start(error_code&)
{ {
@@ -197,6 +200,7 @@ private:
void on_value(boost::string_ref const& s, error_code&) void on_value(boost::string_ref const& s, error_code&)
{ {
value_.append(s.data(), s.size()); value_.append(s.data(), s.size());
flush_ = true;
} }
void set(std::true_type) void set(std::true_type)

View File

@@ -263,7 +263,7 @@ public:
} }
catch(system_error const& se) catch(system_error const& se)
{ {
BEAST_EXPECT(se.code() == ev); BEAST_EXPECTS(se.code() == ev, se.what());
} }
} }
}; };