mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 11:05:54 +00:00
Improved beast::http::message:
* Add headers::erase * Set http::message version with std::pair * Use std::pair for headers::value_type
This commit is contained in:
@@ -38,11 +38,7 @@ namespace http {
|
|||||||
class headers
|
class headers
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
struct value_type
|
using value_type = std::pair<std::string, std::string>;
|
||||||
{
|
|
||||||
std::string field;
|
|
||||||
std::string value;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct element
|
struct element
|
||||||
@@ -139,6 +135,13 @@ public:
|
|||||||
void
|
void
|
||||||
clear() noexcept;
|
clear() noexcept;
|
||||||
|
|
||||||
|
/** Remove a field.
|
||||||
|
@return The number of fields removed.
|
||||||
|
*/
|
||||||
|
template <class = void>
|
||||||
|
std::size_t
|
||||||
|
erase (std::string const& field);
|
||||||
|
|
||||||
/** Append a field value.
|
/** Append a field value.
|
||||||
If a field value already exists the new value will be
|
If a field value already exists the new value will be
|
||||||
extended as per RFC2616 Section 4.2.
|
extended as per RFC2616 Section 4.2.
|
||||||
@@ -164,8 +167,8 @@ template <class>
|
|||||||
headers::element::element (
|
headers::element::element (
|
||||||
std::string const& f, std::string const& v)
|
std::string const& f, std::string const& v)
|
||||||
{
|
{
|
||||||
data.field = f;
|
data.first = f;
|
||||||
data.value = v;
|
data.second = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class String>
|
template <class String>
|
||||||
@@ -173,7 +176,7 @@ bool
|
|||||||
headers::less::operator() (
|
headers::less::operator() (
|
||||||
String const& lhs, element const& rhs) const
|
String const& lhs, element const& rhs) const
|
||||||
{
|
{
|
||||||
return beast::ci_less::operator() (lhs, rhs.data.field);
|
return beast::ci_less::operator() (lhs, rhs.data.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class String>
|
template <class String>
|
||||||
@@ -181,7 +184,7 @@ bool
|
|||||||
headers::less::operator() (
|
headers::less::operator() (
|
||||||
element const& lhs, String const& rhs) const
|
element const& lhs, String const& rhs) const
|
||||||
{
|
{
|
||||||
return beast::ci_less::operator() (lhs.data.field, rhs);
|
return beast::ci_less::operator() (lhs.data.first, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@@ -210,7 +213,7 @@ inline
|
|||||||
headers::headers (headers const& other)
|
headers::headers (headers const& other)
|
||||||
{
|
{
|
||||||
for (auto const& e : other.list_)
|
for (auto const& e : other.list_)
|
||||||
append (e.data.field, e.data.value);
|
append (e.data.first, e.data.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
@@ -219,7 +222,7 @@ headers::operator= (headers const& other)
|
|||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
for (auto const& e : other.list_)
|
for (auto const& e : other.list_)
|
||||||
append (e.data.field, e.data.value);
|
append (e.data.first, e.data.second);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,7 +272,7 @@ headers::operator[] (std::string const& field) const
|
|||||||
auto const found (find (field));
|
auto const found (find (field));
|
||||||
if (found == end())
|
if (found == end())
|
||||||
return none;
|
return none;
|
||||||
return found->value;
|
return found->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class>
|
template <class>
|
||||||
@@ -280,6 +283,20 @@ headers::clear() noexcept
|
|||||||
delete &(*iter++);
|
delete &(*iter++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class>
|
||||||
|
std::size_t
|
||||||
|
headers::erase (std::string const& field)
|
||||||
|
{
|
||||||
|
auto const iter = set_.find(field, less{});
|
||||||
|
if (iter == set_.end())
|
||||||
|
return 0;
|
||||||
|
element& e = *iter;
|
||||||
|
set_.erase(set_.iterator_to(e));
|
||||||
|
list_.erase(list_.iterator_to(e));
|
||||||
|
delete &e;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
template <class>
|
template <class>
|
||||||
void
|
void
|
||||||
headers::append (std::string const& field,
|
headers::append (std::string const& field,
|
||||||
@@ -296,7 +313,7 @@ headers::append (std::string const& field,
|
|||||||
}
|
}
|
||||||
// If field already exists, append comma
|
// If field already exists, append comma
|
||||||
// separated value as per RFC2616 section 4.2
|
// separated value as per RFC2616 section 4.2
|
||||||
auto& cur (result.first->data.value);
|
auto& cur (result.first->data.second);
|
||||||
cur.reserve (cur.size() + 1 + value.size());
|
cur.reserve (cur.size() + 1 + value.size());
|
||||||
cur.append (1, ',');
|
cur.append (1, ',');
|
||||||
cur.append (value);
|
cur.append (value);
|
||||||
@@ -304,6 +321,36 @@ headers::append (std::string const& field,
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <class Streambuf>
|
||||||
|
void
|
||||||
|
write (Streambuf& stream, std::string const& s)
|
||||||
|
{
|
||||||
|
stream.commit (boost::asio::buffer_copy (
|
||||||
|
stream.prepare (s.size()), boost::asio::buffer(s)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Streambuf>
|
||||||
|
void
|
||||||
|
write (Streambuf& stream, char const* s)
|
||||||
|
{
|
||||||
|
auto const len (::strlen(s));
|
||||||
|
stream.commit (boost::asio::buffer_copy (
|
||||||
|
stream.prepare (len), boost::asio::buffer (s, len)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Streambuf>
|
||||||
|
void
|
||||||
|
write (Streambuf& stream, headers const& h)
|
||||||
|
{
|
||||||
|
for (auto const& _ : h)
|
||||||
|
{
|
||||||
|
write (stream, _.first);
|
||||||
|
write (stream, ": ");
|
||||||
|
write (stream, _.second);
|
||||||
|
write (stream, "\r\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <class>
|
template <class>
|
||||||
std::string
|
std::string
|
||||||
to_string (headers const& h)
|
to_string (headers const& h)
|
||||||
@@ -311,13 +358,13 @@ to_string (headers const& h)
|
|||||||
std::string s;
|
std::string s;
|
||||||
std::size_t n (0);
|
std::size_t n (0);
|
||||||
for (auto const& e : h)
|
for (auto const& e : h)
|
||||||
n += e.field.size() + 2 + e.value.size() + 2;
|
n += e.first.size() + 2 + e.second.size() + 2;
|
||||||
s.reserve (n);
|
s.reserve (n);
|
||||||
for (auto const& e : h)
|
for (auto const& e : h)
|
||||||
{
|
{
|
||||||
s.append (e.field);
|
s.append (e.first);
|
||||||
s.append (": ");
|
s.append (": ");
|
||||||
s.append (e.value);
|
s.append (e.second);
|
||||||
s.append ("\r\n");
|
s.append ("\r\n");
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
@@ -338,10 +385,10 @@ build_map (headers const& h)
|
|||||||
std::map <std::string, std::string> c;
|
std::map <std::string, std::string> c;
|
||||||
for (auto const& e : h)
|
for (auto const& e : h)
|
||||||
{
|
{
|
||||||
auto key (e.field);
|
auto key (e.first);
|
||||||
// TODO Replace with safe C++14 version
|
// TODO Replace with safe C++14 version
|
||||||
std::transform (key.begin(), key.end(), key.begin(), ::tolower);
|
std::transform (key.begin(), key.end(), key.begin(), ::tolower);
|
||||||
c [key] = e.value;
|
c [key] = e.second;
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,20 @@
|
|||||||
namespace beast {
|
namespace beast {
|
||||||
namespace http {
|
namespace http {
|
||||||
|
|
||||||
|
inline
|
||||||
|
std::pair<int, int>
|
||||||
|
http_1_0()
|
||||||
|
{
|
||||||
|
return std::pair<int, int>(1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
std::pair<int, int>
|
||||||
|
http_1_1()
|
||||||
|
{
|
||||||
|
return std::pair<int, int>(1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
class message
|
class message
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@@ -178,6 +192,12 @@ public:
|
|||||||
version_ = std::make_pair (major, minor);
|
version_ = std::make_pair (major, minor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
version (std::pair<int, int> p)
|
||||||
|
{
|
||||||
|
version_ = p;
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<int, int>
|
std::pair<int, int>
|
||||||
version() const
|
version() const
|
||||||
{
|
{
|
||||||
@@ -233,23 +253,6 @@ message::operator= (message&& other)
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
template <class Streambuf>
|
|
||||||
void
|
|
||||||
write (Streambuf& stream, std::string const& s)
|
|
||||||
{
|
|
||||||
stream.commit (boost::asio::buffer_copy (
|
|
||||||
stream.prepare (s.size()), boost::asio::buffer(s)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Streambuf>
|
|
||||||
void
|
|
||||||
write (Streambuf& stream, char const* s)
|
|
||||||
{
|
|
||||||
auto const len (::strlen(s));
|
|
||||||
stream.commit (boost::asio::buffer_copy (
|
|
||||||
stream.prepare (len), boost::asio::buffer (s, len)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class Streambuf>
|
template <class Streambuf>
|
||||||
void
|
void
|
||||||
write (Streambuf& stream, message const& m)
|
write (Streambuf& stream, message const& m)
|
||||||
@@ -276,13 +279,7 @@ write (Streambuf& stream, message const& m)
|
|||||||
write (stream, m.reason());
|
write (stream, m.reason());
|
||||||
}
|
}
|
||||||
write (stream, "\r\n");
|
write (stream, "\r\n");
|
||||||
for (auto const& header : m.headers)
|
write(stream, m.headers);
|
||||||
{
|
|
||||||
write (stream, header.field);
|
|
||||||
write (stream, ": ");
|
|
||||||
write (stream, header.value);
|
|
||||||
write (stream, "\r\n");
|
|
||||||
}
|
|
||||||
write (stream, "\r\n");
|
write (stream, "\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,9 +58,19 @@ public:
|
|||||||
log << "|" << result.first.headers["Field"] << "|";
|
log << "|" << result.first.headers["Field"] << "|";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
test_headers()
|
||||||
|
{
|
||||||
|
headers h;
|
||||||
|
h.append("Field", "Value");
|
||||||
|
expect (h.erase("Field") == 1);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
run()
|
run()
|
||||||
{
|
{
|
||||||
|
test_headers();
|
||||||
|
|
||||||
{
|
{
|
||||||
std::string const text =
|
std::string const text =
|
||||||
"GET / HTTP/1.1\r\n"
|
"GET / HTTP/1.1\r\n"
|
||||||
|
|||||||
Reference in New Issue
Block a user