From 193f1cec62b6f060d442df5366c82bd06f922e4a Mon Sep 17 00:00:00 2001 From: Radoslaw Zarzynski Date: Wed, 5 Oct 2016 23:17:17 +0200 Subject: [PATCH] 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 -H "X-First;" -H "X-Second: bla" What Beast's client would see is a single header named as "X-FirstX-Second". --- CHANGELOG.md | 1 + include/beast/http/parser_v1.hpp | 16 ++++++++++------ test/websocket/stream.cpp | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac9e3bfe38..ea4e0b90b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Fix message_v1 constructor * Tidy up DynamicBuffer requirements * Tidy up error types and headers +* Fix handling empty HTTP headers in parser_v1 -------------------------------------------------------------------------------- diff --git a/include/beast/http/parser_v1.hpp b/include/beast/http/parser_v1.hpp index aada5243b5..643c4d3755 100644 --- a/include/beast/http/parser_v1.hpp +++ b/include/beast/http/parser_v1.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -94,6 +95,7 @@ class parser_v1 message_type m_; typename message_type::body_type::reader r_; std::uint8_t skip_body_ = 0; + bool flush_ = false; public: parser_v1(parser_v1&&) = default; @@ -161,12 +163,13 @@ class parser_v1 void flush() { - if(! value_.empty()) - { - m_.headers.insert(field_, value_); - field_.clear(); - value_.clear(); - } + if(! flush_) + return; + flush_ = false; + BOOST_ASSERT(! field_.empty()); + m_.headers.insert(field_, value_); + field_.clear(); + value_.clear(); } void on_start(error_code&) @@ -197,6 +200,7 @@ class parser_v1 void on_value(boost::string_ref const& s, error_code&) { value_.append(s.data(), s.size()); + flush_ = true; } void set(std::true_type) diff --git a/test/websocket/stream.cpp b/test/websocket/stream.cpp index 618e54f05a..76aaecc43f 100644 --- a/test/websocket/stream.cpp +++ b/test/websocket/stream.cpp @@ -263,7 +263,7 @@ class stream_test } catch(system_error const& se) { - BEAST_EXPECT(se.code() == ev); + BEAST_EXPECTS(se.code() == ev, se.what()); } } };