2017-07-20 08:01:46 -07:00
|
|
|
//
|
2017-02-06 20:07:03 -05:00
|
|
|
// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
2017-07-20 08:01:46 -07:00
|
|
|
//
|
|
|
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
|
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
|
//
|
|
|
|
|
|
2017-04-27 17:38:50 -07:00
|
|
|
#ifndef BEAST_HTTP_IMPL_FIELDS_IPP
|
|
|
|
|
#define BEAST_HTTP_IMPL_FIELDS_IPP
|
2017-07-20 08:01:46 -07:00
|
|
|
|
2017-06-05 21:11:33 -07:00
|
|
|
#include <beast/core/static_string.hpp>
|
2016-05-24 06:17:04 -04:00
|
|
|
#include <beast/http/detail/rfc7230.hpp>
|
2017-06-05 09:58:55 -07:00
|
|
|
#include <boost/throw_exception.hpp>
|
2016-07-04 13:57:59 -04:00
|
|
|
#include <algorithm>
|
2016-05-24 06:17:04 -04:00
|
|
|
|
2017-07-20 08:01:46 -07:00
|
|
|
namespace beast {
|
|
|
|
|
namespace http {
|
|
|
|
|
|
2017-06-05 09:58:55 -07:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
~basic_fields()
|
|
|
|
|
{
|
|
|
|
|
delete_all();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
2017-06-05 19:28:17 -07:00
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
inline
|
|
|
|
|
string_view
|
|
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
method_impl() const
|
|
|
|
|
{
|
|
|
|
|
return (*this)[":method"];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
inline
|
|
|
|
|
string_view
|
|
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
target_impl() const
|
|
|
|
|
{
|
|
|
|
|
return (*this)[":target"];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
inline
|
|
|
|
|
string_view
|
|
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
reason_impl() const
|
|
|
|
|
{
|
|
|
|
|
return (*this)[":reason"];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
inline
|
|
|
|
|
void
|
|
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
method_impl(string_view s)
|
|
|
|
|
{
|
|
|
|
|
if(s.empty())
|
|
|
|
|
this->erase(":method");
|
|
|
|
|
else
|
|
|
|
|
this->replace(":method", s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
inline
|
|
|
|
|
void
|
|
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
target_impl(string_view s)
|
|
|
|
|
{
|
|
|
|
|
if(s.empty())
|
|
|
|
|
this->erase(":target");
|
|
|
|
|
else
|
2017-06-05 21:11:33 -07:00
|
|
|
this->replace(":target", s);
|
2017-06-05 19:28:17 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
inline
|
|
|
|
|
void
|
|
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
reason_impl(string_view s)
|
|
|
|
|
{
|
|
|
|
|
if(s.empty())
|
|
|
|
|
this->erase(":reason");
|
|
|
|
|
else
|
|
|
|
|
this->replace(":reason", s);
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-05 21:11:33 -07:00
|
|
|
template<class Allocator>
|
|
|
|
|
inline
|
|
|
|
|
void
|
|
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
content_length_impl(std::uint64_t n)
|
|
|
|
|
{
|
|
|
|
|
this->erase("Content-Length");
|
|
|
|
|
this->insert("Content-Length",
|
|
|
|
|
to_static_string(n));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
inline
|
|
|
|
|
void
|
|
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
connection_impl(close_t)
|
|
|
|
|
{
|
|
|
|
|
auto it = find("Connection");
|
|
|
|
|
if(it == end())
|
|
|
|
|
this->insert("Connection", "close");
|
|
|
|
|
else
|
|
|
|
|
this->replace("Connection",
|
|
|
|
|
it->value().to_string() + ", close");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
inline
|
|
|
|
|
void
|
|
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
connection_impl(keep_alive_t)
|
|
|
|
|
{
|
|
|
|
|
auto it = find("Connection");
|
|
|
|
|
if(it == end())
|
|
|
|
|
this->insert("Connection", "keep-alive");
|
|
|
|
|
else
|
|
|
|
|
this->replace("Connection",
|
|
|
|
|
it->value().to_string() + ", keep-alive");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
inline
|
|
|
|
|
void
|
|
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
connection_impl(upgrade_t)
|
|
|
|
|
{
|
|
|
|
|
auto it = find("Connection");
|
|
|
|
|
if(it == end())
|
|
|
|
|
this->insert("Connection", "upgrade");
|
|
|
|
|
else
|
|
|
|
|
this->replace("Connection",
|
|
|
|
|
it->value().to_string() + ", upgrade");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
inline
|
|
|
|
|
void
|
|
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
chunked_impl()
|
|
|
|
|
{
|
|
|
|
|
auto it = find("Transfer-Encoding");
|
|
|
|
|
if(it == end())
|
|
|
|
|
this->insert("Transfer-Encoding", "chunked");
|
|
|
|
|
else
|
|
|
|
|
this->replace("Transfer-Encoding",
|
|
|
|
|
it->value().to_string() + ", chunked");
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-05 19:28:17 -07:00
|
|
|
//------------------------------------------------------------------------------
|
2017-06-05 09:58:55 -07:00
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
class basic_fields<Allocator>::
|
|
|
|
|
const_iterator
|
|
|
|
|
{
|
|
|
|
|
using iter_type = typename list_t::const_iterator;
|
|
|
|
|
|
|
|
|
|
iter_type it_;
|
|
|
|
|
|
|
|
|
|
template<class Alloc>
|
|
|
|
|
friend class beast::http::basic_fields;
|
|
|
|
|
|
|
|
|
|
const_iterator(iter_type it)
|
|
|
|
|
: it_(it)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
using value_type = typename
|
|
|
|
|
basic_fields<Allocator>::value_type;
|
|
|
|
|
using pointer = value_type const*;
|
|
|
|
|
using reference = value_type const&;
|
|
|
|
|
using difference_type = std::ptrdiff_t;
|
|
|
|
|
using iterator_category =
|
|
|
|
|
std::bidirectional_iterator_tag;
|
|
|
|
|
|
|
|
|
|
const_iterator() = default;
|
|
|
|
|
const_iterator(const_iterator&& other) = default;
|
|
|
|
|
const_iterator(const_iterator const& other) = default;
|
|
|
|
|
const_iterator& operator=(const_iterator&& other) = default;
|
|
|
|
|
const_iterator& operator=(const_iterator const& other) = default;
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
operator==(const_iterator const& other) const
|
|
|
|
|
{
|
|
|
|
|
return it_ == other.it_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
operator!=(const_iterator const& other) const
|
|
|
|
|
{
|
|
|
|
|
return !(*this == other);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reference
|
|
|
|
|
operator*() const
|
|
|
|
|
{
|
|
|
|
|
return it_->data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pointer
|
|
|
|
|
operator->() const
|
|
|
|
|
{
|
|
|
|
|
return &**this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const_iterator&
|
|
|
|
|
operator++()
|
|
|
|
|
{
|
|
|
|
|
++it_;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const_iterator
|
|
|
|
|
operator++(int)
|
|
|
|
|
{
|
|
|
|
|
auto temp = *this;
|
|
|
|
|
++(*this);
|
|
|
|
|
return temp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const_iterator&
|
|
|
|
|
operator--()
|
|
|
|
|
{
|
|
|
|
|
--it_;
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const_iterator
|
|
|
|
|
operator--(int)
|
|
|
|
|
{
|
|
|
|
|
auto temp = *this;
|
|
|
|
|
--(*this);
|
|
|
|
|
return temp;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2017-07-20 08:01:46 -07:00
|
|
|
template<class Allocator>
|
|
|
|
|
void
|
2016-11-10 05:34:49 -05:00
|
|
|
basic_fields<Allocator>::
|
2017-07-20 08:01:46 -07:00
|
|
|
delete_all()
|
|
|
|
|
{
|
|
|
|
|
for(auto it = list_.begin(); it != list_.end();)
|
2017-06-05 09:58:55 -07:00
|
|
|
delete_element(*it++);
|
2017-07-20 08:01:46 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
inline
|
|
|
|
|
void
|
2016-11-10 05:34:49 -05:00
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
move_assign(basic_fields& other, std::false_type)
|
2017-07-20 08:01:46 -07:00
|
|
|
{
|
2017-06-05 09:58:55 -07:00
|
|
|
if(alloc_ != other.alloc_)
|
2017-07-20 08:01:46 -07:00
|
|
|
{
|
|
|
|
|
copy_from(other);
|
|
|
|
|
other.clear();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
set_ = std::move(other.set_);
|
|
|
|
|
list_ = std::move(other.list_);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
inline
|
|
|
|
|
void
|
2016-11-10 05:34:49 -05:00
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
move_assign(basic_fields& other, std::true_type)
|
2017-07-20 08:01:46 -07:00
|
|
|
{
|
2017-06-05 09:58:55 -07:00
|
|
|
alloc_ = std::move(other.alloc_);
|
2017-07-20 08:01:46 -07:00
|
|
|
set_ = std::move(other.set_);
|
|
|
|
|
list_ = std::move(other.list_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
inline
|
|
|
|
|
void
|
2016-11-10 05:34:49 -05:00
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
copy_assign(basic_fields const& other, std::false_type)
|
2017-07-20 08:01:46 -07:00
|
|
|
{
|
|
|
|
|
copy_from(other);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
inline
|
|
|
|
|
void
|
2016-11-10 05:34:49 -05:00
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
copy_assign(basic_fields const& other, std::true_type)
|
2017-07-20 08:01:46 -07:00
|
|
|
{
|
2017-06-05 09:58:55 -07:00
|
|
|
alloc_ = other.alloc_;
|
2017-07-20 08:01:46 -07:00
|
|
|
copy_from(other);
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-05 09:58:55 -07:00
|
|
|
template<class Allocator>
|
|
|
|
|
auto
|
|
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
new_element(string_view name, string_view value) ->
|
|
|
|
|
element&
|
|
|
|
|
{
|
|
|
|
|
if(name.size() + 2 >
|
|
|
|
|
(std::numeric_limits<off_t>::max)())
|
|
|
|
|
BOOST_THROW_EXCEPTION(std::length_error{
|
|
|
|
|
"field name too large"});
|
|
|
|
|
if(value.size() + 2 >
|
|
|
|
|
(std::numeric_limits<off_t>::max)())
|
|
|
|
|
BOOST_THROW_EXCEPTION(std::length_error{
|
|
|
|
|
"field value too large"});
|
|
|
|
|
value = detail::trim(value);
|
|
|
|
|
std::uint16_t const off =
|
|
|
|
|
static_cast<off_t>(name.size() + 2);
|
|
|
|
|
std::uint16_t const len =
|
|
|
|
|
static_cast<off_t>(value.size());
|
|
|
|
|
auto const p = alloc_traits::allocate(alloc_,
|
|
|
|
|
1 + (off + len + 2 + sizeof(element) - 1) /
|
|
|
|
|
sizeof(element));
|
|
|
|
|
alloc_traits::construct(alloc_, p, name, value);
|
|
|
|
|
return *p;
|
|
|
|
|
}
|
2017-07-20 08:01:46 -07:00
|
|
|
|
|
|
|
|
template<class Allocator>
|
2017-06-05 09:58:55 -07:00
|
|
|
void
|
2016-11-10 05:34:49 -05:00
|
|
|
basic_fields<Allocator>::
|
2017-06-05 09:58:55 -07:00
|
|
|
delete_element(element& e)
|
2017-07-20 08:01:46 -07:00
|
|
|
{
|
2017-06-05 09:58:55 -07:00
|
|
|
auto const n = 1 +
|
|
|
|
|
(e.data.off + e.data.len + 2 +
|
|
|
|
|
sizeof(element) - 1) / sizeof(element);
|
|
|
|
|
alloc_traits::destroy(alloc_, &e);
|
|
|
|
|
alloc_traits::deallocate(alloc_, &e, n);
|
2017-07-20 08:01:46 -07:00
|
|
|
}
|
|
|
|
|
|
2017-06-05 09:58:55 -07:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
2017-07-20 08:01:46 -07:00
|
|
|
template<class Allocator>
|
2016-11-10 05:34:49 -05:00
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
basic_fields(Allocator const& alloc)
|
2017-06-05 09:58:55 -07:00
|
|
|
: alloc_(alloc)
|
2017-07-20 08:01:46 -07:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
2016-11-10 05:34:49 -05:00
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
basic_fields(basic_fields&& other)
|
2017-06-05 09:58:55 -07:00
|
|
|
: set_(std::move(other.set_))
|
|
|
|
|
, list_(std::move(other.list_))
|
|
|
|
|
, alloc_(std::move(other.alloc_))
|
2017-07-20 08:01:46 -07:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
auto
|
2016-11-10 05:34:49 -05:00
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
operator=(basic_fields&& other) ->
|
|
|
|
|
basic_fields&
|
2017-07-20 08:01:46 -07:00
|
|
|
{
|
|
|
|
|
if(this == &other)
|
|
|
|
|
return *this;
|
|
|
|
|
clear();
|
|
|
|
|
move_assign(other, std::integral_constant<bool,
|
|
|
|
|
alloc_traits::propagate_on_container_move_assignment::value>{});
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
2016-11-10 05:34:49 -05:00
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
basic_fields(basic_fields const& other)
|
|
|
|
|
: basic_fields(alloc_traits::
|
2017-06-05 09:58:55 -07:00
|
|
|
select_on_container_copy_construction(other.alloc_))
|
2017-07-20 08:01:46 -07:00
|
|
|
{
|
|
|
|
|
copy_from(other);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
auto
|
2016-11-10 05:34:49 -05:00
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
operator=(basic_fields const& other) ->
|
|
|
|
|
basic_fields&
|
2017-07-20 08:01:46 -07:00
|
|
|
{
|
|
|
|
|
clear();
|
|
|
|
|
copy_assign(other, std::integral_constant<bool,
|
|
|
|
|
alloc_traits::propagate_on_container_copy_assignment::value>{});
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
template<class OtherAlloc>
|
2016-11-10 05:34:49 -05:00
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
basic_fields(basic_fields<OtherAlloc> const& other)
|
2017-07-20 08:01:46 -07:00
|
|
|
{
|
|
|
|
|
copy_from(other);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
template<class OtherAlloc>
|
|
|
|
|
auto
|
2016-11-10 05:34:49 -05:00
|
|
|
basic_fields<Allocator>::
|
|
|
|
|
operator=(basic_fields<OtherAlloc> const& other) ->
|
|
|
|
|
basic_fields&
|
2017-07-20 08:01:46 -07:00
|
|
|
{
|
|
|
|
|
clear();
|
|
|
|
|
copy_from(other);
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
2016-07-04 13:57:59 -04:00
|
|
|
template<class Allocator>
|
|
|
|
|
std::size_t
|
2016-11-10 05:34:49 -05:00
|
|
|
basic_fields<Allocator>::
|
2017-06-04 10:52:28 -07:00
|
|
|
count(string_view name) const
|
2016-07-04 13:57:59 -04:00
|
|
|
{
|
|
|
|
|
auto const it = set_.find(name, less{});
|
|
|
|
|
if(it == set_.end())
|
|
|
|
|
return 0;
|
|
|
|
|
auto const last = set_.upper_bound(name, less{});
|
|
|
|
|
return static_cast<std::size_t>(std::distance(it, last));
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-20 08:01:46 -07:00
|
|
|
template<class Allocator>
|
|
|
|
|
auto
|
2016-11-10 05:34:49 -05:00
|
|
|
basic_fields<Allocator>::
|
2017-06-04 10:52:28 -07:00
|
|
|
find(string_view name) const ->
|
2017-07-20 08:01:46 -07:00
|
|
|
iterator
|
|
|
|
|
{
|
|
|
|
|
auto const it = set_.find(name, less{});
|
|
|
|
|
if(it == set_.end())
|
|
|
|
|
return list_.end();
|
|
|
|
|
return list_.iterator_to(*it);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
2017-05-05 14:45:15 -07:00
|
|
|
string_view const
|
2016-11-10 05:34:49 -05:00
|
|
|
basic_fields<Allocator>::
|
2017-06-04 10:52:28 -07:00
|
|
|
operator[](string_view name) const
|
2017-07-20 08:01:46 -07:00
|
|
|
{
|
|
|
|
|
auto const it = find(name);
|
|
|
|
|
if(it == end())
|
2016-07-04 13:57:59 -04:00
|
|
|
return {};
|
2017-06-05 09:58:55 -07:00
|
|
|
return it->value();
|
2017-07-20 08:01:46 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
void
|
2016-11-10 05:34:49 -05:00
|
|
|
basic_fields<Allocator>::
|
2017-07-20 08:01:46 -07:00
|
|
|
clear() noexcept
|
|
|
|
|
{
|
|
|
|
|
delete_all();
|
|
|
|
|
list_.clear();
|
|
|
|
|
set_.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
std::size_t
|
2016-11-10 05:34:49 -05:00
|
|
|
basic_fields<Allocator>::
|
2017-06-04 10:52:28 -07:00
|
|
|
erase(string_view name)
|
2017-07-20 08:01:46 -07:00
|
|
|
{
|
2016-07-04 13:57:59 -04:00
|
|
|
auto it = set_.find(name, less{});
|
2017-07-20 08:01:46 -07:00
|
|
|
if(it == set_.end())
|
|
|
|
|
return 0;
|
2016-07-04 13:57:59 -04:00
|
|
|
auto const last = set_.upper_bound(name, less{});
|
|
|
|
|
std::size_t n = 1;
|
|
|
|
|
for(;;)
|
|
|
|
|
{
|
|
|
|
|
auto& e = *it++;
|
|
|
|
|
set_.erase(set_.iterator_to(e));
|
|
|
|
|
list_.erase(list_.iterator_to(e));
|
2017-06-05 09:58:55 -07:00
|
|
|
delete_element(e);
|
2016-07-04 13:57:59 -04:00
|
|
|
if(it == last)
|
|
|
|
|
break;
|
|
|
|
|
++n;
|
|
|
|
|
}
|
|
|
|
|
return n;
|
2017-07-20 08:01:46 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
void
|
2016-11-10 05:34:49 -05:00
|
|
|
basic_fields<Allocator>::
|
2017-06-04 12:38:42 -07:00
|
|
|
insert(string_view name, string_view value)
|
2017-07-20 08:01:46 -07:00
|
|
|
{
|
2017-06-05 09:58:55 -07:00
|
|
|
auto& e = new_element(name, value);
|
|
|
|
|
set_.insert_before(set_.upper_bound(name, less{}), e);
|
|
|
|
|
list_.push_back(e);
|
2017-07-20 08:01:46 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class Allocator>
|
|
|
|
|
void
|
2016-11-10 05:34:49 -05:00
|
|
|
basic_fields<Allocator>::
|
2017-06-04 12:38:42 -07:00
|
|
|
replace(string_view name, string_view value)
|
2017-07-20 08:01:46 -07:00
|
|
|
{
|
2016-05-24 06:17:04 -04:00
|
|
|
value = detail::trim(value);
|
2017-07-20 08:01:46 -07:00
|
|
|
erase(name);
|
|
|
|
|
insert(name, value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // http
|
|
|
|
|
} // beast
|
|
|
|
|
|
|
|
|
|
#endif
|