Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 52 additions & 5 deletions include/boost/http_proto/response_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ class response_base

@throw std::length_error
Max capacity would be exceeded.
@throw std::invalid_argument
`sc == status::unknown`

@param sc The status code to set. This
must not be @ref status::unknown.
Expand All @@ -122,12 +124,57 @@ class response_base
http_proto::version v =
http_proto::version::http_1_1)
{
set_start_line_impl(
sc,
static_cast<
unsigned short>(sc),
set_start_line_impl(sc,
static_cast<unsigned short>(sc),
obsolete_reason(sc), v);
}

/** Set the HTTP version of the response

@par Exception Safety
Strong guarantee.
Calls to allocate may throw.
Exception thrown if maximum capacity exceeded.

@throw std::length_error
Maximum capacity would be exceeded.

@param v The version to set.
*/
BOOST_HTTP_PROTO_DECL
void
set_version(
http_proto::version v);

/** Set the status code of the response.

The reason-phrase will be set to the
standard text for the specified status
code. The version will remain unchanged.

@par Exception Safety
Strong guarantee.
Calls to allocate may throw.
Exception thrown if maximum capacity exceeded.

@throw std::length_error
Maximum capacity would be exceeded.
@throw std::invalid_argument
`sc == status::unknown`

@param sc The status code to set. This
must not be @ref status::unknown.
*/
void
set_status(
http_proto::status sc)
{
if(sc == http_proto::status::unknown)
detail::throw_invalid_argument();
set_start_line_impl(sc,
static_cast<unsigned short>(sc),
obsolete_reason(sc),
v);
version());
}

/** Set the status code and version of the response.
Expand Down
75 changes: 35 additions & 40 deletions include/boost/http_proto/serializer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,13 @@ class serializer
void
reset() noexcept;

/** Prepare the serializer for a new message without a body.
/** Start serializing a message with an empty body

Initializes the serializer with the HTTP
start-line and headers from `m`, and
without a body.
This function prepares the serializer to create a message which
has an empty body.
Ownership of the specified message is not transferred; the caller is
responsible for ensuring the lifetime of the object extends until the
serializer is done.

@par Preconditions
@code
Expand All @@ -176,19 +178,15 @@ class serializer

@par Exception Safety
Strong guarantee.
Exceptions thrown if there is insufficient
internal buffer space to start the
operation.
Exceptions thrown if there is insufficient internal buffer space
to start the operation.

@throw std::logic_error
`this->is_done() == true`.
@throw std::logic_error `this->is_done() == true`.

@throw std::length_error if there is
insufficient internal buffer space to
start the operation.
@throw std::length_error if there is insufficient internal buffer
space to start the operation.

@param m The message to read the HTTP
start-line and headers from.
@param m The request or response headers to serialize.

@see
@ref message_base.
Expand All @@ -197,17 +195,19 @@ class serializer
BOOST_HTTP_PROTO_DECL
start(message_base const& m);

/** Prepare the serializer for a new message with a ConstBufferSequence body.
/** Start serializing a message with a buffer sequence body

Initializes the serializer with the HTTP
start-line and headers from `m`, and the
provided `buffers` for reading the
message body from.
Initializes the serializer with the HTTP start-line and headers from `m`,
and the provided `buffers` for reading the message body from.

Changing the contents of the message
after calling this function and before
@ref is_done returns `true` results in
undefined behavior.
Changing the contents of the message after calling this function and
before @ref is_done returns `true` results in undefined behavior.

At least one copy of the specified buffer sequence is maintained until
the serializer is done, gets reset, or ios destroyed, after which all
of its copies are destroyed. Ownership of the underlying memory is not
transferred; the caller must ensure the memory remains valid until the
serializer’s copies are destroyed.

@par Preconditions
@code
Expand All @@ -221,26 +221,23 @@ class serializer

@par Constraints
@code
buffers::is_const_buffer_sequence<ConstBufferSequence>::value == true
buffers::is_const_buffer_sequence_v<ConstBufferSequence> == true
@endcode

@par Exception Safety
Strong guarantee.
Exceptions thrown if there is insufficient
internal buffer space to start the
operation.
Exceptions thrown if there is insufficient internal buffer space
to start the operation.

@throw std::logic_error
`this->is_done() == true`.
@throw std::logic_error `this->is_done() == true`.

@throw std::length_error if there is
insufficient internal buffer space to
start the operation.
@throw std::length_error If there is insufficient internal buffer
space to start the operation.

@param m The message to read the HTTP
start-line and headers from.
@param m The message to read the HTTP start-line and headers from.

@param buffers A buffer sequence containing the message body.

@param buffers One or more buffers
containing the message body data. While
the buffers object is copied, ownership of
the underlying memory remains with the
Expand All @@ -261,12 +258,10 @@ class serializer
message_base const& m,
ConstBufferSequence&& buffers);

/** Prepare the serializer for a new message with a Source body.
/** Start serializing a message with a @em Source body

Initializes the serializer with the
HTTP start-line and headers from `m`,
and constructs a `Source` object to read
the message body.
Initializes the serializer with the HTTP start-line and headers from
`m`, and constructs a `Source` object to provide the message body.

Changing the contents of the message
after calling this function and before
Expand Down
32 changes: 32 additions & 0 deletions src/response_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,37 @@ set_start_line_impl(
h_.on_start_line();
}

void
response_base::
set_version(
http_proto::version v)
{
if(v == h_.version)
return;
if(h_.is_default())
{
auto def = h_.get_default(detail::kind::response);
return set_start_line_impl(
def->res.status, def->res.status_int,
core::string_view(
def->cbuf + 13, def->prefix - 15), v);
}

// Introduce a new scope so that prefix_op's
// destructor runs before h_.on_start_line().
{
auto op = prefix_op_t(
*this, h_.prefix, nullptr);
char* dest = h_.buf;
if(v == http_proto::version::http_1_1)
dest[7] = '1';
else
dest[7] = '0';
h_.version = v;
}

h_.on_start_line();
}

} // http_proto
} // boost
3 changes: 2 additions & 1 deletion src/status.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
//

#include <boost/http_proto/status.hpp>
#include <boost/throw_exception.hpp>
#include <boost/http_proto/detail/except.hpp>
//#include <boost/throw_exception.hpp>
#include <ostream>

namespace boost {
Expand Down
28 changes: 28 additions & 0 deletions test/unit/response.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,34 @@ class response_test
BOOST_TEST_EQ(it->value, "0");
}
}

// set_version
{
response res;
res.set_version(version::http_1_1);
BOOST_TEST_EQ(res.buffer(),
"HTTP/1.1 200 OK\r\n\r\n");
res.set_version(version::http_1_0);
BOOST_TEST_EQ(res.buffer(),
"HTTP/1.0 200 OK\r\n\r\n");
res.set_version(version::http_1_1);
BOOST_TEST_EQ(res.buffer(),
"HTTP/1.1 200 OK\r\n\r\n");
}

// set_status
{
response res;
res.set_status(status::not_found);
BOOST_TEST_EQ(res.buffer(),
"HTTP/1.1 404 Not Found\r\n\r\n");
res.set_status(status::bad_request);
BOOST_TEST_EQ(res.buffer(),
"HTTP/1.1 400 Bad Request\r\n\r\n");
res.set_status(status::ok);
BOOST_TEST_EQ(res.buffer(),
"HTTP/1.1 200 OK\r\n\r\n");
}
}

void
Expand Down
Loading