2017-05-28 17:04:39 -07:00
|
|
|
//
|
|
|
|
|
// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
|
|
|
|
//
|
|
|
|
|
// 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)
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
#ifndef BEAST_HTTP_IMPL_SERIALIZER_IPP
|
|
|
|
|
#define BEAST_HTTP_IMPL_SERIALIZER_IPP
|
|
|
|
|
|
|
|
|
|
#include <beast/http/error.hpp>
|
2017-05-30 15:02:14 -07:00
|
|
|
#include <beast/http/status.hpp>
|
2017-06-26 17:20:42 -07:00
|
|
|
#include <beast/core/detail/config.hpp>
|
2017-05-28 17:04:39 -07:00
|
|
|
#include <boost/assert.hpp>
|
|
|
|
|
#include <ostream>
|
|
|
|
|
|
|
|
|
|
namespace beast {
|
|
|
|
|
namespace http {
|
|
|
|
|
|
2017-06-07 05:10:58 -07:00
|
|
|
template<bool isRequest, class Body,
|
|
|
|
|
class Fields, class ChunkDecorator>
|
2017-05-28 17:04:39 -07:00
|
|
|
void
|
2017-06-07 05:10:58 -07:00
|
|
|
serializer<isRequest, Body, Fields, ChunkDecorator>::
|
2017-06-06 17:26:11 -07:00
|
|
|
frdinit(std::true_type)
|
2017-05-28 17:04:39 -07:00
|
|
|
{
|
2017-06-06 17:26:11 -07:00
|
|
|
frd_.emplace(m_, m_.version, m_.method());
|
2017-05-28 17:04:39 -07:00
|
|
|
}
|
|
|
|
|
|
2017-06-07 05:10:58 -07:00
|
|
|
template<bool isRequest, class Body,
|
|
|
|
|
class Fields, class ChunkDecorator>
|
2017-05-28 17:04:39 -07:00
|
|
|
void
|
2017-06-07 05:10:58 -07:00
|
|
|
serializer<isRequest, Body, Fields, ChunkDecorator>::
|
2017-06-06 17:26:11 -07:00
|
|
|
frdinit(std::false_type)
|
2017-05-28 17:04:39 -07:00
|
|
|
{
|
2017-06-06 17:26:11 -07:00
|
|
|
frd_.emplace(m_, m_.version, m_.result_int());
|
2017-05-28 17:04:39 -07:00
|
|
|
}
|
|
|
|
|
|
2017-06-07 05:10:58 -07:00
|
|
|
template<bool isRequest, class Body,
|
|
|
|
|
class Fields, class ChunkDecorator>
|
|
|
|
|
serializer<isRequest, Body, Fields, ChunkDecorator>::
|
2017-05-28 17:04:39 -07:00
|
|
|
serializer(message<isRequest, Body, Fields> const& m,
|
2017-06-07 05:10:58 -07:00
|
|
|
ChunkDecorator const& d)
|
2017-05-28 17:04:39 -07:00
|
|
|
: m_(m)
|
|
|
|
|
, d_(d)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-07 05:10:58 -07:00
|
|
|
template<bool isRequest, class Body,
|
|
|
|
|
class Fields, class ChunkDecorator>
|
2017-05-28 17:04:39 -07:00
|
|
|
template<class Visit>
|
|
|
|
|
void
|
2017-06-07 05:10:58 -07:00
|
|
|
serializer<isRequest, Body, Fields, ChunkDecorator>::
|
2017-05-28 17:04:39 -07:00
|
|
|
get(error_code& ec, Visit&& visit)
|
|
|
|
|
{
|
|
|
|
|
using boost::asio::buffer_size;
|
|
|
|
|
switch(s_)
|
|
|
|
|
{
|
2017-05-31 08:01:55 -07:00
|
|
|
case do_construct:
|
|
|
|
|
{
|
2017-06-06 17:26:11 -07:00
|
|
|
frdinit(std::integral_constant<bool,
|
|
|
|
|
isRequest>{});
|
2017-06-19 14:35:32 -07:00
|
|
|
close_ = ! frd_->keep_alive();
|
|
|
|
|
if(frd_->chunked())
|
2017-05-31 08:01:55 -07:00
|
|
|
goto go_init_c;
|
|
|
|
|
s_ = do_init;
|
2017-06-26 17:20:42 -07:00
|
|
|
BEAST_FALLTHROUGH;
|
2017-05-31 08:01:55 -07:00
|
|
|
}
|
|
|
|
|
|
2017-05-28 17:04:39 -07:00
|
|
|
case do_init:
|
|
|
|
|
{
|
|
|
|
|
if(split_)
|
|
|
|
|
goto go_header_only;
|
2017-06-25 08:28:41 -07:00
|
|
|
rd_.emplace(m_, ec);
|
2017-05-28 17:04:39 -07:00
|
|
|
if(ec)
|
|
|
|
|
return;
|
|
|
|
|
auto result = rd_->get(ec);
|
2017-06-25 10:14:18 -07:00
|
|
|
if(ec == error::need_more)
|
|
|
|
|
goto go_header_only;
|
2017-05-28 17:04:39 -07:00
|
|
|
if(ec)
|
|
|
|
|
return;
|
|
|
|
|
if(! result)
|
|
|
|
|
goto go_header_only;
|
|
|
|
|
more_ = result->second;
|
|
|
|
|
v_ = cb0_t{
|
|
|
|
|
boost::in_place_init,
|
2017-06-06 17:26:11 -07:00
|
|
|
frd_->get(),
|
2017-05-28 17:04:39 -07:00
|
|
|
result->first};
|
|
|
|
|
s_ = do_header;
|
2017-06-26 17:20:42 -07:00
|
|
|
BEAST_FALLTHROUGH;
|
2017-05-28 17:04:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case do_header:
|
|
|
|
|
visit(ec, boost::get<cb0_t>(v_));
|
|
|
|
|
break;
|
|
|
|
|
|
2017-06-06 17:26:11 -07:00
|
|
|
go_header_only:
|
|
|
|
|
v_ = ch_t{frd_->get()};
|
|
|
|
|
s_ = do_header_only;
|
2017-05-28 17:04:39 -07:00
|
|
|
case do_header_only:
|
2017-06-06 17:26:11 -07:00
|
|
|
visit(ec, boost::get<ch_t>(v_));
|
2017-05-28 17:04:39 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case do_body:
|
2017-06-25 10:14:18 -07:00
|
|
|
if(! rd_)
|
|
|
|
|
{
|
|
|
|
|
rd_.emplace(m_, ec);
|
|
|
|
|
if(ec)
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-05-28 17:04:39 -07:00
|
|
|
s_ = do_body + 1;
|
2017-06-26 17:20:42 -07:00
|
|
|
BEAST_FALLTHROUGH;
|
2017-05-28 17:04:39 -07:00
|
|
|
|
|
|
|
|
case do_body + 1:
|
|
|
|
|
{
|
|
|
|
|
auto result = rd_->get(ec);
|
|
|
|
|
if(ec)
|
|
|
|
|
return;
|
|
|
|
|
if(! result)
|
|
|
|
|
goto go_complete;
|
|
|
|
|
more_ = result->second;
|
|
|
|
|
v_ = cb1_t{result->first};
|
|
|
|
|
s_ = do_body + 2;
|
2017-06-26 17:20:42 -07:00
|
|
|
BEAST_FALLTHROUGH;
|
2017-05-28 17:04:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case do_body + 2:
|
|
|
|
|
visit(ec, boost::get<cb1_t>(v_));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
2017-05-31 08:01:55 -07:00
|
|
|
go_init_c:
|
|
|
|
|
s_ = do_init_c;
|
2017-05-28 17:04:39 -07:00
|
|
|
case do_init_c:
|
|
|
|
|
{
|
|
|
|
|
if(split_)
|
|
|
|
|
goto go_header_only_c;
|
2017-06-25 08:28:41 -07:00
|
|
|
rd_.emplace(m_, ec);
|
2017-05-28 17:04:39 -07:00
|
|
|
if(ec)
|
|
|
|
|
return;
|
|
|
|
|
auto result = rd_->get(ec);
|
2017-06-25 10:14:18 -07:00
|
|
|
if(ec == error::need_more)
|
|
|
|
|
goto go_header_only_c;
|
2017-05-28 17:04:39 -07:00
|
|
|
if(ec)
|
|
|
|
|
return;
|
|
|
|
|
if(! result)
|
|
|
|
|
goto go_header_only_c;
|
|
|
|
|
more_ = result->second;
|
2017-06-26 18:26:35 -07:00
|
|
|
#if ! BEAST_NO_BIG_VARIANTS
|
|
|
|
|
if(! more_)
|
|
|
|
|
{
|
|
|
|
|
// do it all in one buffer
|
|
|
|
|
v_ = ch3_t{
|
|
|
|
|
boost::in_place_init,
|
|
|
|
|
frd_->get(),
|
|
|
|
|
detail::chunk_header{
|
|
|
|
|
buffer_size(result->first)},
|
|
|
|
|
[&]()
|
|
|
|
|
{
|
|
|
|
|
auto sv = d_(result->first);
|
|
|
|
|
return boost::asio::const_buffers_1{
|
|
|
|
|
sv.data(), sv.size()};
|
|
|
|
|
|
|
|
|
|
}(),
|
|
|
|
|
detail::chunk_crlf(),
|
|
|
|
|
result->first,
|
|
|
|
|
detail::chunk_crlf(),
|
|
|
|
|
detail::chunk_final(),
|
|
|
|
|
[&]()
|
|
|
|
|
{
|
|
|
|
|
auto sv = d_(
|
|
|
|
|
boost::asio::null_buffers{});
|
|
|
|
|
return boost::asio::const_buffers_1{
|
|
|
|
|
sv.data(), sv.size()};
|
|
|
|
|
|
|
|
|
|
}(),
|
|
|
|
|
detail::chunk_crlf()};
|
|
|
|
|
goto go_all_c;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2017-05-28 17:04:39 -07:00
|
|
|
v_ = ch0_t{
|
|
|
|
|
boost::in_place_init,
|
2017-06-06 17:26:11 -07:00
|
|
|
frd_->get(),
|
2017-05-28 17:04:39 -07:00
|
|
|
detail::chunk_header{
|
|
|
|
|
buffer_size(result->first)},
|
|
|
|
|
[&]()
|
|
|
|
|
{
|
|
|
|
|
auto sv = d_(result->first);
|
|
|
|
|
return boost::asio::const_buffers_1{
|
|
|
|
|
sv.data(), sv.size()};
|
|
|
|
|
|
|
|
|
|
}(),
|
2017-06-03 06:49:11 -07:00
|
|
|
detail::chunk_crlf(),
|
2017-05-28 17:04:39 -07:00
|
|
|
result->first,
|
|
|
|
|
detail::chunk_crlf()};
|
|
|
|
|
s_ = do_header_c;
|
2017-06-26 17:20:42 -07:00
|
|
|
BEAST_FALLTHROUGH;
|
2017-05-28 17:04:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case do_header_c:
|
|
|
|
|
visit(ec, boost::get<ch0_t>(v_));
|
|
|
|
|
break;
|
|
|
|
|
|
2017-06-06 17:26:11 -07:00
|
|
|
go_header_only_c:
|
|
|
|
|
v_ = ch_t{frd_->get()};
|
|
|
|
|
s_ = do_header_only_c;
|
2017-05-28 17:04:39 -07:00
|
|
|
case do_header_only_c:
|
2017-06-06 17:26:11 -07:00
|
|
|
visit(ec, boost::get<ch_t>(v_));
|
2017-05-28 17:04:39 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case do_body_c:
|
2017-06-25 10:14:18 -07:00
|
|
|
if(! rd_)
|
|
|
|
|
{
|
|
|
|
|
rd_.emplace(m_, ec);
|
|
|
|
|
if(ec)
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-05-28 17:04:39 -07:00
|
|
|
s_ = do_body_c + 1;
|
2017-06-26 17:20:42 -07:00
|
|
|
BEAST_FALLTHROUGH;
|
2017-05-28 17:04:39 -07:00
|
|
|
|
|
|
|
|
case do_body_c + 1:
|
|
|
|
|
{
|
|
|
|
|
auto result = rd_->get(ec);
|
|
|
|
|
if(ec)
|
|
|
|
|
return;
|
|
|
|
|
if(! result)
|
|
|
|
|
goto go_final_c;
|
|
|
|
|
more_ = result->second;
|
2017-06-26 18:26:35 -07:00
|
|
|
#if ! BEAST_NO_BIG_VARIANTS
|
|
|
|
|
if(! more_)
|
|
|
|
|
{
|
|
|
|
|
// do it all in one buffer
|
|
|
|
|
v_ = ch2_t{
|
|
|
|
|
boost::in_place_init,
|
|
|
|
|
detail::chunk_header{
|
|
|
|
|
buffer_size(result->first)},
|
|
|
|
|
[&]()
|
|
|
|
|
{
|
|
|
|
|
auto sv = d_(result->first);
|
|
|
|
|
return boost::asio::const_buffers_1{
|
|
|
|
|
sv.data(), sv.size()};
|
|
|
|
|
|
|
|
|
|
}(),
|
|
|
|
|
detail::chunk_crlf(),
|
|
|
|
|
result->first,
|
|
|
|
|
detail::chunk_crlf(),
|
|
|
|
|
detail::chunk_final(),
|
|
|
|
|
[&]()
|
|
|
|
|
{
|
|
|
|
|
auto sv = d_(
|
|
|
|
|
boost::asio::null_buffers{});
|
|
|
|
|
return boost::asio::const_buffers_1{
|
|
|
|
|
sv.data(), sv.size()};
|
|
|
|
|
|
|
|
|
|
}(),
|
|
|
|
|
detail::chunk_crlf()};
|
|
|
|
|
goto go_body_final_c;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2017-05-28 17:04:39 -07:00
|
|
|
v_ = ch1_t{
|
|
|
|
|
boost::in_place_init,
|
|
|
|
|
detail::chunk_header{
|
|
|
|
|
buffer_size(result->first)},
|
|
|
|
|
[&]()
|
|
|
|
|
{
|
|
|
|
|
auto sv = d_(result->first);
|
|
|
|
|
return boost::asio::const_buffers_1{
|
|
|
|
|
sv.data(), sv.size()};
|
|
|
|
|
|
|
|
|
|
}(),
|
2017-06-03 06:49:11 -07:00
|
|
|
detail::chunk_crlf(),
|
2017-05-28 17:04:39 -07:00
|
|
|
result->first,
|
|
|
|
|
detail::chunk_crlf()};
|
|
|
|
|
s_ = do_body_c + 2;
|
2017-06-26 17:20:42 -07:00
|
|
|
BEAST_FALLTHROUGH;
|
2017-05-28 17:04:39 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case do_body_c + 2:
|
|
|
|
|
visit(ec, boost::get<ch1_t>(v_));
|
|
|
|
|
break;
|
|
|
|
|
|
2017-06-26 18:26:35 -07:00
|
|
|
#if ! BEAST_NO_BIG_VARIANTS
|
|
|
|
|
go_body_final_c:
|
|
|
|
|
s_ = do_body_final_c;
|
|
|
|
|
case do_body_final_c:
|
|
|
|
|
visit(ec, boost::get<ch2_t>(v_));
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
go_all_c:
|
|
|
|
|
s_ = do_all_c;
|
|
|
|
|
case do_all_c:
|
|
|
|
|
visit(ec, boost::get<ch3_t>(v_));
|
|
|
|
|
break;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
go_final_c:
|
2017-05-28 17:04:39 -07:00
|
|
|
case do_final_c:
|
2017-06-26 18:26:35 -07:00
|
|
|
v_ = ch4_t{
|
2017-05-28 17:04:39 -07:00
|
|
|
boost::in_place_init,
|
|
|
|
|
detail::chunk_final(),
|
|
|
|
|
[&]()
|
|
|
|
|
{
|
|
|
|
|
auto sv = d_(
|
|
|
|
|
boost::asio::null_buffers{});
|
|
|
|
|
return boost::asio::const_buffers_1{
|
|
|
|
|
sv.data(), sv.size()};
|
|
|
|
|
|
|
|
|
|
}(),
|
|
|
|
|
detail::chunk_crlf()};
|
|
|
|
|
s_ = do_final_c + 1;
|
2017-06-26 17:20:42 -07:00
|
|
|
BEAST_FALLTHROUGH;
|
2017-05-28 17:04:39 -07:00
|
|
|
|
|
|
|
|
case do_final_c + 1:
|
2017-06-26 18:26:35 -07:00
|
|
|
visit(ec, boost::get<ch4_t>(v_));
|
2017-05-28 17:04:39 -07:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
case do_complete:
|
|
|
|
|
BOOST_ASSERT(false);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
go_complete:
|
|
|
|
|
s_ = do_complete;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-07 05:10:58 -07:00
|
|
|
template<bool isRequest, class Body,
|
|
|
|
|
class Fields, class ChunkDecorator>
|
2017-05-28 17:04:39 -07:00
|
|
|
void
|
2017-06-07 05:10:58 -07:00
|
|
|
serializer<isRequest, Body, Fields, ChunkDecorator>::
|
2017-05-28 17:04:39 -07:00
|
|
|
consume(std::size_t n)
|
|
|
|
|
{
|
|
|
|
|
using boost::asio::buffer_size;
|
|
|
|
|
switch(s_)
|
|
|
|
|
{
|
|
|
|
|
case do_header:
|
|
|
|
|
BOOST_ASSERT(n <= buffer_size(
|
|
|
|
|
boost::get<cb0_t>(v_)));
|
|
|
|
|
boost::get<cb0_t>(v_).consume(n);
|
|
|
|
|
if(buffer_size(boost::get<cb0_t>(v_)) > 0)
|
|
|
|
|
break;
|
|
|
|
|
header_done_ = true;
|
|
|
|
|
v_ = boost::blank{};
|
|
|
|
|
if(! more_)
|
|
|
|
|
goto go_complete;
|
|
|
|
|
s_ = do_body + 1;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case do_header_only:
|
2017-06-06 17:26:11 -07:00
|
|
|
BOOST_ASSERT(n <= buffer_size(
|
|
|
|
|
boost::get<ch_t>(v_)));
|
|
|
|
|
boost::get<ch_t>(v_).consume(n);
|
|
|
|
|
if(buffer_size(boost::get<ch_t>(v_)) > 0)
|
2017-05-28 17:04:39 -07:00
|
|
|
break;
|
2017-06-06 17:26:11 -07:00
|
|
|
frd_ = boost::none;
|
2017-05-28 17:04:39 -07:00
|
|
|
header_done_ = true;
|
2017-05-31 08:01:55 -07:00
|
|
|
if(! split_)
|
2017-05-28 17:04:39 -07:00
|
|
|
goto go_complete;
|
|
|
|
|
s_ = do_body;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case do_body + 2:
|
|
|
|
|
{
|
|
|
|
|
BOOST_ASSERT(n <= buffer_size(
|
|
|
|
|
boost::get<cb1_t>(v_)));
|
|
|
|
|
boost::get<cb1_t>(v_).consume(n);
|
|
|
|
|
if(buffer_size(boost::get<cb1_t>(v_)) > 0)
|
|
|
|
|
break;
|
|
|
|
|
v_ = boost::blank{};
|
|
|
|
|
if(! more_)
|
|
|
|
|
goto go_complete;
|
|
|
|
|
s_ = do_body + 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
case do_header_c:
|
|
|
|
|
BOOST_ASSERT(n <= buffer_size(
|
|
|
|
|
boost::get<ch0_t>(v_)));
|
|
|
|
|
boost::get<ch0_t>(v_).consume(n);
|
|
|
|
|
if(buffer_size(boost::get<ch0_t>(v_)) > 0)
|
|
|
|
|
break;
|
|
|
|
|
header_done_ = true;
|
|
|
|
|
v_ = boost::blank{};
|
|
|
|
|
if(more_)
|
|
|
|
|
s_ = do_body_c + 1;
|
|
|
|
|
else
|
|
|
|
|
s_ = do_final_c;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case do_header_only_c:
|
|
|
|
|
{
|
2017-06-06 17:26:11 -07:00
|
|
|
BOOST_ASSERT(n <= buffer_size(
|
|
|
|
|
boost::get<ch_t>(v_)));
|
|
|
|
|
boost::get<ch_t>(v_).consume(n);
|
|
|
|
|
if(buffer_size(boost::get<ch_t>(v_)) > 0)
|
2017-05-28 17:04:39 -07:00
|
|
|
break;
|
2017-06-06 17:26:11 -07:00
|
|
|
frd_ = boost::none;
|
2017-05-28 17:04:39 -07:00
|
|
|
header_done_ = true;
|
2017-05-31 08:01:55 -07:00
|
|
|
if(! split_)
|
2017-05-28 17:04:39 -07:00
|
|
|
{
|
|
|
|
|
s_ = do_final_c;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
s_ = do_body_c;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case do_body_c + 2:
|
|
|
|
|
BOOST_ASSERT(n <= buffer_size(
|
|
|
|
|
boost::get<ch1_t>(v_)));
|
|
|
|
|
boost::get<ch1_t>(v_).consume(n);
|
|
|
|
|
if(buffer_size(boost::get<ch1_t>(v_)) > 0)
|
|
|
|
|
break;
|
|
|
|
|
v_ = boost::blank{};
|
|
|
|
|
if(more_)
|
|
|
|
|
s_ = do_body_c + 1;
|
|
|
|
|
else
|
|
|
|
|
s_ = do_final_c;
|
|
|
|
|
break;
|
|
|
|
|
|
2017-06-26 18:26:35 -07:00
|
|
|
#if ! BEAST_NO_BIG_VARIANTS
|
|
|
|
|
case do_body_final_c:
|
|
|
|
|
{
|
|
|
|
|
auto& b = boost::get<ch2_t>(v_);
|
|
|
|
|
BOOST_ASSERT(n <= buffer_size(b));
|
|
|
|
|
b.consume(n);
|
|
|
|
|
if(buffer_size(b) > 0)
|
|
|
|
|
break;
|
|
|
|
|
v_ = boost::blank{};
|
|
|
|
|
s_ = do_complete;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case do_all_c:
|
|
|
|
|
{
|
|
|
|
|
auto& b = boost::get<ch3_t>(v_);
|
|
|
|
|
BOOST_ASSERT(n <= buffer_size(b));
|
|
|
|
|
b.consume(n);
|
|
|
|
|
if(buffer_size(b) > 0)
|
|
|
|
|
break;
|
|
|
|
|
header_done_ = true;
|
|
|
|
|
v_ = boost::blank{};
|
|
|
|
|
s_ = do_complete;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2017-05-28 17:04:39 -07:00
|
|
|
case do_final_c + 1:
|
|
|
|
|
BOOST_ASSERT(buffer_size(
|
2017-06-26 18:26:35 -07:00
|
|
|
boost::get<ch4_t>(v_)));
|
|
|
|
|
boost::get<ch4_t>(v_).consume(n);
|
|
|
|
|
if(buffer_size(boost::get<ch4_t>(v_)) > 0)
|
2017-05-28 17:04:39 -07:00
|
|
|
break;
|
|
|
|
|
v_ = boost::blank{};
|
|
|
|
|
goto go_complete;
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
BOOST_ASSERT(false);
|
|
|
|
|
case do_complete:
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
go_complete:
|
|
|
|
|
s_ = do_complete;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // http
|
|
|
|
|
} // beast
|
|
|
|
|
|
|
|
|
|
#endif
|