diff --git a/doc/modules/ROOT/pages/reference.adoc b/doc/modules/ROOT/pages/reference.adoc
index e2d0de29..75fb2387 100644
--- a/doc/modules/ROOT/pages/reference.adoc
+++ b/doc/modules/ROOT/pages/reference.adoc
@@ -21,10 +21,6 @@ cpp:boost::http_proto::fields[fields]
cpp:boost::http_proto::fields_base[fields_base]
-cpp:boost::http_proto::fields_view[fields_view]
-
-cpp:boost::http_proto::fields_view_base[fields_view_base]
-
cpp:boost::http_proto::file[file]
cpp:boost::http_proto::file_sink[file_sink]
@@ -35,8 +31,6 @@ cpp:boost::http_proto::header_limits[header_limits]
cpp:boost::http_proto::message_base[message_base]
-cpp:boost::http_proto::message_view_base[message_view_base]
-
cpp:boost::http_proto::metadata[metadata]
cpp:boost::http_proto::parser[parser]
@@ -47,26 +41,20 @@ cpp:boost::http_proto::request_base[request_base]
cpp:boost::http_proto::request_parser[request_parser]
-cpp:boost::http_proto::request_view[request_view]
-
cpp:boost::http_proto::response[response]
cpp:boost::http_proto::response_base[response_base]
cpp:boost::http_proto::response_parser[response_parser]
-| **Types (2/2)**
-
-cpp:boost::http_proto::response_view[response_view]
-
cpp:boost::http_proto::serializer[serializer]
+| **Types (2/2)**
+
cpp:boost::http_proto::sink[sink]
cpp:boost::http_proto::source[source]
-cpp:boost::http_proto::static_fields[static_fields]
-
cpp:boost::http_proto::static_request[static_request]
cpp:boost::http_proto::static_response[static_response]
diff --git a/doc/tagfiles/boost-http_proto-doxygen.tag.xml b/doc/tagfiles/boost-http_proto-doxygen.tag.xml
index c52e205f..88ccc858 100644
--- a/doc/tagfiles/boost-http_proto-doxygen.tag.xml
+++ b/doc/tagfiles/boost-http_proto-doxygen.tag.xml
@@ -8,14 +8,11 @@
boost::http_proto::is_source
boost::http_proto::fields
boost::http_proto::fields_base
- boost::http_proto::fields_view
- boost::http_proto::fields_view_base
boost::http_proto::file
boost::http_proto::file_sink
boost::http_proto::file_source
boost::http_proto::header_limits
boost::http_proto::message_base
- boost::http_proto::message_view_base
boost::http_proto::metadata
boost::http_proto::parameter
boost::http_proto::parser
@@ -23,15 +20,12 @@
boost::http_proto::request
boost::http_proto::request_base
boost::http_proto::request_parser
- boost::http_proto::request_view
boost::http_proto::response
boost::http_proto::response_base
boost::http_proto::response_parser
- boost::http_proto::response_view
boost::http_proto::serializer
boost::http_proto::sink
boost::http_proto::source
- boost::http_proto::static_fields
boost::http_proto::static_request
boost::http_proto::static_response
boost::http_proto::string_body
@@ -61,7 +55,7 @@
combine_field_values
boost/http_proto/combine_field_values.adoc
- (const fields_view_base::subrange& vr, grammar::recycled_ptr<std::string>& temp)
+ (const fields_base::subrange& vr, grammar::recycled_ptr<std::string>& temp)
void
@@ -145,14 +139,14 @@
iterator
begin
- boost/http_proto/fields_view_base/begin.adoc
+ boost/http_proto/fields_base/begin.adoc
()
core::string_view
buffer
- boost/http_proto/fields_view_base/buffer.adoc
+ boost/http_proto/fields_base/buffer.adoc
()
@@ -173,7 +167,7 @@
iterator
end
- boost/http_proto/fields_view_base/end.adoc
+ boost/http_proto/fields_base/end.adoc
()
@@ -187,14 +181,14 @@
reverse_iterator
rbegin
- boost/http_proto/fields_view_base/rbegin.adoc
+ boost/http_proto/fields_base/rbegin.adoc
()
reverse_iterator
rend
- boost/http_proto/fields_view_base/rend.adoc
+ boost/http_proto/fields_base/rend.adoc
()
@@ -222,7 +216,7 @@
std::size_t
size
- boost/http_proto/fields_view_base/size.adoc
+ boost/http_proto/fields_base/size.adoc
()
@@ -233,17 +227,10 @@
(fields& other)
-
- fields_view
- operator fields_view
- boost/http_proto/fields/2conversion.adoc
-
- ()
-
std::size_t
max_size
- boost/http_proto/fields_view_base/max_size.adoc
+ boost/http_proto/fields_base/max_size.adoc
()
@@ -261,14 +248,14 @@
iterator
begin
- boost/http_proto/fields_view_base/begin.adoc
+ boost/http_proto/fields_base/begin.adoc
()
core::string_view
buffer
- boost/http_proto/fields_view_base/buffer.adoc
+ boost/http_proto/fields_base/buffer.adoc
()
@@ -289,7 +276,7 @@
iterator
end
- boost/http_proto/fields_view_base/end.adoc
+ boost/http_proto/fields_base/end.adoc
()
@@ -303,14 +290,14 @@
reverse_iterator
rbegin
- boost/http_proto/fields_view_base/rbegin.adoc
+ boost/http_proto/fields_base/rbegin.adoc
()
reverse_iterator
rend
- boost/http_proto/fields_view_base/rend.adoc
+ boost/http_proto/fields_base/rend.adoc
()
@@ -338,162 +325,28 @@
std::size_t
size
- boost/http_proto/fields_view_base/size.adoc
+ boost/http_proto/fields_base/size.adoc
()
std::size_t
max_size
- boost/http_proto/fields_view_base/max_size.adoc
+ boost/http_proto/fields_base/max_size.adoc
()
- boost::http_proto::fields_view
- boost/http_proto/fields_view.adoc
-
- void
- ~fields_view
- boost/http_proto/fields_view/2destructor.adoc
-
- ()
-
-
- fields_view&
- operator=
- boost/http_proto/fields_view/operator_assign.adoc
-
- (const fields_view& other)
-
-
- iterator
- begin
- boost/http_proto/fields_view_base/begin.adoc
-
- ()
-
-
- core::string_view
- buffer
- boost/http_proto/fields_view_base/buffer.adoc
-
- ()
-
-
- iterator
- end
- boost/http_proto/fields_view_base/end.adoc
-
- ()
-
-
- reverse_iterator
- rbegin
- boost/http_proto/fields_view_base/rbegin.adoc
-
- ()
-
-
- reverse_iterator
- rend
- boost/http_proto/fields_view_base/rend.adoc
-
- ()
-
-
- std::size_t
- size
- boost/http_proto/fields_view_base/size.adoc
-
- ()
-
-
- void
- swap
- boost/http_proto/fields_view/swap.adoc
-
- (fields_view& other)
-
-
- std::size_t
- max_size
- boost/http_proto/fields_view_base/max_size.adoc
-
- ()
-
+ boost::http_proto::file
+ boost/http_proto/file.adoc
void
- fields_view
- boost/http_proto/fields_view/2constructor-0c.adoc
-
- (const detail::header* ph)
-
-
-
- boost::http_proto::fields_view_base
- boost/http_proto/fields_view_base.adoc
-
- iterator
- begin
- boost/http_proto/fields_view_base/begin.adoc
-
- ()
-
-
- core::string_view
- buffer
- boost/http_proto/fields_view_base/buffer.adoc
-
- ()
-
-
- iterator
- end
- boost/http_proto/fields_view_base/end.adoc
-
- ()
-
-
- reverse_iterator
- rbegin
- boost/http_proto/fields_view_base/rbegin.adoc
-
- ()
-
-
- reverse_iterator
- rend
- boost/http_proto/fields_view_base/rend.adoc
-
- ()
-
-
- std::size_t
- size
- boost/http_proto/fields_view_base/size.adoc
-
- ()
-
-
- std::size_t
- max_size
- boost/http_proto/fields_view_base/max_size.adoc
+ ~file
+ boost/http_proto/file/2destructor.adoc
()
-
- fields_view_base&
- operator=
- boost/http_proto/fields_view_base/operator_assign.adoc
-
- (const fields_view_base& )
-
-
-
- boost::http_proto::file
- boost/http_proto/file.adoc
file&
operator=
@@ -501,13 +354,6 @@
(file&& other)
-
- void
- close
- boost/http_proto/file/close.adoc
-
- (system::error_code& ec)
-
bool
is_open
@@ -515,48 +361,6 @@
()
-
- void
- open
- boost/http_proto/file/open.adoc
-
- (const char* path, file_mode mode, system::error_code& ec)
-
-
- std::uint64_t
- pos
- boost/http_proto/file/pos.adoc
-
- (system::error_code& ec)
-
-
- std::size_t
- read
- boost/http_proto/file/read.adoc
-
- (void* buffer, std::size_t n, system::error_code& ec)
-
-
- void
- seek
- boost/http_proto/file/seek.adoc
-
- (std::uint64_t offset, system::error_code& ec)
-
-
- std::uint64_t
- size
- boost/http_proto/file/size.adoc
-
- (system::error_code& ec)
-
-
- std::size_t
- write
- boost/http_proto/file/write.adoc
-
- (const void* buffer, std::size_t n, system::error_code& ec)
-
boost::http_proto::file_sink
@@ -611,14 +415,14 @@
iterator
begin
- boost/http_proto/fields_view_base/begin.adoc
+ boost/http_proto/fields_base/begin.adoc
()
core::string_view
buffer
- boost/http_proto/fields_view_base/buffer.adoc
+ boost/http_proto/fields_base/buffer.adoc
()
@@ -632,7 +436,7 @@
bool
chunked
- boost/http_proto/message_view_base/chunked.adoc
+ boost/http_proto/message_base/chunked.adoc
()
@@ -646,14 +450,14 @@
iterator
end
- boost/http_proto/fields_view_base/end.adoc
+ boost/http_proto/fields_base/end.adoc
()
bool
keep_alive
- boost/http_proto/message_view_base/keep_alive.adoc
+ boost/http_proto/message_base/keep_alive.adoc
()
@@ -667,35 +471,35 @@
const http_proto::metadata&
metadata
- boost/http_proto/message_view_base/metadata.adoc
+ boost/http_proto/message_base/metadata.adoc
()
http_proto::payload
payload
- boost/http_proto/message_view_base/payload.adoc
+ boost/http_proto/message_base/payload.adoc
()
- std::uint64_t
+ uint64_t
payload_size
- boost/http_proto/message_view_base/payload_size.adoc
+ boost/http_proto/message_base/payload_size.adoc
()
reverse_iterator
rbegin
- boost/http_proto/fields_view_base/rbegin.adoc
+ boost/http_proto/fields_base/rbegin.adoc
()
reverse_iterator
rend
- boost/http_proto/fields_view_base/rend.adoc
+ boost/http_proto/fields_base/rend.adoc
()
@@ -718,7 +522,7 @@
set_content_length
boost/http_proto/message_base/set_content_length.adoc
- (std::uint64_t n)
+ (uint64_t n)
void
@@ -739,7 +543,7 @@
set_payload_size
boost/http_proto/message_base/set_payload_size.adoc
- (std::uint64_t n)
+ (uint64_t n)
void
@@ -751,116 +555,21 @@
std::size_t
size
- boost/http_proto/fields_view_base/size.adoc
-
- ()
-
-
- http_proto::version
- version
- boost/http_proto/message_view_base/version.adoc
-
- ()
-
-
- std::size_t
- max_size
- boost/http_proto/fields_view_base/max_size.adoc
-
- ()
-
-
-
- boost::http_proto::message_view_base
- boost/http_proto/message_view_base.adoc
-
- iterator
- begin
- boost/http_proto/fields_view_base/begin.adoc
-
- ()
-
-
- core::string_view
- buffer
- boost/http_proto/fields_view_base/buffer.adoc
-
- ()
-
-
- bool
- chunked
- boost/http_proto/message_view_base/chunked.adoc
-
- ()
-
-
- iterator
- end
- boost/http_proto/fields_view_base/end.adoc
-
- ()
-
-
- bool
- keep_alive
- boost/http_proto/message_view_base/keep_alive.adoc
-
- ()
-
-
- const http_proto::metadata&
- metadata
- boost/http_proto/message_view_base/metadata.adoc
-
- ()
-
-
- http_proto::payload
- payload
- boost/http_proto/message_view_base/payload.adoc
-
- ()
-
-
- std::uint64_t
- payload_size
- boost/http_proto/message_view_base/payload_size.adoc
-
- ()
-
-
- reverse_iterator
- rbegin
- boost/http_proto/fields_view_base/rbegin.adoc
-
- ()
-
-
- reverse_iterator
- rend
- boost/http_proto/fields_view_base/rend.adoc
-
- ()
-
-
- std::size_t
- size
- boost/http_proto/fields_view_base/size.adoc
+ boost/http_proto/fields_base/size.adoc
()
http_proto::version
version
- boost/http_proto/message_view_base/version.adoc
+ boost/http_proto/message_base/version.adoc
()
std::size_t
max_size
- boost/http_proto/fields_view_base/max_size.adoc
+ boost/http_proto/fields_base/max_size.adoc
()
@@ -883,27 +592,6 @@
boost::http_proto::parser
boost/http_proto/parser.adoc
-
- void
- parser
- boost/http_proto/parser/2constructor-0f.adoc
-
- (parser&& other)
-
-
- void
- ~parser
- boost/http_proto/parser/2destructor.adoc
-
- ()
-
-
- parser&
- operator=
- boost/http_proto/parser/operator_assign.adoc
-
- (parser&& other)
-
core::string_view
body
@@ -986,7 +674,7 @@
set_body_limit
boost/http_proto/parser/set_body_limit.adoc
- (std::uint64_t n)
+ (uint64_t n)
void
@@ -997,43 +685,29 @@
void
- parser
- boost/http_proto/parser/2constructor-0b.adoc
-
- (rts::context& , detail::kind )
-
-
- std::size_t
- apply_filter
- boost/http_proto/parser/apply_filter.adoc
-
- (system::error_code& , std::size_t , bool )
-
-
- std::uint64_t
- body_limit_remain
- boost/http_proto/parser/body_limit_remain.adoc
+ ~parser
+ boost/http_proto/parser/2destructor.adoc
()
bool
- is_plain
- boost/http_proto/parser/is_plain.adoc
+ is_body_set
+ boost/http_proto/parser/is_body_set.adoc
()
- void
- on_set_body
- boost/http_proto/parser/on_set_body.adoc
+ const static_request&
+ safe_get_request
+ boost/http_proto/parser/safe_get_request.adoc
()
- const detail::header*
- safe_get_header
- boost/http_proto/parser/safe_get_header.adoc
+ const static_response&
+ safe_get_response
+ boost/http_proto/parser/safe_get_response.adoc
()
@@ -1044,6 +718,13 @@
(bool )
+
+ detail::workspace&
+ ws
+ boost/http_proto/parser/ws.adoc
+
+ ()
+
boost::http_proto::quoted_token_view
@@ -1237,14 +918,14 @@
iterator
begin
- boost/http_proto/fields_view_base/begin.adoc
+ boost/http_proto/fields_base/begin.adoc
()
core::string_view
buffer
- boost/http_proto/fields_view_base/buffer.adoc
+ boost/http_proto/fields_base/buffer.adoc
()
@@ -1258,7 +939,7 @@
bool
chunked
- boost/http_proto/message_view_base/chunked.adoc
+ boost/http_proto/message_base/chunked.adoc
()
@@ -1272,14 +953,14 @@
iterator
end
- boost/http_proto/fields_view_base/end.adoc
+ boost/http_proto/fields_base/end.adoc
()
bool
keep_alive
- boost/http_proto/message_view_base/keep_alive.adoc
+ boost/http_proto/message_base/keep_alive.adoc
()
@@ -1293,7 +974,7 @@
const http_proto::metadata&
metadata
- boost/http_proto/message_view_base/metadata.adoc
+ boost/http_proto/message_base/metadata.adoc
()
@@ -1314,28 +995,28 @@
http_proto::payload
payload
- boost/http_proto/message_view_base/payload.adoc
+ boost/http_proto/message_base/payload.adoc
()
- std::uint64_t
+ uint64_t
payload_size
- boost/http_proto/message_view_base/payload_size.adoc
+ boost/http_proto/message_base/payload_size.adoc
()
reverse_iterator
rbegin
- boost/http_proto/fields_view_base/rbegin.adoc
+ boost/http_proto/fields_base/rbegin.adoc
()
reverse_iterator
rend
- boost/http_proto/fields_view_base/rend.adoc
+ boost/http_proto/fields_base/rend.adoc
()
@@ -1358,7 +1039,7 @@
set_content_length
boost/http_proto/message_base/set_content_length.adoc
- (std::uint64_t n)
+ (uint64_t n)
void
@@ -1386,7 +1067,7 @@
set_payload_size
boost/http_proto/message_base/set_payload_size.adoc
- (std::uint64_t n)
+ (uint64_t n)
void
@@ -1412,7 +1093,7 @@
std::size_t
size
- boost/http_proto/fields_view_base/size.adoc
+ boost/http_proto/fields_base/size.adoc
()
@@ -1433,21 +1114,14 @@
http_proto::version
version
- boost/http_proto/message_view_base/version.adoc
+ boost/http_proto/message_base/version.adoc
()
- request_view
- operator request_view
- boost/http_proto/request_base/2conversion.adoc
-
- ()
-
-
- std::size_t
- max_size
- boost/http_proto/fields_view_base/max_size.adoc
+ std::size_t
+ max_size
+ boost/http_proto/fields_base/max_size.adoc
()
@@ -1458,14 +1132,14 @@
iterator
begin
- boost/http_proto/fields_view_base/begin.adoc
+ boost/http_proto/fields_base/begin.adoc
()
core::string_view
buffer
- boost/http_proto/fields_view_base/buffer.adoc
+ boost/http_proto/fields_base/buffer.adoc
()
@@ -1479,7 +1153,7 @@
bool
chunked
- boost/http_proto/message_view_base/chunked.adoc
+ boost/http_proto/message_base/chunked.adoc
()
@@ -1493,14 +1167,14 @@
iterator
end
- boost/http_proto/fields_view_base/end.adoc
+ boost/http_proto/fields_base/end.adoc
()
bool
keep_alive
- boost/http_proto/message_view_base/keep_alive.adoc
+ boost/http_proto/message_base/keep_alive.adoc
()
@@ -1514,7 +1188,7 @@
const http_proto::metadata&
metadata
- boost/http_proto/message_view_base/metadata.adoc
+ boost/http_proto/message_base/metadata.adoc
()
@@ -1535,28 +1209,28 @@
http_proto::payload
payload
- boost/http_proto/message_view_base/payload.adoc
+ boost/http_proto/message_base/payload.adoc
()
- std::uint64_t
+ uint64_t
payload_size
- boost/http_proto/message_view_base/payload_size.adoc
+ boost/http_proto/message_base/payload_size.adoc
()
reverse_iterator
rbegin
- boost/http_proto/fields_view_base/rbegin.adoc
+ boost/http_proto/fields_base/rbegin.adoc
()
reverse_iterator
rend
- boost/http_proto/fields_view_base/rend.adoc
+ boost/http_proto/fields_base/rend.adoc
()
@@ -1579,7 +1253,7 @@
set_content_length
boost/http_proto/message_base/set_content_length.adoc
- (std::uint64_t n)
+ (uint64_t n)
void
@@ -1607,7 +1281,7 @@
set_payload_size
boost/http_proto/message_base/set_payload_size.adoc
- (std::uint64_t n)
+ (uint64_t n)
void
@@ -1633,7 +1307,7 @@
std::size_t
size
- boost/http_proto/fields_view_base/size.adoc
+ boost/http_proto/fields_base/size.adoc
()
@@ -1647,21 +1321,14 @@
http_proto::version
version
- boost/http_proto/message_view_base/version.adoc
-
- ()
-
-
- request_view
- operator request_view
- boost/http_proto/request_base/2conversion.adoc
+ boost/http_proto/message_base/version.adoc
()
std::size_t
max_size
- boost/http_proto/fields_view_base/max_size.adoc
+ boost/http_proto/fields_base/max_size.adoc
()
@@ -1676,13 +1343,6 @@
boost::http_proto::request_parser
boost/http_proto/request_parser.adoc
-
- void
- request_parser
- boost/http_proto/request_parser/2constructor.adoc
-
- (rts::context& ctx)
-
void
~request_parser
@@ -1690,13 +1350,6 @@
()
-
- parser&
- operator=
- boost/http_proto/parser/operator_assign.adoc
-
- (parser&& other)
-
core::string_view
body
@@ -1726,7 +1379,7 @@
(std::size_t n)
- request_view
+ const static_request&
get
boost/http_proto/request_parser/get.adoc
@@ -1786,7 +1439,7 @@
set_body_limit
boost/http_proto/parser/set_body_limit.adoc
- (std::uint64_t n)
+ (uint64_t n)
void
@@ -1796,164 +1449,20 @@
()
-
- boost::http_proto::request_view
- boost/http_proto/request_view.adoc
-
- void
- ~request_view
- boost/http_proto/request_view/2destructor.adoc
-
- ()
-
-
- request_view&
- operator=
- boost/http_proto/request_view/operator_assign.adoc
-
- (const request_view& other)
-
-
- iterator
- begin
- boost/http_proto/fields_view_base/begin.adoc
-
- ()
-
-
- core::string_view
- buffer
- boost/http_proto/fields_view_base/buffer.adoc
-
- ()
-
-
- bool
- chunked
- boost/http_proto/message_view_base/chunked.adoc
-
- ()
-
-
- iterator
- end
- boost/http_proto/fields_view_base/end.adoc
-
- ()
-
-
- bool
- keep_alive
- boost/http_proto/message_view_base/keep_alive.adoc
-
- ()
-
-
- const http_proto::metadata&
- metadata
- boost/http_proto/message_view_base/metadata.adoc
-
- ()
-
-
- http_proto::method
- method
- boost/http_proto/request_view/method.adoc
-
- ()
-
-
- core::string_view
- method_text
- boost/http_proto/request_view/method_text.adoc
-
- ()
-
-
- http_proto::payload
- payload
- boost/http_proto/message_view_base/payload.adoc
-
- ()
-
-
- std::uint64_t
- payload_size
- boost/http_proto/message_view_base/payload_size.adoc
-
- ()
-
-
- reverse_iterator
- rbegin
- boost/http_proto/fields_view_base/rbegin.adoc
-
- ()
-
-
- reverse_iterator
- rend
- boost/http_proto/fields_view_base/rend.adoc
-
- ()
-
-
- std::size_t
- size
- boost/http_proto/fields_view_base/size.adoc
-
- ()
-
-
- void
- swap
- boost/http_proto/request_view/swap.adoc
-
- (request_view& other)
-
-
- core::string_view
- target
- boost/http_proto/request_view/target.adoc
-
- ()
-
-
- http_proto::version
- version
- boost/http_proto/message_view_base/version.adoc
-
- ()
-
-
- std::size_t
- max_size
- boost/http_proto/fields_view_base/max_size.adoc
-
- ()
-
-
- void
- request_view
- boost/http_proto/request_view/2constructor-00.adoc
-
- (const detail::header* ph)
-
-
boost::http_proto::response
boost/http_proto/response.adoc
iterator
begin
- boost/http_proto/fields_view_base/begin.adoc
+ boost/http_proto/fields_base/begin.adoc
()
core::string_view
buffer
- boost/http_proto/fields_view_base/buffer.adoc
+ boost/http_proto/fields_base/buffer.adoc
()
@@ -1967,7 +1476,7 @@
bool
chunked
- boost/http_proto/message_view_base/chunked.adoc
+ boost/http_proto/message_base/chunked.adoc
()
@@ -1981,14 +1490,14 @@
iterator
end
- boost/http_proto/fields_view_base/end.adoc
+ boost/http_proto/fields_base/end.adoc
()
bool
keep_alive
- boost/http_proto/message_view_base/keep_alive.adoc
+ boost/http_proto/message_base/keep_alive.adoc
()
@@ -2002,28 +1511,28 @@
const http_proto::metadata&
metadata
- boost/http_proto/message_view_base/metadata.adoc
+ boost/http_proto/message_base/metadata.adoc
()
http_proto::payload
payload
- boost/http_proto/message_view_base/payload.adoc
+ boost/http_proto/message_base/payload.adoc
()
- std::uint64_t
+ uint64_t
payload_size
- boost/http_proto/message_view_base/payload_size.adoc
+ boost/http_proto/message_base/payload_size.adoc
()
reverse_iterator
rbegin
- boost/http_proto/fields_view_base/rbegin.adoc
+ boost/http_proto/fields_base/rbegin.adoc
()
@@ -2037,7 +1546,7 @@
reverse_iterator
rend
- boost/http_proto/fields_view_base/rend.adoc
+ boost/http_proto/fields_base/rend.adoc
()
@@ -2060,7 +1569,7 @@
set_content_length
boost/http_proto/message_base/set_content_length.adoc
- (std::uint64_t n)
+ (uint64_t n)
void
@@ -2081,7 +1590,7 @@
set_payload_size
boost/http_proto/message_base/set_payload_size.adoc
- (std::uint64_t n)
+ (uint64_t n)
void
@@ -2093,7 +1602,7 @@
std::size_t
size
- boost/http_proto/fields_view_base/size.adoc
+ boost/http_proto/fields_base/size.adoc
()
@@ -2121,21 +1630,14 @@
http_proto::version
version
- boost/http_proto/message_view_base/version.adoc
-
- ()
-
-
- response_view
- operator response_view
- boost/http_proto/response_base/2conversion.adoc
+ boost/http_proto/message_base/version.adoc
()
std::size_t
max_size
- boost/http_proto/fields_view_base/max_size.adoc
+ boost/http_proto/fields_base/max_size.adoc
()
@@ -2146,14 +1648,14 @@
iterator
begin
- boost/http_proto/fields_view_base/begin.adoc
+ boost/http_proto/fields_base/begin.adoc
()
core::string_view
buffer
- boost/http_proto/fields_view_base/buffer.adoc
+ boost/http_proto/fields_base/buffer.adoc
()
@@ -2167,7 +1669,7 @@
bool
chunked
- boost/http_proto/message_view_base/chunked.adoc
+ boost/http_proto/message_base/chunked.adoc
()
@@ -2181,14 +1683,14 @@
iterator
end
- boost/http_proto/fields_view_base/end.adoc
+ boost/http_proto/fields_base/end.adoc
()
bool
keep_alive
- boost/http_proto/message_view_base/keep_alive.adoc
+ boost/http_proto/message_base/keep_alive.adoc
()
@@ -2202,28 +1704,28 @@
const http_proto::metadata&
metadata
- boost/http_proto/message_view_base/metadata.adoc
+ boost/http_proto/message_base/metadata.adoc
()
http_proto::payload
payload
- boost/http_proto/message_view_base/payload.adoc
+ boost/http_proto/message_base/payload.adoc
()
- std::uint64_t
+ uint64_t
payload_size
- boost/http_proto/message_view_base/payload_size.adoc
+ boost/http_proto/message_base/payload_size.adoc
()
reverse_iterator
rbegin
- boost/http_proto/fields_view_base/rbegin.adoc
+ boost/http_proto/fields_base/rbegin.adoc
()
@@ -2237,7 +1739,7 @@
reverse_iterator
rend
- boost/http_proto/fields_view_base/rend.adoc
+ boost/http_proto/fields_base/rend.adoc
()
@@ -2260,7 +1762,7 @@
set_content_length
boost/http_proto/message_base/set_content_length.adoc
- (std::uint64_t n)
+ (uint64_t n)
void
@@ -2281,7 +1783,7 @@
set_payload_size
boost/http_proto/message_base/set_payload_size.adoc
- (std::uint64_t n)
+ (uint64_t n)
void
@@ -2293,7 +1795,7 @@
std::size_t
size
- boost/http_proto/fields_view_base/size.adoc
+ boost/http_proto/fields_base/size.adoc
()
@@ -2314,21 +1816,14 @@
http_proto::version
version
- boost/http_proto/message_view_base/version.adoc
-
- ()
-
-
- response_view
- operator response_view
- boost/http_proto/response_base/2conversion.adoc
+ boost/http_proto/message_base/version.adoc
()
std::size_t
max_size
- boost/http_proto/fields_view_base/max_size.adoc
+ boost/http_proto/fields_base/max_size.adoc
()
@@ -2343,13 +1838,6 @@
boost::http_proto::response_parser
boost/http_proto/response_parser.adoc
-
- void
- response_parser
- boost/http_proto/response_parser/2constructor.adoc
-
- (rts::context& ctx)
-
void
~response_parser
@@ -2357,13 +1845,6 @@
()
-
- parser&
- operator=
- boost/http_proto/parser/operator_assign.adoc
-
- (parser&& other)
-
core::string_view
body
@@ -2393,7 +1874,7 @@
(std::size_t n)
- response_view
+ const static_response&
get
boost/http_proto/response_parser/get.adoc
@@ -2453,7 +1934,7 @@
set_body_limit
boost/http_proto/parser/set_body_limit.adoc
- (std::uint64_t n)
+ (uint64_t n)
void
@@ -2470,150 +1951,6 @@
()
-
- boost::http_proto::response_view
- boost/http_proto/response_view.adoc
-
- void
- ~response_view
- boost/http_proto/response_view/2destructor.adoc
-
- ()
-
-
- response_view&
- operator=
- boost/http_proto/response_view/operator_assign.adoc
-
- (const response_view& other)
-
-
- iterator
- begin
- boost/http_proto/fields_view_base/begin.adoc
-
- ()
-
-
- core::string_view
- buffer
- boost/http_proto/fields_view_base/buffer.adoc
-
- ()
-
-
- bool
- chunked
- boost/http_proto/message_view_base/chunked.adoc
-
- ()
-
-
- iterator
- end
- boost/http_proto/fields_view_base/end.adoc
-
- ()
-
-
- bool
- keep_alive
- boost/http_proto/message_view_base/keep_alive.adoc
-
- ()
-
-
- const http_proto::metadata&
- metadata
- boost/http_proto/message_view_base/metadata.adoc
-
- ()
-
-
- http_proto::payload
- payload
- boost/http_proto/message_view_base/payload.adoc
-
- ()
-
-
- std::uint64_t
- payload_size
- boost/http_proto/message_view_base/payload_size.adoc
-
- ()
-
-
- reverse_iterator
- rbegin
- boost/http_proto/fields_view_base/rbegin.adoc
-
- ()
-
-
- core::string_view
- reason
- boost/http_proto/response_view/reason.adoc
-
- ()
-
-
- reverse_iterator
- rend
- boost/http_proto/fields_view_base/rend.adoc
-
- ()
-
-
- std::size_t
- size
- boost/http_proto/fields_view_base/size.adoc
-
- ()
-
-
- http_proto::status
- status
- boost/http_proto/response_view/status.adoc
-
- ()
-
-
- unsigned short
- status_int
- boost/http_proto/response_view/status_int.adoc
-
- ()
-
-
- void
- swap
- boost/http_proto/response_view/swap.adoc
-
- (response_view& other)
-
-
- http_proto::version
- version
- boost/http_proto/message_view_base/version.adoc
-
- ()
-
-
- std::size_t
- max_size
- boost/http_proto/fields_view_base/max_size.adoc
-
- ()
-
-
- void
- response_view
- boost/http_proto/response_view/2constructor-09.adoc
-
- (const detail::header* ph)
-
-
boost::http_proto::serializer
boost/http_proto/serializer.adoc
@@ -2624,13 +1961,6 @@
()
-
- serializer&
- operator=
- boost/http_proto/serializer/operator_assign.adoc
-
- (serializer&& other)
-
void
consume
@@ -2664,84 +1994,35 @@
start_stream
boost/http_proto/serializer/start_stream.adoc
- (const message_view_base& m)
-
-
- bool
- is_header_done
- boost/http_proto/serializer/is_header_done.adoc
-
- ()
-
-
- detail::array_of_const_buffers
- make_array
- boost/http_proto/serializer/make_array.adoc
-
- (std::size_t n)
-
-
- std::size_t
- out_capacity
- boost/http_proto/serializer/out_capacity.adoc
-
- ()
-
-
- void
- out_commit
- boost/http_proto/serializer/out_commit.adoc
-
- (std::size_t )
-
-
- void
- out_finish
- boost/http_proto/serializer/out_finish.adoc
-
- ()
-
-
- void
- out_init
- boost/http_proto/serializer/out_init.adoc
-
- ()
-
-
- buffers::mutable_buffer_pair
- out_prepare
- boost/http_proto/serializer/out_prepare.adoc
-
- ()
+ (const message_base& m)
void
start_buffers
boost/http_proto/serializer/start_buffers.adoc
- (const message_view_base& )
-
-
- void
- start_empty
- boost/http_proto/serializer/start_empty.adoc
-
- (const message_view_base& )
+ (const message_base& , cbs_gen& )
void
start_init
boost/http_proto/serializer/start_init.adoc
- (const message_view_base& )
+ (const message_base& )
void
start_source
boost/http_proto/serializer/start_source.adoc
- (const message_view_base& )
+ (const message_base& , source& )
+
+
+ detail::workspace&
+ ws
+ boost/http_proto/serializer/ws.adoc
+
+ ()
@@ -2766,122 +2047,20 @@
(const MutableBufferSequence& bs)
-
- boost::http_proto::static_fields
- boost/http_proto/static_fields.adoc
-
- iterator
- begin
- boost/http_proto/fields_view_base/begin.adoc
-
- ()
-
-
- core::string_view
- buffer
- boost/http_proto/fields_view_base/buffer.adoc
-
- ()
-
-
- std::size_t
- capacity_in_bytes
- boost/http_proto/fields_base/capacity_in_bytes.adoc
-
- ()
-
-
- void
- clear
- boost/http_proto/fields_base/clear.adoc
-
- ()
-
-
- iterator
- end
- boost/http_proto/fields_view_base/end.adoc
-
- ()
-
-
- std::size_t
- max_capacity_in_bytes
- boost/http_proto/fields_base/max_capacity_in_bytes.adoc
-
- ()
-
-
- reverse_iterator
- rbegin
- boost/http_proto/fields_view_base/rbegin.adoc
-
- ()
-
-
- reverse_iterator
- rend
- boost/http_proto/fields_view_base/rend.adoc
-
- ()
-
-
- void
- reserve_bytes
- boost/http_proto/fields_base/reserve_bytes.adoc
-
- (std::size_t n)
-
-
- void
- set_max_capacity_in_bytes
- boost/http_proto/fields_base/set_max_capacity_in_bytes.adoc
-
- (std::size_t n)
-
-
- void
- shrink_to_fit
- boost/http_proto/fields_base/shrink_to_fit.adoc
-
- ()
-
-
- std::size_t
- size
- boost/http_proto/fields_view_base/size.adoc
-
- ()
-
-
- fields_view
- operator fields_view
- boost/http_proto/static_fields/2conversion.adoc
-
- ()
-
-
- std::size_t
- max_size
- boost/http_proto/fields_view_base/max_size.adoc
-
- ()
-
-
boost::http_proto::static_request
boost/http_proto/static_request.adoc
iterator
begin
- boost/http_proto/fields_view_base/begin.adoc
+ boost/http_proto/fields_base/begin.adoc
()
core::string_view
buffer
- boost/http_proto/fields_view_base/buffer.adoc
+ boost/http_proto/fields_base/buffer.adoc
()
@@ -2895,7 +2074,7 @@
bool
chunked
- boost/http_proto/message_view_base/chunked.adoc
+ boost/http_proto/message_base/chunked.adoc
()
@@ -2909,14 +2088,14 @@
iterator
end
- boost/http_proto/fields_view_base/end.adoc
+ boost/http_proto/fields_base/end.adoc
()
bool
keep_alive
- boost/http_proto/message_view_base/keep_alive.adoc
+ boost/http_proto/message_base/keep_alive.adoc
()
@@ -2930,7 +2109,7 @@
const http_proto::metadata&
metadata
- boost/http_proto/message_view_base/metadata.adoc
+ boost/http_proto/message_base/metadata.adoc
()
@@ -2951,28 +2130,28 @@
http_proto::payload
payload
- boost/http_proto/message_view_base/payload.adoc
+ boost/http_proto/message_base/payload.adoc
()
- std::uint64_t
+ uint64_t
payload_size
- boost/http_proto/message_view_base/payload_size.adoc
+ boost/http_proto/message_base/payload_size.adoc
()
reverse_iterator
rbegin
- boost/http_proto/fields_view_base/rbegin.adoc
+ boost/http_proto/fields_base/rbegin.adoc
()
reverse_iterator
rend
- boost/http_proto/fields_view_base/rend.adoc
+ boost/http_proto/fields_base/rend.adoc
()
@@ -2995,7 +2174,7 @@
set_content_length
boost/http_proto/message_base/set_content_length.adoc
- (std::uint64_t n)
+ (uint64_t n)
void
@@ -3023,7 +2202,7 @@
set_payload_size
boost/http_proto/message_base/set_payload_size.adoc
- (std::uint64_t n)
+ (uint64_t n)
void
@@ -3049,7 +2228,7 @@
std::size_t
size
- boost/http_proto/fields_view_base/size.adoc
+ boost/http_proto/fields_base/size.adoc
()
@@ -3063,21 +2242,14 @@
http_proto::version
version
- boost/http_proto/message_view_base/version.adoc
-
- ()
-
-
- request_view
- operator request_view
- boost/http_proto/request_base/2conversion.adoc
+ boost/http_proto/message_base/version.adoc
()
std::size_t
max_size
- boost/http_proto/fields_view_base/max_size.adoc
+ boost/http_proto/fields_base/max_size.adoc
()
@@ -3088,14 +2260,14 @@
iterator
begin
- boost/http_proto/fields_view_base/begin.adoc
+ boost/http_proto/fields_base/begin.adoc
()
core::string_view
buffer
- boost/http_proto/fields_view_base/buffer.adoc
+ boost/http_proto/fields_base/buffer.adoc
()
@@ -3109,7 +2281,7 @@
bool
chunked
- boost/http_proto/message_view_base/chunked.adoc
+ boost/http_proto/message_base/chunked.adoc
()
@@ -3123,14 +2295,14 @@
iterator
end
- boost/http_proto/fields_view_base/end.adoc
+ boost/http_proto/fields_base/end.adoc
()
bool
keep_alive
- boost/http_proto/message_view_base/keep_alive.adoc
+ boost/http_proto/message_base/keep_alive.adoc
()
@@ -3144,28 +2316,28 @@
const http_proto::metadata&
metadata
- boost/http_proto/message_view_base/metadata.adoc
+ boost/http_proto/message_base/metadata.adoc
()
http_proto::payload
payload
- boost/http_proto/message_view_base/payload.adoc
+ boost/http_proto/message_base/payload.adoc
()
- std::uint64_t
+ uint64_t
payload_size
- boost/http_proto/message_view_base/payload_size.adoc
+ boost/http_proto/message_base/payload_size.adoc
()
reverse_iterator
rbegin
- boost/http_proto/fields_view_base/rbegin.adoc
+ boost/http_proto/fields_base/rbegin.adoc
()
@@ -3179,7 +2351,7 @@
reverse_iterator
rend
- boost/http_proto/fields_view_base/rend.adoc
+ boost/http_proto/fields_base/rend.adoc
()
@@ -3202,7 +2374,7 @@
set_content_length
boost/http_proto/message_base/set_content_length.adoc
- (std::uint64_t n)
+ (uint64_t n)
void
@@ -3223,7 +2395,7 @@
set_payload_size
boost/http_proto/message_base/set_payload_size.adoc
- (std::uint64_t n)
+ (uint64_t n)
void
@@ -3235,7 +2407,7 @@
std::size_t
size
- boost/http_proto/fields_view_base/size.adoc
+ boost/http_proto/fields_base/size.adoc
()
@@ -3256,21 +2428,14 @@
http_proto::version
version
- boost/http_proto/message_view_base/version.adoc
-
- ()
-
-
- response_view
- operator response_view
- boost/http_proto/response_base/2conversion.adoc
+ boost/http_proto/message_base/version.adoc
()
std::size_t
max_size
- boost/http_proto/fields_view_base/max_size.adoc
+ boost/http_proto/fields_base/max_size.adoc
()
diff --git a/include/boost/http_proto.hpp b/include/boost/http_proto.hpp
index 41ffe717..38dca128 100644
--- a/include/boost/http_proto.hpp
+++ b/include/boost/http_proto.hpp
@@ -14,27 +14,21 @@
#include
#include
#include
-#include
-#include
#include
#include
#include
#include
#include
#include
-#include
#include
#include
#include
#include
-#include
#include
#include
-#include
#include
#include
#include
-#include
#include
#include
#include
diff --git a/include/boost/http_proto/fields.hpp b/include/boost/http_proto/fields.hpp
index dc0ae554..607e8e51 100644
--- a/include/boost/http_proto/fields.hpp
+++ b/include/boost/http_proto/fields.hpp
@@ -14,8 +14,6 @@
#include
#include
-#include
-#include
namespace boost {
namespace http_proto {
@@ -46,8 +44,7 @@ namespace http_proto {
@endcode
@see
- @ref static_fields,
- @ref fields_view.
+ @ref fields_base.
*/
class fields final
: public fields_base
@@ -78,8 +75,11 @@ class fields final
@par Complexity
Constant.
*/
- BOOST_HTTP_PROTO_DECL
- fields() noexcept;
+ fields() noexcept
+ : fields_base(detail::kind::fields)
+ {
+ }
+
/** Constructor.
@@ -116,10 +116,12 @@ class fields final
@param s The string to parse.
*/
- BOOST_HTTP_PROTO_DECL
explicit
fields(
- core::string_view s);
+ core::string_view s)
+ : fields_base(detail::kind::fields, s)
+ {
+ }
/** Constructor.
@@ -147,11 +149,15 @@ class fields final
@param max_cap Maximum allowed capacity in bytes.
*/
- BOOST_HTTP_PROTO_DECL
explicit
fields(
std::size_t cap,
- std::size_t max_cap = std::size_t(-1));
+ std::size_t max_cap = std::size_t(-1))
+ : fields()
+ {
+ reserve_bytes(cap);
+ set_max_capacity_in_bytes(max_cap);
+ }
/** Constructor.
@@ -172,29 +178,12 @@ class fields final
@param f The fields to move from.
*/
- BOOST_HTTP_PROTO_DECL
- fields(fields&& f) noexcept;
-
- /** Constructor.
-
- The newly constructed object contains
- a copy of `f`.
-
- @par Postconditions
- @code
- this->buffer() == f.buffer() && this->buffer().data() != f.buffer().data()
- @endcode
-
- @par Complexity
- Linear in `f.size()`.
-
- @par Exception Safety
- Calls to allocate may throw.
+ fields(fields&& f) noexcept
+ : fields_base(f.h_.kind)
+ {
+ swap(f);
+ }
- @param f The fields to copy.
- */
- BOOST_HTTP_PROTO_DECL
- fields(fields const& f);
/** Constructor.
@@ -210,13 +199,11 @@ class fields final
Linear in `f.size()`.
@par Exception Safety
- Strong guarantee.
Calls to allocate may throw.
@param f The fields to copy.
*/
- BOOST_HTTP_PROTO_DECL
- fields(fields_view const& f);
+ fields(fields const& f) = default;
/** Assignment.
@@ -239,40 +226,11 @@ class fields final
@return A reference to this object.
*/
- BOOST_HTTP_PROTO_DECL
- fields&
- operator=(fields&& f) noexcept;
-
- /** Assignment.
-
- The contents of `f` are copied and
- the previous contents of `this` are
- discarded.
-
- @par Postconditions
- @code
- this->buffer() == f.buffer() && this->buffer().data() != f.buffer().data()
- @endcode
-
- @par Complexity
- Linear in `f.size()`.
-
- @par Exception Safety
- Strong guarantee.
- Calls to allocate may throw.
- Exception thrown if max capacity exceeded.
-
- @throw std::length_error
- Max capacity would be exceeded.
-
- @return A reference to this object.
-
- @param f The fields to copy.
- */
fields&
- operator=(fields const& f) noexcept
+ operator=(fields&& f) noexcept
{
- copy_impl(*f.ph_);
+ fields tmp(std::move(f));
+ tmp.swap(*this);
return *this;
}
@@ -288,7 +246,7 @@ class fields final
@endcode
@par Complexity
- Linear in `r.size()`.
+ Linear in `f.size()`.
@par Exception Safety
Strong guarantee.
@@ -303,24 +261,12 @@ class fields final
@param f The fields to copy.
*/
fields&
- operator=(fields_view const& f)
+ operator=(fields const& f) noexcept
{
- copy_impl(*f.ph_);
+ copy_impl(f.h_);
return *this;
}
- /** Conversion.
-
- @see
- @ref fields_view.
-
- @return A view of the fields.
- */
- operator fields_view() const noexcept
- {
- return fields_view(ph_);
- }
-
//--------------------------------------------
/** Swap.
diff --git a/include/boost/http_proto/fields_base.hpp b/include/boost/http_proto/fields_base.hpp
index ce9f25f8..e9c4e4bc 100644
--- a/include/boost/http_proto/fields_base.hpp
+++ b/include/boost/http_proto/fields_base.hpp
@@ -14,9 +14,11 @@
#include
#include
-#include
+#include
#include
+#include
+
namespace boost {
namespace http_proto {
@@ -31,7 +33,6 @@ namespace http_proto {
@note HTTP field names are case-insensitive.
*/
class fields_base
- : public virtual fields_view_base
{
detail::header h_;
std::size_t max_cap_ =
@@ -63,17 +64,15 @@ class fields_base
};
friend class fields;
- template
- friend class static_fields;
+ friend class message_base;
friend class request_base;
friend class request;
- template
friend class static_request;
friend class response_base;
friend class response;
- template
friend class static_response;
- friend class message_base;
+ friend class parser;
+ friend class serializer;
BOOST_HTTP_PROTO_DECL
explicit
@@ -83,7 +82,7 @@ class fields_base
BOOST_HTTP_PROTO_DECL
fields_base(
detail::kind k,
- char* storage,
+ void* storage,
std::size_t cap) noexcept;
BOOST_HTTP_PROTO_DECL
@@ -92,29 +91,398 @@ class fields_base
core::string_view s);
BOOST_HTTP_PROTO_DECL
+ explicit
fields_base(
- detail::kind k,
- char* storage,
- std::size_t cap,
- core::string_view s);
+ detail::header const& h);
BOOST_HTTP_PROTO_DECL
- explicit
fields_base(
- detail::header const& h);
+ fields_base const&);
BOOST_HTTP_PROTO_DECL
fields_base(
detail::header const& h,
- char* storage,
+ void* storage,
std::size_t cap);
public:
+ //--------------------------------------------
+ //
+ // Types
+ //
+ //--------------------------------------------
+
+ /** A view to an HTTP field.
+
+ The view will be invalidated when the
+ underlying container is modified.
+
+ The caller is responsible for ensuring
+ that the lifetime of the container extends
+ until it is no longer referenced.
+ */
+ struct reference
+ {
+ /** Field name constant.
+
+ Set to `boost::none` if the constant
+ does not exist in @ref field.
+ */
+ boost::optional const id;
+
+ /// A view to the field name.
+ core::string_view const name;
+
+ /// A view to the field value.
+ core::string_view const value;
+
+ reference const*
+ operator->() const noexcept
+ {
+ return this;
+ }
+ };
+
+ /// @copydoc reference
+ typedef reference const_reference;
+
+ /** A value type which represent an HTTP field.
+
+ This type allows for making a copy of
+ a field where ownership is retained
+ in the copy.
+ */
+ struct value_type
+ {
+ /** Field name constant.
+
+ Set to `boost::none` if the
+ constant does not exist in @ref field.
+ */
+ boost::optional id;
+
+ /// Field name.
+ std::string name;
+
+ /// Field value.
+ std::string value;
+
+ /// Constructor.
+ BOOST_HTTP_PROTO_DECL
+ value_type(
+ reference const& other);
+
+ /** Conversion.
+
+ @see
+ @ref reference.
+
+ @return A view to the fields.
+ */
+ operator reference() const noexcept;
+ };
+
+ /** A bidirectional iterator to HTTP fields.
+ */
+ class iterator;
+
+ /// @copydoc iterator
+ using const_iterator = iterator;
+
+ /** A bidirectional reverse iterator to HTTP fields.
+ */
+ class reverse_iterator;
+
+ /// @copydoc iterator
+ using const_reverse_iterator = reverse_iterator;
+
+ /** A forward range of matching fields.
+
+ Objects of this type are returned by
+ the function @ref find_all.
+ */
+ class subrange;
+
+ //--------------------------------------------
+ //
+ // Special Members
+ //
+ //--------------------------------------------
+
/** Destructor.
*/
BOOST_HTTP_PROTO_DECL
~fields_base();
+ //--------------------------------------------
+ //
+ // Observers
+ //
+ //--------------------------------------------
+
+ /** Return the largest possible serialized message.
+ */
+ static
+ constexpr
+ std::size_t
+ max_size() noexcept
+ {
+ // TODO: this doesn't take into account
+ // the start-line
+ return detail::header::max_offset;
+ }
+
+ /** Return an iterator to the beginning.
+ */
+ iterator
+ begin() const noexcept;
+
+ /** Return an iterator to the end.
+ */
+ iterator
+ end() const noexcept;
+
+ /** Return a reverse iterator to the beginning.
+ */
+ reverse_iterator
+ rbegin() const noexcept;
+
+ /** Return a reverse iterator to the end.
+ */
+ reverse_iterator
+ rend() const noexcept;
+
+ /** Return a string view representing the serialized data.
+ */
+ core::string_view
+ buffer() const noexcept
+ {
+ return core::string_view(
+ h_.cbuf, h_.size);
+ }
+
+ /** Return the number of fields in the container.
+ */
+ std::size_t
+ size() const noexcept
+ {
+ return h_.count;
+ }
+
+ /** Return the value of a field, or throws an exception.
+
+ If more than one field with the specified
+ name exists, the first field defined by
+ insertion order is returned.
+
+ @par Exception Safety
+ Strong guarantee.
+
+ @throw std::out_of_range
+ Field is not found.
+
+ @param id The field name constant.
+ */
+ BOOST_HTTP_PROTO_DECL
+ core::string_view
+ at(field id) const;
+
+ /** Return the value of a field, or throws an exception.
+
+ If more than one field with the specified
+ name exists, the first field defined by
+ insertion order is returned.
+
+ If `name` refers to a known field, it is
+ faster to call @ref at with a field id
+ instead of a string.
+
+ @par Exception Safety
+ Strong guarantee.
+
+ @throw std::out_of_range
+ Field is not found.
+
+ @param name The field name.
+ */
+ BOOST_HTTP_PROTO_DECL
+ core::string_view
+ at(core::string_view name) const;
+
+ /** Return true if a field exists.
+ */
+ BOOST_HTTP_PROTO_DECL
+ bool
+ exists(field id) const noexcept;
+
+ /** Return true if a field exists.
+
+ If `name` refers to a known field,
+ it is faster to call @ref exists
+ with a field id instead of a string.
+
+ @param name The field name.
+ */
+ BOOST_HTTP_PROTO_DECL
+ bool
+ exists(
+ core::string_view name) const noexcept;
+
+ /** Return the number of matching fields.
+
+ @param id The field name constant.
+ */
+ BOOST_HTTP_PROTO_DECL
+ std::size_t
+ count(field id) const noexcept;
+
+ /** Return the number of matching fields.
+
+ If `name` refers to a known field,
+ it is faster to call @ref count
+ with a field id instead of a string.
+
+ @param name The field name.
+ */
+ BOOST_HTTP_PROTO_DECL
+ std::size_t
+ count(
+ core::string_view name) const noexcept;
+
+ /** Return an iterator to the matching element if it exists.
+
+ @param id The field name constant.
+ */
+ BOOST_HTTP_PROTO_DECL
+ iterator
+ find(field id) const noexcept;
+
+ /** Return an iterator to the matching element if it exists.
+
+ If `name` refers to a known field,
+ it is faster to call @ref find
+ with a field id instead of a string.
+
+ @param name The field name.
+ */
+ BOOST_HTTP_PROTO_DECL
+ iterator
+ find(
+ core::string_view name) const noexcept;
+
+ /** Return an iterator to the matching element if it exists.
+
+ @param from The position to begin the
+ search from. This can be `end()`.
+
+ @param id The field name constant.
+ */
+ BOOST_HTTP_PROTO_DECL
+ iterator
+ find(
+ iterator from,
+ field id) const noexcept;
+
+ /** Return an iterator to the matching element if it exists.
+
+ If `name` refers to a known field,
+ it is faster to call @ref find
+ with a field id instead of a string.
+
+ @param from The position to begin the
+ search from. This can be `end()`.
+
+ @param name The field name.
+ */
+ BOOST_HTTP_PROTO_DECL
+ iterator
+ find(
+ iterator from,
+ core::string_view name) const noexcept;
+
+ /** Return an iterator to the matching element if it exists.
+
+ @param before One past the position
+ to begin the search from. This can
+ be `end()`.
+
+ @param id The field name constant.
+ */
+ BOOST_HTTP_PROTO_DECL
+ iterator
+ find_last(
+ iterator before,
+ field id) const noexcept;
+
+ /** Return an iterator to the matching element if it exists.
+
+ If `name` refers to a known field,
+ it is faster to call @ref find_last
+ with a field id instead of a string.
+
+ @param before One past the position
+ to begin the search from. This can
+ be `end()`.
+
+ @param name The field name.
+ */
+ BOOST_HTTP_PROTO_DECL
+ iterator
+ find_last(
+ iterator before,
+ core::string_view name) const noexcept;
+
+ /** Return the value of a field or a default if missing.
+
+ @param id The field name constant.
+
+ @param s The value to be returned if
+ field does not exist.
+ */
+ BOOST_HTTP_PROTO_DECL
+ core::string_view
+ value_or(
+ field id,
+ core::string_view s) const noexcept;
+
+ /** Return the value of a field or a default if missing.
+
+ If `name` refers to a known field,
+ it is faster to call @ref value_or
+ with a field id instead of a string.
+
+ @param name The field name.
+
+ @param s The value to be returned if
+ field does not exist.
+ */
+ BOOST_HTTP_PROTO_DECL
+ core::string_view
+ value_or(
+ core::string_view name,
+ core::string_view s) const noexcept;
+
+ /** Return a forward range containing values for all matching fields.
+
+ @param id The field name constant.
+ */
+ BOOST_HTTP_PROTO_DECL
+ subrange
+ find_all(field id) const noexcept;
+
+ /** Return a forward range containing values for all matching fields.
+
+ If `name` refers to a known field,
+ it is faster to call @ref find_all
+ with a field id instead of a string.
+
+ @param name The field name.
+ */
+ BOOST_HTTP_PROTO_DECL
+ subrange
+ find_all(
+ core::string_view name) const noexcept;
+
//--------------------------------------------
//
// Capacity
@@ -467,19 +835,12 @@ class fields_base
@param value The value which must be semantically
valid for the message.
*/
+ BOOST_HTTP_PROTO_DECL
iterator
insert(
iterator before,
field id,
- core::string_view value)
- {
- system::error_code ec;
- auto const it = insert(
- before, id, value, ec);
- if(ec.failed())
- detail::throw_system_error(ec);
- return it;
- }
+ core::string_view value);
/** Insert a header.
@@ -523,21 +884,13 @@ class fields_base
@param ec Set to the error if input is invalid.
*/
+ BOOST_HTTP_PROTO_DECL
iterator
insert(
iterator before,
field id,
core::string_view value,
- system::error_code& ec)
- {
- insert_impl(
- id,
- to_string(id),
- value,
- before.i_,
- ec);
- return before;
- }
+ system::error_code& ec);
/** Insert a header.
@@ -583,18 +936,12 @@ class fields_base
@param value The value which must be semantically
valid for the message.
*/
+ BOOST_HTTP_PROTO_DECL
iterator
insert(
iterator before,
core::string_view name,
- core::string_view value)
- {
- system::error_code ec;
- insert(before, name, value, ec);
- if(ec.failed())
- detail::throw_system_error(ec);
- return before;
- }
+ core::string_view value);
/** Insert a header.
@@ -638,21 +985,13 @@ class fields_base
@param ec Set to the error if input is invalid.
*/
+ BOOST_HTTP_PROTO_DECL
iterator
insert(
iterator before,
core::string_view name,
core::string_view value,
- system::error_code& ec)
- {
- insert_impl(
- string_to_field(name),
- name,
- value,
- before.i_,
- ec);
- return before;
- }
+ system::error_code& ec);
//--------------------------------------------
@@ -752,16 +1091,9 @@ class fields_base
@param value The value which must be semantically
valid for the message.
*/
+ BOOST_HTTP_PROTO_DECL
void
- set(
- iterator it,
- core::string_view value)
- {
- system::error_code ec;
- set(it, value, ec);
- if(ec.failed())
- detail::throw_system_error(ec);
- }
+ set(iterator it, core::string_view value);
/** Set a header value.
@@ -1020,7 +1352,45 @@ class fields_base
std::size_t i) const noexcept;
};
+/** Format the container to the output stream
+
+ This function serializes the container to
+ the specified output stream.
+
+ @par Example
+ @code
+ request req;
+ std::stringstream ss;
+ ss << req;
+ assert( ss.str() == "GET / HTTP/1.1\r\n\r\n" );
+ @endcode
+
+ @par Effects
+ @code
+ return os << f.buffer();
+ @endcode
+
+ @par Complexity
+ Linear in `f.buffer().size()`
+
+ @par Exception Safety
+ Basic guarantee.
+
+ @return A reference to the output stream, for chaining
+
+ @param os The output stream to write to.
+
+ @param f The container to write.
+*/
+BOOST_HTTP_PROTO_DECL
+std::ostream&
+operator<<(
+ std::ostream& os,
+ const fields_base& f);
+
} // http_proto
} // boost
+#include
+
#endif
diff --git a/include/boost/http_proto/fields_view.hpp b/include/boost/http_proto/fields_view.hpp
deleted file mode 100644
index c2c8d40e..00000000
--- a/include/boost/http_proto/fields_view.hpp
+++ /dev/null
@@ -1,217 +0,0 @@
-//
-// Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
-// Copyright (c) 2025 Mohammad Nejati
-//
-// 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)
-//
-// Official repository: https://github.com/cppalliance/http_proto
-//
-
-#ifndef BOOST_HTTP_PROTO_FIELDS_VIEW_HPP
-#define BOOST_HTTP_PROTO_FIELDS_VIEW_HPP
-
-#include
-#include
-#include
-
-namespace boost {
-namespace http_proto {
-
-/** A view to a valid HTTP headers section.
-
- Objects of this type represent a view to
- an HTTP fields container. That is, it acts
- like a `core::string_view` in terms of
- ownership. The caller is responsible for
- ensuring that the lifetime of the underlying
- buffer extends until it is no
- longer referenced.
-
- @see
- @ref fields,
- @ref static_fields,
-*/
-class fields_view
- : public fields_view_base
-{
- friend class fields;
- template
- friend class static_fields;
-
- fields_view(
- detail::header const* ph) noexcept
- : fields_view_base(ph)
- {
- BOOST_ASSERT(ph_->kind ==
- detail::kind::fields);
- }
-
-public:
-
- //--------------------------------------------
- //
- // Special Members
- //
- //--------------------------------------------
-
- /** Constructor.
-
- A default-constructed fields views refer to
- a valid HTTP headers section that contains
- no name-value pairs, which always remains
- valid.
-
- @par Example
- @code
- fields fs;
- @endcode
-
- @par Postconditions
- @code
- this->buffer() == "\r\n"
- @endcode
-
- @par Complexity
- Constant.
- */
- fields_view() noexcept
- : fields_view_base(
- detail::header::get_default(
- detail::kind::fields))
- {
- }
-
- /** Constructor.
-
- After construction, both fields views
- reference the same underlying buffer.
- Ownership is not transferred.
-
- @par Postconditions
- @code
- this->buffer().data() == other.buffer().data()
- @endcode
-
- @par Complexity
- Constant.
-
- @param other The other view.
- */
- fields_view(
- fields_view const& other) noexcept = default;
-
- /** Assignment.
-
- After assignment, both fields views
- reference the same underlying buffer.
- Ownership is not transferred.
-
- @par Postconditions
- @code
- this->buffer().data() == other.buffer().data()
- @endcode
-
- @par Complexity
- Constant.
-
- @return A reference to this object.
-
- @param other The other view.
- */
- fields_view&
- operator=(
- fields_view const& other) noexcept = default;
-
- /** Destructor
-
- Any reference, iterator, or other view
- which reference the same underlying
- buffer remain valid.
- */
- ~fields_view() = default;
-
- //--------------------------------------------
-
- /** Swap.
-
- Exchanges the view with that of `other`.
- All iterators and references remain valid.
-
- If `this == &other`, this function call has no effect.
-
- @par Example
- @code
- fields f1;
- f1.set(field::accept, "text/html");
- fields f2;
- f2.set(field::connection, "keep-alive");
- fields_view v1 = f1;
- fields_view v2 = f2;
- v1.swap(v2);
- assert(v1.buffer() == "Connection: keep-alive\r\n\r\n" );
- assert(v2.buffer() == "Accept: text/html\r\n\r\n" );
- @endcode
-
- @par Complexity
- Constant.
-
- @param other The object to swap with.
- */
- void
- swap(fields_view& other) noexcept
- {
- auto ph = ph_;
- ph_ = other.ph_;
- other.ph_ = ph;
- }
-
- /** Swap.
-
- Exchanges the view of `v0` with
- another `v1`. All iterators and
- references remain valid.
-
- If `&v0 == &v1`, this function call has no effect.
-
- @par Example
- @code
- fields f1;
- f1.set(field::accept, "text/html");
- fields f2;
- f2.set(field::connection, "keep-alive");
- fields_view v1 = f1;
- fields_view v2 = f2;
- std::swap(v1, v2);
- assert(v1.buffer() == "Connection: keep-alive\r\n\r\n" );
- assert(v2.buffer() == "Accept: text/html\r\n\r\n" );
- @endcode
-
- @par Effects
- @code
- v0.swap(v1);
- @endcode
-
- @par Complexity
- Constant.
-
- @param v0 The first object to swap.
- @param v1 The second object to swap.
-
- @see
- @ref fields_view::swap
- */
- friend
- void
- swap(
- fields_view& v0,
- fields_view& v1) noexcept
- {
- v0.swap(v1);
- }
-};
-
-} // http_proto
-} // boost
-
-#endif
diff --git a/include/boost/http_proto/fields_view_base.hpp b/include/boost/http_proto/fields_view_base.hpp
deleted file mode 100644
index 8bf213e3..00000000
--- a/include/boost/http_proto/fields_view_base.hpp
+++ /dev/null
@@ -1,476 +0,0 @@
-//
-// Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
-// Copyright (c) 2025 Mohammad Nejati
-//
-// 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)
-//
-// Official repository: https://github.com/cppalliance/http_proto
-//
-
-#ifndef BOOST_HTTP_PROTO_FIELDS_VIEW_BASE_HPP
-#define BOOST_HTTP_PROTO_FIELDS_VIEW_BASE_HPP
-
-#include
-#include
-
-#include
-#include
-#include
-
-#include
-#include
-
-namespace boost {
-namespace http_proto {
-
-/** A read-only, bidirectional range of HTTP fields.
-
- This is a mix-in used to add common
- functionality to derived classes.
-*/
-class fields_view_base
-{
- detail::header const* ph_;
-
- friend class fields;
- template
- friend class static_fields;
- friend class fields_base;
- friend class fields_view;
- friend class message_base;
- friend class message_view_base;
- friend class request_base;
- friend class request;
- template
- friend class static_request;
- friend class request_view;
- friend class response_base;
- friend class response;
- template
- friend class static_response;
- friend class response_view;
- friend class serializer;
-
- explicit
- fields_view_base(
- detail::header const* ph) noexcept
- : ph_(ph)
- {
- }
-
- fields_view_base(
- fields_view_base const&) = default;
- fields_view_base&
- operator=(fields_view_base const&) = default;
-
-public:
- //--------------------------------------------
- //
- // Types
- //
- //--------------------------------------------
-
- /** A view to an HTTP field.
-
- The view will be invalidated when the
- underlying container is modified.
-
- The caller is responsible for ensuring
- that the lifetime of the container extends
- until it is no longer referenced.
- */
- struct reference
- {
- /** Field name constant.
-
- Set to `boost::none` if the constant
- does not exist in @ref field.
- */
- boost::optional const id;
-
- /// A view to the field name.
- core::string_view const name;
-
- /// A view to the field value.
- core::string_view const value;
-
- reference const*
- operator->() const noexcept
- {
- return this;
- }
- };
-
- /// @copydoc reference
- typedef reference const_reference;
-
- /** A value type which represent an HTTP field.
-
- This type allows for making a copy of
- a field where ownership is retained
- in the copy.
- */
- struct value_type
- {
- /** Field name constant.
-
- Set to `boost::none` if the
- constant does not exist in @ref field.
- */
- boost::optional id;
-
- /// Field name.
- std::string name;
-
- /// Field value.
- std::string value;
-
- /// Constructor.
- BOOST_HTTP_PROTO_DECL
- value_type(
- reference const& other);
-
- /** Conversion.
-
- @see
- @ref reference.
-
- @return A view to the fields.
- */
- operator reference() const noexcept;
- };
-
- /** A bidirectional iterator to HTTP fields.
- */
- class iterator;
-
- /// @copydoc iterator
- using const_iterator = iterator;
-
- /** A bidirectional reverse iterator to HTTP fields.
- */
- class reverse_iterator;
-
- /// @copydoc iterator
- using const_reverse_iterator = reverse_iterator;
-
- /** A forward range of matching fields.
-
- Objects of this type are returned by
- the function @ref find_all.
- */
- class subrange;
-
- //--------------------------------------------
- //
- // Observers
- //
- //--------------------------------------------
-
- /** Return the largest possible serialized message.
- */
- static
- constexpr
- std::size_t
- max_size() noexcept
- {
- // TODO: this doesn't take into account
- // the start-line
- return detail::header::max_offset;
- }
-
- /** Return an iterator to the beginning.
- */
- iterator
- begin() const noexcept;
-
- /** Return an iterator to the end.
- */
- iterator
- end() const noexcept;
-
- /** Return a reverse iterator to the beginning.
- */
- reverse_iterator
- rbegin() const noexcept;
-
- /** Return a reverse iterator to the end.
- */
- reverse_iterator
- rend() const noexcept;
-
- /** Return a string view representing the serialized data.
- */
- core::string_view
- buffer() const noexcept
- {
- return core::string_view(
- ph_->cbuf, ph_->size);
- }
-
- /** Return the number of fields in the container.
- */
- std::size_t
- size() const noexcept
- {
- return ph_->count;
- }
-
- /** Return the value of a field, or throws an exception.
-
- If more than one field with the specified
- name exists, the first field defined by
- insertion order is returned.
-
- @par Exception Safety
- Strong guarantee.
-
- @throw std::out_of_range
- Field is not found.
-
- @param id The field name constant.
- */
- BOOST_HTTP_PROTO_DECL
- core::string_view
- at(field id) const;
-
- /** Return the value of a field, or throws an exception.
-
- If more than one field with the specified
- name exists, the first field defined by
- insertion order is returned.
-
- If `name` refers to a known field, it is
- faster to call @ref at with a field id
- instead of a string.
-
- @par Exception Safety
- Strong guarantee.
-
- @throw std::out_of_range
- Field is not found.
-
- @param name The field name.
- */
- BOOST_HTTP_PROTO_DECL
- core::string_view
- at(core::string_view name) const;
-
- /** Return true if a field exists.
- */
- BOOST_HTTP_PROTO_DECL
- bool
- exists(field id) const noexcept;
-
- /** Return true if a field exists.
-
- If `name` refers to a known field,
- it is faster to call @ref exists
- with a field id instead of a string.
-
- @param name The field name.
- */
- BOOST_HTTP_PROTO_DECL
- bool
- exists(
- core::string_view name) const noexcept;
-
- /** Return the number of matching fields.
-
- @param id The field name constant.
- */
- BOOST_HTTP_PROTO_DECL
- std::size_t
- count(field id) const noexcept;
-
- /** Return the number of matching fields.
-
- If `name` refers to a known field,
- it is faster to call @ref count
- with a field id instead of a string.
-
- @param name The field name.
- */
- BOOST_HTTP_PROTO_DECL
- std::size_t
- count(
- core::string_view name) const noexcept;
-
- /** Return an iterator to the matching element if it exists.
-
- @param id The field name constant.
- */
- BOOST_HTTP_PROTO_DECL
- iterator
- find(field id) const noexcept;
-
- /** Return an iterator to the matching element if it exists.
-
- If `name` refers to a known field,
- it is faster to call @ref find
- with a field id instead of a string.
-
- @param name The field name.
- */
- BOOST_HTTP_PROTO_DECL
- iterator
- find(
- core::string_view name) const noexcept;
-
- /** Return an iterator to the matching element if it exists.
-
- @param from The position to begin the
- search from. This can be `end()`.
-
- @param id The field name constant.
- */
- BOOST_HTTP_PROTO_DECL
- iterator
- find(
- iterator from,
- field id) const noexcept;
-
- /** Return an iterator to the matching element if it exists.
-
- If `name` refers to a known field,
- it is faster to call @ref find
- with a field id instead of a string.
-
- @param from The position to begin the
- search from. This can be `end()`.
-
- @param name The field name.
- */
- BOOST_HTTP_PROTO_DECL
- iterator
- find(
- iterator from,
- core::string_view name) const noexcept;
-
- /** Return an iterator to the matching element if it exists.
-
- @param before One past the position
- to begin the search from. This can
- be `end()`.
-
- @param id The field name constant.
- */
- BOOST_HTTP_PROTO_DECL
- iterator
- find_last(
- iterator before,
- field id) const noexcept;
-
- /** Return an iterator to the matching element if it exists.
-
- If `name` refers to a known field,
- it is faster to call @ref find_last
- with a field id instead of a string.
-
- @param before One past the position
- to begin the search from. This can
- be `end()`.
-
- @param name The field name.
- */
- BOOST_HTTP_PROTO_DECL
- iterator
- find_last(
- iterator before,
- core::string_view name) const noexcept;
-
- /** Return the value of a field or a default if missing.
-
- @param id The field name constant.
-
- @param s The value to be returned if
- field does not exist.
- */
- BOOST_HTTP_PROTO_DECL
- core::string_view
- value_or(
- field id,
- core::string_view s) const noexcept;
-
- /** Return the value of a field or a default if missing.
-
- If `name` refers to a known field,
- it is faster to call @ref value_or
- with a field id instead of a string.
-
- @param name The field name.
-
- @param s The value to be returned if
- field does not exist.
- */
- BOOST_HTTP_PROTO_DECL
- core::string_view
- value_or(
- core::string_view name,
- core::string_view s) const noexcept;
-
- /** Return a forward range containing values for all matching fields.
-
- @param id The field name constant.
- */
- BOOST_HTTP_PROTO_DECL
- subrange
- find_all(field id) const noexcept;
-
- /** Return a forward range containing values for all matching fields.
-
- If `name` refers to a known field,
- it is faster to call @ref find_all
- with a field id instead of a string.
-
- @param name The field name.
- */
- BOOST_HTTP_PROTO_DECL
- subrange
- find_all(
- core::string_view name) const noexcept;
-};
-
-/** Format the container to the output stream
-
- This function serializes the container to
- the specified output stream.
-
- @par Example
- @code
- request req;
- std::stringstream ss;
- ss << req;
- assert( ss.str() == "GET / HTTP/1.1\r\n\r\n" );
- @endcode
-
- @par Effects
- @code
- return os << f.buffer();
- @endcode
-
- @par Complexity
- Linear in `f.buffer().size()`
-
- @par Exception Safety
- Basic guarantee.
-
- @return A reference to the output stream, for chaining
-
- @param os The output stream to write to.
-
- @param f The container to write.
-*/
-BOOST_HTTP_PROTO_DECL
-std::ostream&
-operator<<(
- std::ostream& os,
- const fields_view_base& f);
-
-} // http_proto
-} // boost
-
-#include
-
-#endif
diff --git a/include/boost/http_proto/http_proto.natvis b/include/boost/http_proto/http_proto.natvis
index 4a830bfb..efd3005c 100644
--- a/include/boost/http_proto/http_proto.natvis
+++ b/include/boost/http_proto/http_proto.natvis
@@ -32,10 +32,10 @@
-
- { *ph_ }
+
+ { h_ }
- *ph_
+ h_
diff --git a/include/boost/http_proto/impl/fields_view_base.hpp b/include/boost/http_proto/impl/fields_base.hpp
similarity index 90%
rename from include/boost/http_proto/impl/fields_view_base.hpp
rename to include/boost/http_proto/impl/fields_base.hpp
index 02883cb4..576780b9 100644
--- a/include/boost/http_proto/impl/fields_view_base.hpp
+++ b/include/boost/http_proto/impl/fields_base.hpp
@@ -7,8 +7,8 @@
// Official repository: https://github.com/cppalliance/http_proto
//
-#ifndef BOOST_HTTP_PROTO_IMPL_FIELDS_VIEW_BASE_HPP
-#define BOOST_HTTP_PROTO_IMPL_FIELDS_VIEW_BASE_HPP
+#ifndef BOOST_HTTP_PROTO_IMPL_FIELDS_BASE_HPP
+#define BOOST_HTTP_PROTO_IMPL_FIELDS_BASE_HPP
#include
#include
@@ -22,13 +22,12 @@ namespace http_proto {
//
//------------------------------------------------
-class fields_view_base::iterator
+class fields_base::iterator
{
detail::header const* ph_ = nullptr;
std::size_t i_ = 0;
friend class fields_base;
- friend class fields_view_base;
iterator(
detail::header const* ph,
@@ -40,9 +39,9 @@ class fields_view_base::iterator
public:
using value_type =
- fields_view_base::value_type;
+ fields_base::value_type;
using reference =
- fields_view_base::reference;
+ fields_base::reference;
using pointer = reference;
using difference_type =
std::ptrdiff_t;
@@ -118,13 +117,12 @@ class fields_view_base::iterator
//------------------------------------------------
-class fields_view_base::reverse_iterator
+class fields_base::reverse_iterator
{
detail::header const* ph_ = nullptr;
std::size_t i_ = 0;
friend class fields_base;
- friend class fields_view_base;
reverse_iterator(
detail::header const* ph,
@@ -136,9 +134,9 @@ class fields_view_base::reverse_iterator
public:
using value_type =
- fields_view_base::value_type;
+ fields_base::value_type;
using reference =
- fields_view_base::reference;
+ fields_base::reference;
using pointer = reference;
using difference_type =
std::ptrdiff_t;
@@ -226,13 +224,12 @@ class fields_view_base::reverse_iterator
//
//------------------------------------------------
-class fields_view_base::subrange
+class fields_base::subrange
{
detail::header const* ph_ = nullptr;
std::size_t i_ = 0;
- friend class fields_view;
- friend class fields_view_base;
+ friend class fields_base;
friend struct detail::header;
subrange(
@@ -273,13 +270,13 @@ class fields_view_base::subrange
//
//------------------------------------------------
-class fields_view_base::subrange::
+class fields_base::subrange::
iterator
{
detail::header const* ph_ = nullptr;
std::size_t i_ = 0;
- friend class fields_view_base::subrange;
+ friend class fields_base::subrange;
BOOST_HTTP_PROTO_DECL
iterator(
@@ -307,7 +304,7 @@ class fields_view_base::subrange::
// conversion to regular iterator
operator
- fields_view_base::
+ fields_base::
iterator() const noexcept
{
return {ph_, i_};
@@ -357,7 +354,7 @@ class fields_view_base::subrange::
inline
auto
-fields_view_base::
+fields_base::
subrange::
begin() const noexcept ->
iterator
@@ -367,7 +364,7 @@ begin() const noexcept ->
inline
auto
-fields_view_base::
+fields_base::
subrange::
end() const noexcept ->
iterator
@@ -378,10 +375,10 @@ end() const noexcept ->
//------------------------------------------------
inline
-fields_view_base::
+fields_base::
value_type::
operator
-fields_view_base::
+fields_base::
reference() const noexcept
{
return reference{
@@ -392,25 +389,25 @@ reference() const noexcept
inline
auto
-fields_view_base::
+fields_base::
begin() const noexcept ->
iterator
{
- return iterator(ph_, 0);
+ return iterator(&h_, 0);
}
inline
auto
-fields_view_base::
+fields_base::
end() const noexcept ->
iterator
{
- return iterator(ph_, ph_->count);
+ return iterator(&h_, h_.count);
}
inline
auto
-fields_view_base::
+fields_base::
rbegin() const noexcept ->
reverse_iterator
{
@@ -419,7 +416,7 @@ rbegin() const noexcept ->
inline
auto
-fields_view_base::
+fields_base::
rend() const noexcept ->
reverse_iterator
{
diff --git a/include/boost/http_proto/impl/serializer.hpp b/include/boost/http_proto/impl/serializer.hpp
index f3273fe7..1613dc6b 100644
--- a/include/boost/http_proto/impl/serializer.hpp
+++ b/include/boost/http_proto/impl/serializer.hpp
@@ -117,7 +117,7 @@ template<
void
serializer::
start(
- message_view_base const& m,
+ message_base const& m,
ConstBufferSequence&& cbs)
{
static_assert(buffers::is_const_buffer_sequence<
@@ -139,7 +139,7 @@ template<
Source&
serializer::
start(
- message_view_base const& m,
+ message_base const& m,
Args&&... args)
{
static_assert(
diff --git a/include/boost/http_proto/message_base.hpp b/include/boost/http_proto/message_base.hpp
index c46c3fdc..24e3a995 100644
--- a/include/boost/http_proto/message_base.hpp
+++ b/include/boost/http_proto/message_base.hpp
@@ -13,7 +13,6 @@
#include
#include
-#include
#include
namespace boost {
@@ -27,7 +26,6 @@ namespace http_proto {
and responses.
@see
- @ref message_view_base,
@ref response,
@ref request,
@ref static_response,
@@ -36,74 +34,83 @@ namespace http_proto {
*/
class message_base
: public fields_base
- , public message_view_base
{
friend class request_base;
friend class response_base;
- explicit
- message_base(
- detail::kind k) noexcept
- : fields_view_base(
- &this->fields_base::h_)
- , fields_base(k)
+ using fields_base::fields_base;
+
+public:
+ //--------------------------------------------
+ //
+ // Observers
+ //
+ //--------------------------------------------
+
+ /** Return the type of payload of this message.
+ */
+ auto
+ payload() const noexcept ->
+ http_proto::payload
{
+ return h_.md.payload;
}
- message_base(
- detail::kind k,
- char* storage,
- std::size_t cap) noexcept
- : fields_view_base(&this->fields_base::h_)
- , fields_base(
- k, storage, cap)
+ /** Return the payload size.
+
+ When @ref payload returns @ref payload::size,
+ this function returns the number of octets
+ in the actual message payload.
+
+ @return The number of octets in the
+ actual message payload.
+ */
+ std::uint64_t
+ payload_size() const noexcept
{
+ BOOST_ASSERT(
+ payload() == payload::size);
+ return h_.md.payload_size;
}
- message_base(
- detail::kind k,
- core::string_view s)
- : fields_view_base(
- &this->fields_base::h_)
- , fields_base(k, s)
+ /** Return true if semantics indicate
+ connection persistence.
+ */
+ bool
+ keep_alive() const noexcept
{
+ return h_.keep_alive();
}
- message_base(
- detail::kind k,
- char* storage,
- std::size_t cap,
- core::string_view s)
- : fields_view_base(
- &this->fields_base::h_)
- , fields_base(
- k, storage, cap, s)
+ /** Return metadata about the message.
+ */
+ auto
+ metadata() const noexcept ->
+ http_proto::metadata const&
{
+ return h_.md;
}
- explicit
- message_base(
- detail::header const& ph)
- : fields_view_base(
- &this->fields_base::h_)
- , fields_base(ph)
+ /** Return true if the message is using a chunked
+ transfer encoding.
+ */
+ bool
+ chunked() const noexcept
{
+ return h_.md.transfer_encoding.is_chunked;
}
- message_base(
- detail::header const& ph,
- char* storage,
- std::size_t cap)
- : fields_view_base(
- &this->fields_base::h_)
- , fields_base(ph, storage, cap)
+ /** Return the HTTP-version.
+ */
+ http_proto::version
+ version() const noexcept
{
+ return h_.version;
}
-public:
//--------------------------------------------
//
- // Metadata
+ // Modifiers
//
//--------------------------------------------
diff --git a/include/boost/http_proto/message_view_base.hpp b/include/boost/http_proto/message_view_base.hpp
deleted file mode 100644
index 99daea98..00000000
--- a/include/boost/http_proto/message_view_base.hpp
+++ /dev/null
@@ -1,130 +0,0 @@
-//
-// Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
-// Copyright (c) 2024 Christian Mazakas
-// Copyright (c) 2025 Mohammad Nejati
-//
-// 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)
-//
-// Official repository: https://github.com/cppalliance/http_proto
-//
-
-#ifndef BOOST_HTTP_PROTO_MESSAGE_VIEW_BASE_HPP
-#define BOOST_HTTP_PROTO_MESSAGE_VIEW_BASE_HPP
-
-#include
-#include
-
-namespace boost {
-namespace http_proto {
-
-/** Provides read-only access to common metadata
- in HTTP request and response messages.
-
- This type is useful for accessing common
- properties shared by request and response
- messages.
-
- @see
- @ref message_base,
- @ref response_view,
- @ref request_view,
- @ref metadata,
- @ref response_parser,
- @ref request_parser.
-*/
-class message_view_base
- : public virtual fields_view_base
-{
- friend class request_view;
- friend class response_view;
- friend class message_base;
-
- message_view_base() noexcept
- // VFALCO This ctor-init has to be
- // here even though it isn't called,
- // so nullptr doesn't matter.
- : fields_view_base(nullptr)
- {
- }
-
- explicit
- message_view_base(
- detail::header const* ph) noexcept
- : fields_view_base(ph)
- {
- }
-
-public:
- //--------------------------------------------
- //
- // Metadata
- //
- //--------------------------------------------
-
- /** Return the type of payload of this message.
- */
- auto
- payload() const noexcept ->
- http_proto::payload
- {
- return ph_->md.payload;
- }
-
- /** Return the payload size.
-
- When @ref payload returns @ref payload::size,
- this function returns the number of octets
- in the actual message payload.
-
- @return The number of octets in the
- actual message payload.
- */
- std::uint64_t
- payload_size() const noexcept
- {
- BOOST_ASSERT(
- payload() == payload::size);
- return ph_->md.payload_size;
- }
-
- /** Return true if semantics indicate
- connection persistence.
- */
- bool
- keep_alive() const noexcept
- {
- return ph_->keep_alive();
- }
-
- /** Return metadata about the message.
- */
- auto
- metadata() const noexcept ->
- http_proto::metadata const&
- {
- return ph_->md;
- }
-
- /** Return true if the message is using a chunked
- transfer encoding.
- */
- bool
- chunked() const noexcept
- {
- return ph_->md.transfer_encoding.is_chunked;
- }
-
- /** Return the HTTP-version.
- */
- http_proto::version
- version() const noexcept
- {
- return ph_->version;
- }
-};
-
-} // http_proto
-} // boost
-
-#endif
diff --git a/include/boost/http_proto/parser.hpp b/include/boost/http_proto/parser.hpp
index 5a347eb8..c2552fa8 100644
--- a/include/boost/http_proto/parser.hpp
+++ b/include/boost/http_proto/parser.hpp
@@ -32,6 +32,8 @@ namespace http_proto {
// Forward declaration
class request_parser;
class response_parser;
+class static_request;
+class static_response;
/** A parser for HTTP/1 messages.
@@ -627,8 +629,11 @@ class parser
void
start_impl(bool);
- detail::header const*
- safe_get_header() const;
+ static_request const&
+ safe_get_request() const;
+
+ static_response const&
+ safe_get_response() const;
BOOST_HTTP_PROTO_DECL
detail::workspace&
diff --git a/include/boost/http_proto/request.hpp b/include/boost/http_proto/request.hpp
index d9c43d93..e9741b0f 100644
--- a/include/boost/http_proto/request.hpp
+++ b/include/boost/http_proto/request.hpp
@@ -43,13 +43,12 @@ namespace http_proto {
@see
@ref static_request,
- @ref request_view.
+ @ref request_base.
*/
class request
: public request_base
{
public:
-
//--------------------------------------------
//
// Special Members
@@ -74,8 +73,7 @@ class request
@par Complexity
Constant.
*/
- BOOST_HTTP_PROTO_DECL
- request() noexcept;
+ request() noexcept = default;
/** Constructor.
@@ -111,10 +109,12 @@ class request
@param s The string to parse.
*/
- BOOST_HTTP_PROTO_DECL
explicit
request(
- core::string_view s);
+ core::string_view s)
+ : request_base(s)
+ {
+ }
/** Constructor.
@@ -203,10 +203,14 @@ class request
@param max_cap Maximum allowed capacity in bytes.
*/
- BOOST_HTTP_PROTO_DECL
request(
std::size_t cap,
- std::size_t max_cap = std::size_t(-1));
+ std::size_t max_cap = std::size_t(-1))
+ : request()
+ {
+ reserve_bytes(cap);
+ set_max_capacity_in_bytes(max_cap);
+ }
/** Constructor.
@@ -227,8 +231,12 @@ class request
@param r The request to move from.
*/
- BOOST_HTTP_PROTO_DECL
- request(request&& r) noexcept;
+ request(
+ request&& other) noexcept
+ : request()
+ {
+ swap(other);
+ }
/** Constructor.
@@ -248,8 +256,8 @@ class request
@param r The request to copy.
*/
- BOOST_HTTP_PROTO_DECL
- request(request const& r);
+ request(
+ request const& r) = default;
/** Constructor.
@@ -265,14 +273,15 @@ class request
Linear in `r.size()`.
@par Exception Safety
- Strong guarantee.
Calls to allocate may throw.
@param r The request to copy.
*/
- BOOST_HTTP_PROTO_DECL
request(
- request_view const& r);
+ request_base const& r)
+ : request_base(r)
+ {
+ }
/** Assignment
@@ -295,10 +304,13 @@ class request
@return A reference to this object.
*/
- BOOST_HTTP_PROTO_DECL
request&
- operator=(request&& r) noexcept;
-
+ operator=(request&& r) noexcept
+ {
+ request temp(std::move(r));
+ temp.swap(*this);
+ return *this;
+ }
/** Assignment.
@@ -330,7 +342,7 @@ class request
operator=(
request const& r)
{
- copy_impl(*r.ph_);
+ copy_impl(r.h_);
return *this;
}
@@ -362,9 +374,9 @@ class request
*/
request&
operator=(
- request_view const& r)
+ request_base const& r)
{
- copy_impl(*r.ph_);
+ copy_impl(r.h_);
return *this;
}
@@ -399,7 +411,6 @@ class request
std::swap(max_cap_, other.max_cap_);
}
-
/** Swap.
Exchanges the contents of `v0` with
diff --git a/include/boost/http_proto/request_base.hpp b/include/boost/http_proto/request_base.hpp
index d7587fb8..450158d3 100644
--- a/include/boost/http_proto/request_base.hpp
+++ b/include/boost/http_proto/request_base.hpp
@@ -13,7 +13,6 @@
#include
#include
-#include
namespace boost {
namespace http_proto {
@@ -29,86 +28,28 @@ class request_base
: public message_base
{
friend class request;
- template
friend class static_request;
request_base() noexcept
- : fields_view_base(
- &this->fields_base::h_)
- , message_base(detail::kind::request)
+ : message_base(detail::kind::request)
{
}
explicit
request_base(core::string_view s)
- : fields_view_base(
- &this->fields_base::h_)
- , message_base(detail::kind::request, s)
+ : message_base(detail::kind::request, s)
{
}
- explicit
- request_base(detail::header const& ph)
- : fields_view_base(
- &this->fields_base::h_)
- , message_base(ph)
- {
- }
-
- request_base(
- detail::header const& ph,
- char* storage,
- std::size_t cap)
- : fields_view_base(
- &this->fields_base::h_)
- , message_base(ph, storage, cap)
- {
- }
-
-public:
request_base(
- char* storage,
+ void* storage,
std::size_t cap) noexcept
- : fields_view_base(
- &this->fields_base::h_)
- , message_base(
+ : message_base(
detail::kind::request, storage, cap)
{
}
- request_base(
- core::string_view s,
- char* storage,
- std::size_t cap)
- : fields_view_base(
- &this->fields_base::h_)
- , message_base(
- detail::kind::request, storage, cap, s)
- {
- }
-
- request_base(
- request_view const& other,
- char* storage,
- std::size_t cap)
- : fields_view_base(
- &this->fields_base::h_)
- , message_base(*other.ph_, storage, cap)
- {
- }
-
- /** Conversion.
-
- @see
- @ref request_view.
-
- @return A view of the request.
- */
- operator request_view() const noexcept
- {
- return request_view(ph_);
- }
-
+public:
//--------------------------------------------
//
// Observers
@@ -125,7 +66,7 @@ class request_base
http_proto::method
method() const noexcept
{
- return ph_->req.method;
+ return h_.req.method;
}
/** Return the method as a string.
@@ -134,8 +75,8 @@ class request_base
method_text() const noexcept
{
return core::string_view(
- ph_->cbuf,
- ph_->req.method_len);
+ h_.cbuf,
+ h_.req.method_len);
}
/** Return the request-target string.
@@ -144,9 +85,9 @@ class request_base
target() const noexcept
{
return core::string_view(
- ph_->cbuf +
- ph_->req.method_len + 1,
- ph_->req.target_len);
+ h_.cbuf +
+ h_.req.method_len + 1,
+ h_.req.target_len);
}
//--------------------------------------------
@@ -233,7 +174,7 @@ class request_base
core::string_view s)
{
set_start_line_impl(
- ph_->req.method,
+ h_.req.method,
method_text(),
s,
version());
@@ -256,7 +197,7 @@ class request_base
http_proto::version v)
{
set_start_line_impl(
- ph_->req.method,
+ h_.req.method,
method_text(),
target(),
v);
diff --git a/include/boost/http_proto/request_parser.hpp b/include/boost/http_proto/request_parser.hpp
index e329e67e..7ad99bfb 100644
--- a/include/boost/http_proto/request_parser.hpp
+++ b/include/boost/http_proto/request_parser.hpp
@@ -15,7 +15,7 @@
#include
#include
#include
-#include
+#include
namespace boost {
namespace http_proto {
@@ -114,9 +114,9 @@ class request_parser
*/
~request_parser() = default;
- /** Return a read-only view to the parsed request headers.
+ /** Return a reference to the parsed request headers.
- The returned view remains valid until:
+ The returned reference remains valid until:
@li @ref start is called
@li @ref reset is called
@li The parser instance is destroyed
@@ -133,7 +133,7 @@ class request_parser
@ref got_header.
*/
BOOST_HTTP_PROTO_DECL
- request_view
+ static_request const&
get() const;
};
diff --git a/include/boost/http_proto/request_view.hpp b/include/boost/http_proto/request_view.hpp
deleted file mode 100644
index 23de7d29..00000000
--- a/include/boost/http_proto/request_view.hpp
+++ /dev/null
@@ -1,251 +0,0 @@
-//
-// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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)
-//
-// Official repository: https://github.com/cppalliance/http_proto
-//
-
-#ifndef BOOST_HTTP_PROTO_REQUEST_VIEW_HPP
-#define BOOST_HTTP_PROTO_REQUEST_VIEW_HPP
-
-#include
-#include
-#include
-
-namespace boost {
-namespace http_proto {
-
-/** A view to a valid HTTP request.
-
- Objects of this type represent a view to
- a HTTP request container. That is, it acts
- like a `core::string_view` in terms of
- ownership. The caller is responsible for
- ensuring that the lifetime of the underlying
- buffer extends until it is no
- longer referenced.
-
- @see
- @ref request,
- @ref static_request,
- @ref request_parser,
-*/
-class request_view
- : public message_view_base
-{
- friend class request_base;
- friend class request_parser;
-
- explicit
- request_view(
- detail::header const* ph) noexcept
- : fields_view_base(ph)
- {
- BOOST_ASSERT(ph_->kind ==
- detail::kind::request);
- }
-
-public:
- //--------------------------------------------
- //
- // Special Members
- //
- //--------------------------------------------
-
- /** Constructor.
-
- A default-constructed request views refer
- to a valid HTTP `GET` request with no
- headers, which always remains valid.
-
- @par Example
- @code
- request_view reqv;
- @endcode
-
- @par Postconditions
- @code
- this->buffer() == "GET / HTTP/1.1\r\n\r\n"
- @endcode
-
- @par Complexity
- Constant.
- */
- request_view() noexcept
- : fields_view_base(
- detail::header::get_default(
- detail::kind::request))
- {
- }
-
- /** Constructor.
-
- After construction, both request views
- reference the same underlying buffer.
- Ownership is not transferred.
-
- @par Postconditions
- @code
- this->buffer().data() == other.buffer().data()
- @endcode
-
- @par Complexity
- Constant.
-
- @param other The other view.
- */
- request_view(
- request_view const& other) noexcept = default;
-
- /** Assignment.
-
- After assignment, both request views
- reference the same underlying buffer.
- Ownership is not transferred.
-
- @par Postconditions
- @code
- this->buffer().data() == other.buffer().data()
- @endcode
-
- @par Complexity
- Constant.
-
- @return A reference to this object.
-
- @param other The other view.
- */
- request_view&
- operator=(
- request_view const& other) noexcept = default;
-
- /** Destructor
-
- Any reference, iterators, or other views
- which reference the same underlying
- buffer remain valid.
- */
- ~request_view() = default;
-
- //--------------------------------------------
- //
- // Observers
- //
- //--------------------------------------------
-
- /** Return the method as an integral constant
-
- If the method returned is equal to
- @ref method::unknown, the method may
- be obtained as a string instead, by
- calling @ref method_text.
- */
- http_proto::method
- method() const noexcept
- {
- return ph_->req.method;
- };
-
- /** Return the method as a string
- */
- core::string_view
- method_text() const noexcept
- {
- return core::string_view(
- ph_->cbuf,
- ph_->req.method_len);
- }
-
- /** Return the request-target string.
- */
- core::string_view
- target() const noexcept
- {
- return core::string_view(
- ph_->cbuf +
- ph_->req.method_len + 1,
- ph_->req.target_len);
- }
-
- //--------------------------------------------
-
- /** Swap.
-
- Exchanges the view with that of `other`.
- All iterators and references remain valid.
-
- If `this == &other`, this function call has no effect.
-
- @par Example
- @code
- request r1(method::get, "/");
- request r2(method::delete_, "/item/42");
- request_view v1 = r1;
- request_view v2 = r2;
- v1.swap(v2);
- assert(v1.buffer() == "DELETE /item/42 HTTP/1.1\r\n\r\n" );
- assert(v2.buffer() == "GET / HTTP/1.1\r\n\r\n" );
- @endcode
-
- @par Complexity
- Constant.
-
- @param other The object to swap with.
- */
- void
- swap(request_view& other) noexcept
- {
- auto ph = ph_;
- ph_ = other.ph_;
- ph_ = ph;
- }
-
- /** Swap.
-
- Exchanges the view of `v0` with
- another `v1`. All iterators and
- references remain valid.
-
- If `&v0 == &v1`, this function call has no effect.
-
- @par Example
- @code
- request r1(method::get, "/");
- request r2(method::delete_, "/item/42");
- request_view v1 = r1;
- request_view v2 = r2;
- std::swap(v1, v2);
- assert(v1.buffer() == "DELETE /item/42 HTTP/1.1\r\n\r\n" );
- assert(v2.buffer() == "GET / HTTP/1.1\r\n\r\n" );
- @endcode
-
- @par Effects
- @code
- v0.swap(v1);
- @endcode
-
- @par Complexity
- Constant.
-
- @param v0 The first object to swap.
- @param v1 The second object to swap.
-
- @see
- @ref request_view::swap.
- */
- friend
- void
- swap(
- request_view& v0,
- request_view& v1) noexcept
- {
- v0.swap(v1);
- }
-};
-
-} // http_proto
-} // boost
-
-#endif
diff --git a/include/boost/http_proto/response.hpp b/include/boost/http_proto/response.hpp
index 71dc6dd1..0650abb7 100644
--- a/include/boost/http_proto/response.hpp
+++ b/include/boost/http_proto/response.hpp
@@ -45,13 +45,12 @@ namespace http_proto {
@see
@ref static_response,
- @ref response_view.
+ @ref response_base.
*/
class response
: public response_base
{
public:
-
//--------------------------------------------
//
// Special Members
@@ -76,8 +75,7 @@ class response
@par Complexity
Constant.
*/
- BOOST_HTTP_PROTO_DECL
- response() noexcept;
+ response() noexcept = default;
/** Constructor.
@@ -113,10 +111,12 @@ class response
@param s The string to parse.
*/
- BOOST_HTTP_PROTO_DECL
explicit
response(
- core::string_view s);
+ core::string_view s)
+ : response_base(s)
+ {
+ }
/** Constructor.
@@ -143,10 +143,15 @@ class response
@param max_cap Maximum allowed capacity in bytes.
*/
- BOOST_HTTP_PROTO_DECL
+ explicit
response(
std::size_t cap,
- std::size_t max_cap = std::size_t(-1));
+ std::size_t max_cap = std::size_t(-1))
+ : response()
+ {
+ reserve_bytes(cap);
+ set_max_capacity_in_bytes(max_cap);
+ }
/** Constructor.
@@ -169,10 +174,13 @@ class response
@param v The HTTP version.
*/
- BOOST_HTTP_PROTO_DECL
response(
http_proto::status sc,
- http_proto::version v);
+ http_proto::version v)
+ : response()
+ {
+ set_start_line(sc, v);
+ }
/** Constructor.
@@ -194,10 +202,13 @@ class response
@param sc The status code.
*/
- BOOST_HTTP_PROTO_DECL
explicit
response(
- http_proto::status sc);
+ http_proto::status sc)
+ : response(
+ sc, http_proto::version::http_1_1)
+ {
+ }
/** Constructor.
@@ -218,8 +229,11 @@ class response
@param r The response to move from.
*/
- BOOST_HTTP_PROTO_DECL
- response(response&& r) noexcept;
+ response(response&& r) noexcept
+ : response()
+ {
+ swap(r);
+ }
/** Constructor.
@@ -239,8 +253,7 @@ class response
@param r The response to copy.
*/
- BOOST_HTTP_PROTO_DECL
- response(response const& r);
+ response(response const&) = default;
/** Constructor.
@@ -256,14 +269,14 @@ class response
Linear in `r.size()`.
@par Exception Safety
- Strong guarantee.
Calls to allocate may throw.
@param r The response to copy.
*/
- BOOST_HTTP_PROTO_DECL
- response(
- response_view const& r);
+ response(response_base const& r)
+ : response_base(r)
+ {
+ }
/** Assignment
@@ -286,10 +299,14 @@ class response
@return A reference to this object.
*/
- BOOST_HTTP_PROTO_DECL
response&
operator=(
- response&& r) noexcept;
+ response&& r) noexcept
+ {
+ response temp(std::move(r));
+ temp.swap(*this);
+ return *this;
+ }
/** Assignment.
@@ -321,7 +338,7 @@ class response
operator=(
response const& r)
{
- copy_impl(*r.ph_);
+ copy_impl(r.h_);
return *this;
}
@@ -353,9 +370,9 @@ class response
*/
response&
operator=(
- response_view const& r)
+ response_base const& r)
{
- copy_impl(*r.ph_);
+ copy_impl(r.h_);
return *this;
}
diff --git a/include/boost/http_proto/response_base.hpp b/include/boost/http_proto/response_base.hpp
index 8bc18211..3708b0d9 100644
--- a/include/boost/http_proto/response_base.hpp
+++ b/include/boost/http_proto/response_base.hpp
@@ -14,7 +14,6 @@
#include
#include
-#include
#include
namespace boost {
@@ -31,86 +30,28 @@ class response_base
: public message_base
{
friend class response;
- template
friend class static_response;
response_base() noexcept
- : fields_view_base(
- &this->fields_base::h_)
- , message_base(detail::kind::response)
+ : message_base(detail::kind::response)
{
}
explicit
response_base(core::string_view s)
- : fields_view_base(
- &this->fields_base::h_)
- , message_base(detail::kind::response, s)
+ : message_base(detail::kind::response, s)
{
}
- explicit
- response_base(detail::header const& ph)
- : fields_view_base(
- &this->fields_base::h_)
- , message_base(ph)
- {
- }
-
- response_base(
- detail::header const& ph,
- char* storage,
- std::size_t cap)
- : fields_view_base(
- &this->fields_base::h_)
- , message_base(ph, storage, cap)
- {
- }
-
-public:
response_base(
- char* storage,
+ void* storage,
std::size_t cap) noexcept
- : fields_view_base(
- &this->fields_base::h_)
- , message_base(
+ : message_base(
detail::kind::response, storage, cap)
{
}
- response_base(
- core::string_view s,
- char* storage,
- std::size_t cap)
- : fields_view_base(
- &this->fields_base::h_)
- , message_base(
- detail::kind::response, storage, cap, s)
- {
- }
-
- response_base(
- response_view const& other,
- char* storage,
- std::size_t cap)
- : fields_view_base(
- &this->fields_base::h_)
- , message_base(*other.ph_, storage, cap)
- {
- }
-
- /** Conversion.
-
- @see
- @ref response_view.
-
- @return A view of the response.
- */
- operator response_view() const noexcept
- {
- return response_view(ph_);
- }
-
+public:
//--------------------------------------------
//
// Observers
@@ -127,8 +68,8 @@ class response_base
reason() const noexcept
{
return core::string_view(
- ph_->cbuf + 13,
- ph_->prefix - 15);
+ h_.cbuf + 13,
+ h_.prefix - 15);
}
/** Return the status code.
@@ -136,7 +77,7 @@ class response_base
http_proto::status
status() const noexcept
{
- return ph_->res.status;
+ return h_.res.status;
}
/** Return the status code as an integral.
@@ -144,7 +85,7 @@ class response_base
unsigned short
status_int() const noexcept
{
- return ph_->res.status_int;
+ return h_.res.status_int;
}
//--------------------------------------------
diff --git a/include/boost/http_proto/response_parser.hpp b/include/boost/http_proto/response_parser.hpp
index 00e0b772..6d3380e5 100644
--- a/include/boost/http_proto/response_parser.hpp
+++ b/include/boost/http_proto/response_parser.hpp
@@ -14,7 +14,7 @@
#include
#include
#include
-#include
+#include
#include
namespace boost {
@@ -143,9 +143,9 @@ class response_parser
start_impl(true);
}
- /** Return a read-only view to the parsed response headers.
+ /** Return a reference to the parsed response headers.
- The returned view remains valid until:
+ The returned reference remains valid until:
@li @ref start or @ref start_head_response is called
@li @ref reset is called
@li The parser instance is destroyed
@@ -162,7 +162,7 @@ class response_parser
@ref got_header.
*/
BOOST_HTTP_PROTO_DECL
- response_view
+ static_response const&
get() const;
};
diff --git a/include/boost/http_proto/response_view.hpp b/include/boost/http_proto/response_view.hpp
deleted file mode 100644
index 4a52d7fc..00000000
--- a/include/boost/http_proto/response_view.hpp
+++ /dev/null
@@ -1,247 +0,0 @@
-//
-// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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)
-//
-// Official repository: https://github.com/cppalliance/http_proto
-//
-
-#ifndef BOOST_HTTP_PROTO_RESPONSE_VIEW_HPP
-#define BOOST_HTTP_PROTO_RESPONSE_VIEW_HPP
-
-#include
-#include
-#include
-
-namespace boost {
-namespace http_proto {
-
-/** A view to a valid HTTP response.
-
- Objects of this type represent a view to
- a HTTP response container. That is, it acts
- like a `core::string_view` in terms of
- ownership. The caller is responsible for
- ensuring that the lifetime of the underlying
- buffer extends until it is no
- longer referenced.
-
- @see
- @ref response,
- @ref static_response,
- @ref response_parser,
-*/
-class response_view
- : public message_view_base
-{
- friend class response_base;
- friend class response_parser;
-
- explicit
- response_view(
- detail::header const* ph) noexcept
- : fields_view_base(ph)
- {
- BOOST_ASSERT(ph_->kind ==
- detail::kind::response);
- }
-
-public:
-
- //--------------------------------------------
- //
- // Special Members
- //
- //--------------------------------------------
-
- /** Constructor.
-
- A default-constructed response view refer
- to a valid HTTP 200 OK response with no
- headers, which always remains valid.
-
- @par Example
- @code
- response_view resv;
- @endcode
-
- @par Postconditions
- @code
- this->buffer() == "HTTP/1.1 200 OK\r\n\r\n"
- @endcode
-
- @par Complexity
- Constant.
- */
- response_view() noexcept
- : fields_view_base(
- detail::header::get_default(
- detail::kind::response))
- {
- }
-
- /** Constructor.
-
- After construction, both response views
- reference the same underlying buffer.
- Ownership is not transferred.
-
- @par Postconditions
- @code
- this->buffer().data() == other.buffer().data()
- @endcode
-
- @par Complexity
- Constant.
-
- @param other The other view.
- */
- response_view(
- response_view const& other) noexcept = default;
-
- /** Assignment.
-
- After assignment, both response views
- reference the same underlying buffer.
- Ownership is not transferred.
-
- @par Postconditions
- @code
- this->buffer().data() == other.buffer().data()
- @endcode
-
- @par Complexity
- Constant.
-
- @param other The other view.
- @return A reference to this object.
- */
- response_view&
- operator=(
- response_view const& other) noexcept = default;
-
- /** Destructor
-
- Any reference, iterators, or other views
- which reference the same underlying
- buffer remain valid.
- */
- ~response_view() = default;
-
- //--------------------------------------------
- //
- // Observers
- //
- //--------------------------------------------
-
- /** Return the reason string
-
- This field is obsolete in `HTTP/1.1`
- and should only be used for display
- purposes.
- */
- core::string_view
- reason() const noexcept
- {
- return core::string_view(
- ph_->cbuf + 13,
- ph_->prefix - 15);
- }
-
- /** Return the status code.
- */
- http_proto::status
- status() const noexcept
- {
- return ph_->res.status;
- }
-
- /** Return the status code integer.
- */
- unsigned short
- status_int() const noexcept
- {
- return ph_->res.status_int;
- }
-
- //--------------------------------------------
-
- /** Swap.
-
- Exchanges the view with that of `other`.
- All iterators and references remain valid.
-
- If `this == &other`, this function call has no effect.
-
- @par Example
- @code
- response r1(status::ok);
- response r2(status::bad_request);
- response_view v1 = r1;
- response_view v2 = r2;
- v1.swap(v2);
- assert(v1.buffer() == "HTTP/1.1 400 Bad Request\r\n\r\n" );
- assert(v2.buffer() == "HTTP/1.1 200 OK\r\n\r\n" );
- @endcode
-
- @par Complexity
- Constant.
-
- @param other The object to swap with.
- */
- void
- swap(response_view& other) noexcept
- {
- auto ph = ph_;
- ph_ = other.ph_;
- ph_ = ph;
- }
-
- /** Swap.
-
- Exchanges the view of `v0` with
- another `v1`. All iterators and
- references remain valid.
-
- If `&v0 == &v1`, this function call has no effect.
-
- @par Example
- @code
- response r1(status::ok);
- response r2(status::bad_request);
- response_view v1 = r1;
- response_view v2 = r2;
- std::swap(v1, v2);
- assert(v1.buffer() == "HTTP/1.1 400 Bad Request\r\n\r\n" );
- assert(v2.buffer() == "HTTP/1.1 200 OK\r\n\r\n" );
- @endcode
-
- @par Effects
- @code
- v0.swap(v1);
- @endcode
-
- @par Complexity
- Constant.
-
- @param v0 The first object to swap.
- @param v1 The second object to swap.
-
- @see
- @ref response_view::swap.
- */
- friend
- void
- swap(
- response_view& v0,
- response_view& v1) noexcept
- {
- v0.swap(v1);
- }
-};
-
-} // http_proto
-} // boost
-
-#endif
diff --git a/include/boost/http_proto/rfc/combine_field_values.hpp b/include/boost/http_proto/rfc/combine_field_values.hpp
index 0e0e1152..1811a870 100644
--- a/include/boost/http_proto/rfc/combine_field_values.hpp
+++ b/include/boost/http_proto/rfc/combine_field_values.hpp
@@ -11,7 +11,7 @@
#define BOOST_HTTP_PROTO_RFC_COMBINE_FIELD_VALUES_HPP
#include
-#include
+#include
#include
#include
#include
@@ -55,7 +55,7 @@ namespace http_proto {
BOOST_HTTP_PROTO_DECL
core::string_view
combine_field_values(
- fields_view_base::subrange const& vr,
+ fields_base::subrange const& vr,
grammar::recycled_ptr& temp);
} // http_proto
diff --git a/include/boost/http_proto/serializer.hpp b/include/boost/http_proto/serializer.hpp
index 0d3fbfc0..f65f13ad 100644
--- a/include/boost/http_proto/serializer.hpp
+++ b/include/boost/http_proto/serializer.hpp
@@ -27,7 +27,7 @@ namespace boost {
namespace http_proto {
// Forward declaration
-class message_view_base;
+class message_base;
/** A serializer for HTTP/1 messages
@@ -191,11 +191,11 @@ class serializer
start-line and headers from.
@see
- @ref message_view_base.
+ @ref message_base.
*/
void
BOOST_HTTP_PROTO_DECL
- start(message_view_base const& m);
+ start(message_base const& m);
/** Prepare the serializer for a new message with a ConstBufferSequence body.
@@ -248,7 +248,7 @@ class serializer
until @ref is_done returns `true`.
@see
- @ref message_view_base.
+ @ref message_base.
*/
template<
class ConstBufferSequence,
@@ -258,7 +258,7 @@ class serializer
>
void
start(
- message_view_base const& m,
+ message_base const& m,
ConstBufferSequence&& buffers);
/** Prepare the serializer for a new message with a Source body.
@@ -321,7 +321,7 @@ class serializer
@see
@ref source,
@ref file_source,
- @ref message_view_base.
+ @ref message_base.
*/
template<
class Source,
@@ -330,7 +330,7 @@ class serializer
is_source::value>::type>
Source&
start(
- message_view_base const& m,
+ message_base const& m,
Args&&... args);
/** Prepare the serializer for a new message using a stream interface.
@@ -402,12 +402,12 @@ class serializer
@see
@ref stream,
- @ref message_view_base.
+ @ref message_base.
*/
BOOST_HTTP_PROTO_DECL
stream
start_stream(
- message_view_base const& m);
+ message_base const& m);
/** Return the output area.
@@ -527,18 +527,18 @@ class serializer
BOOST_HTTP_PROTO_DECL
void
start_init(
- message_view_base const&);
+ message_base const&);
BOOST_HTTP_PROTO_DECL
void
start_buffers(
- message_view_base const&,
+ message_base const&,
cbs_gen&);
BOOST_HTTP_PROTO_DECL
void
start_source(
- message_view_base const&,
+ message_base const&,
source&);
impl* impl_;
diff --git a/include/boost/http_proto/static_fields.hpp b/include/boost/http_proto/static_fields.hpp
deleted file mode 100644
index 24b71904..00000000
--- a/include/boost/http_proto/static_fields.hpp
+++ /dev/null
@@ -1,281 +0,0 @@
-//
-// Copyright (c) 2025 Mohammad Nejati
-//
-// 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)
-//
-// Official repository: https://github.com/cppalliance/http_proto
-//
-
-#ifndef BOOST_HTTP_PROTO_STATIC_FIELDS_HPP
-#define BOOST_HTTP_PROTO_STATIC_FIELDS_HPP
-
-#include
-#include
-#include
-#include
-
-namespace boost {
-namespace http_proto {
-
-/** A modifiable static container of HTTP fields.
-
- This container owns a collection of HTTP fields,
- represented by an inline buffer with fixed capacity.
- The contents may be inspected and modified,
- and the implementation maintains a useful
- invariant: changes to the fields always
- leave it in a valid state.
-
- @par Example
- @code
- static_fields<1024> fs;
-
- fs.set(field::host, "example.com");
- fs.set(field::accept_encoding, "gzip, deflate, br");
- fs.set(field::cache_control, "no-cache");
-
- assert(fs.buffer() ==
- "Host: example.com\r\n"
- "Accept-Encoding: gzip, deflate, br\r\n"
- "Cache-Control: no-cache\r\n"
- "\r\n");
- @endcode
-
- @par Invariants
- @code
- this->capacity_in_bytes() == Capacity && this->max_capacity_in_bytes() == Capacity
- @endcode
-
- @tparam Capacity The maximum capacity in bytes.
-
- @see
- @ref fields,
- @ref fields_view.
-*/
-template
-class static_fields final
- : public fields_base
-{
- alignas(entry)
- char buf_[Capacity];
-
-public:
-
- //--------------------------------------------
- //
- // Special Members
- //
- //--------------------------------------------
-
- /** Constructor.
-
- A default-constructed fields container
- contains no name-value pairs.
-
- @par Example
- @code
- static_fields<1024> fs;
- @endcode
-
- @par Postconditions
- @code
- this->buffer() == "\r\n"
- @endcode
-
- @par Complexity
- Constant.
- */
- static_fields() noexcept
- : fields_view_base(
- &this->fields_base::h_)
- , fields_base(
- detail::kind::fields,
- buf_,
- Capacity)
- {
- }
-
-
- /** Constructor.
-
- Constructs a fields container from the
- string `s`, which must contain valid
- HTTP fields or else an exception is thrown.
- The new fields container retains ownership
- by making a copy of the passed string.
-
- @par Example
- @code
- static_fields<1024> fs(
- "Server: Boost.HttpProto\r\n"
- "Content-Type: text/plain\r\n"
- "\r\n");
- @endcode
-
- @par Postconditions
- @code
- this->buffer.data() != s.data()
- @endcode
-
- @par Complexity
- Linear in `s.size()`.
-
- @par Exception Safety
- Exception thrown on invalid input.
- Exception thrown if max capacity exceeded.
-
- @throw system_error
- The input does not contain a valid HTTP fields.
-
- @throw std::length_error
- Max capacity would be exceeded.
-
- @param s The string to parse.
- */
- explicit static_fields(
- core::string_view s)
- : fields_view_base(
- &this->fields_base::h_)
- , fields_base(
- detail::kind::fields,
- buf_,
- Capacity,
- s)
- {
- }
-
- /** Constructor.
-
- The newly constructed object contains
- a copy of `f`.
-
- @par Postconditions
- @code
- this->buffer() == f.buffer() && this->buffer.data() != f.buffer().data()
- @endcode
-
- @par Complexity
- Linear in `f.size()`.
-
- @param f The fields container to copy.
- */
- static_fields(
- static_fields const& f) noexcept
- : fields_view_base(
- &this->fields_base::h_)
- , fields_base(
- *f.ph_,
- buf_,
- Capacity)
- {
- }
-
- /** Constructor.
-
- The newly constructed object contains
- a copy of `f`.
-
- @par Postconditions
- @code
- this->buffer() == f.buffer() && this->buffer.data() != f.buffer().data()
- @endcode
-
- @par Complexity
- Linear in `f.size()`.
-
- @par Exception Safety
- Exception thrown if max capacity exceeded.
-
- @throw std::length_error
- Max capacity would be exceeded.
-
- @param f The fields container to copy.
- */
- /** Constructor
- */
- static_fields(
- fields_view const& f)
- : fields_view_base(
- &this->fields_base::h_)
- , fields_base(
- *f.ph_,
- buf_,
- Capacity)
- {
- }
-
- /** Assignment.
-
- The contents of `f` are copied and
- the previous contents of `this` are
- discarded.
-
- @par Postconditions
- @code
- this->buffer() == f.buffer() && this->buffer().data() != f.buffer().data()
- @endcode
-
- @par Complexity
- Linear in `f.size()`.
-
- @param f The fields container to copy.
-
- @return A reference to this object.
- */
- static_fields&
- operator=(static_fields const& f) noexcept
- {
- copy_impl(*f.ph_);
- return *this;
- }
-
- /** Assignment.
-
- The contents of `f` are copied and
- the previous contents of `this` are
- discarded.
-
- @par Postconditions
- @code
- this->buffer() == f.buffer() && this->buffer().data() != f.buffer().data()
- @endcode
-
- @par Complexity
- Linear in `f.size()`.
-
- @par Exception Safety
- Strong guarantee.
- Exception thrown if max capacity exceeded.
-
- @throw std::length_error
- Max capacity would be exceeded.
-
- @param f The fields container to copy.
-
- @return A reference to this object.
- */
- static_fields&
- operator=(fields_view const& f)
- {
- copy_impl(*f.ph_);
- return *this;
- }
-
- /** Conversion.
-
- @see
- @ref fields_view.
-
- @return A view of the fields.
- */
- operator fields_view() const noexcept
- {
- return fields_view(ph_);
- }
-};
-
-} // http_proto
-} // boost
-
-#endif
diff --git a/include/boost/http_proto/static_request.hpp b/include/boost/http_proto/static_request.hpp
index 366f148f..b13ff1a4 100644
--- a/include/boost/http_proto/static_request.hpp
+++ b/include/boost/http_proto/static_request.hpp
@@ -17,8 +17,8 @@ namespace http_proto {
/** A modifiable static container for HTTP requests.
- This container owns a request, represented
- by an inline buffer with fixed capacity.
+ This container uses an external memory
+ storage with fixed capacity.
The contents may be inspected and modified,
and the implementation maintains a useful
invariant: changes to the request always
@@ -26,40 +26,38 @@ namespace http_proto {
@par Example
@code
- static_request<1024> req(method::get, "/");
+ char buf[1024];
+ static_request req(buf, sizeof(buf));
+ req.set_start_line(method::get, "/");
req.set(field::host, "example.com");
req.set(field::accept_encoding, "gzip, deflate, br");
req.set(field::cache_control, "no-cache");
assert(req.buffer() ==
- "GET / HTTP/1.1\r\n"
- "Host: example.com\r\n"
- "Accept-Encoding: gzip, deflate, br\r\n"
- "Cache-Control: no-cache\r\n"
- "\r\n");
+ "GET / HTTP/1.1\r\n"
+ "Host: example.com\r\n"
+ "Accept-Encoding: gzip, deflate, br\r\n"
+ "Cache-Control: no-cache\r\n"
+ "\r\n");
@endcode
@par Invariants
@code
- this->capacity_in_bytes() == Capacity && this->max_capacity_in_bytes() == Capacity
+ this->capacity_in_bytes() == Capacity && this->max_capacity_in_bytes() ==
+ Capacity
@endcode
@tparam Capacity The maximum capacity in bytes.
@see
@ref request,
- @ref request_view.
+ @ref request_base.
*/
-template
class static_request
: public request_base
{
- alignas(entry)
- char buf_[Capacity];
-
public:
-
//--------------------------------------------
//
// Special Members
@@ -68,214 +66,91 @@ class static_request
/** Constructor.
- A default-constructed request contains
- a valid HTTP `GET` request with no headers.
-
- @par Example
- @code
- static_request<1024> req;
- @endcode
-
- @par Postconditions
- @code
- this->buffer() == "GET / HTTP/1.1\r\n\r\n"
- @endcode
-
- @par Complexity
- Constant.
- */
- static_request() noexcept
- : fields_view_base(&this->fields_base::h_)
- , request_base(buf_, Capacity)
- {
- }
-
- /** Constructor.
-
- Constructs a request from the string `s`,
- which must contain valid HTTP request
- or else an exception is thrown.
- The new request retains ownership by
- making a copy of the passed string.
+ Constructs a request object that uses an
+ external memory storage and does not perform
+ any allocations during its lifetime.
- @par Example
- @code
- static_request<1024> req(
- "GET / HTTP/1.1\r\n"
- "Accept-Encoding: gzip, deflate, br\r\n"
- "Cache-Control: no-cache\r\n"
- "\r\n");
- @endcode
+ The caller is responsible for ensuring that the
+ lifetime of the storage extends until the
+ request object is destroyed.
- @par Postconditions
+ @par Postcondition
@code
- this->buffer.data() != s.data()
+ this->capacity_in_bytes() == cap
+ this->max_capacity_in_bytes() == cap
@endcode
- @par Complexity
- Linear in `s.size()`.
-
- @par Exception Safety
- Exception thrown on invalid input.
- Exception thrown if max capacity exceeded.
-
- @throw system_error
- The input does not contain a valid request.
-
- @throw std::length_error
- Max capacity would be exceeded.
-
- @param s The string to parse.
- */
- explicit
- static_request(
- core::string_view s)
- : fields_view_base(&this->fields_base::h_)
- , request_base(s, buf_, Capacity)
- {
- }
-
- /** Constructor.
-
- The start-line of the request will
- contain the standard text for the
- supplied method, target and HTTP version.
-
- @par Example
- @code
- static_request<1024> req(method::get, "/index.html", version::http_1_0);
- @endcode
-
- @par Complexity
- Linear in `to_string(m).size() + t.size()`.
-
- @par Exception Safety
- Exception thrown if max capacity exceeded.
-
- @throw std::length_error
- Max capacity would be exceeded.
-
- @param m The method to set.
-
- @param t The string representing a target.
-
- @param v The version to set.
+ @param storage The storage to use.
+ @param cap The capacity of the storage.
*/
static_request(
- http_proto::method m,
- core::string_view t,
- http_proto::version v) noexcept
- : static_request()
+ void* storage,
+ std::size_t cap)
+ : request_base(storage, cap)
{
- set_start_line(m, t, v);
}
- /** Constructor.
-
- The start-line of the request will
- contain the standard text for the
- supplied method and target with the HTTP
- version defaulted to `HTTP/1.1`.
-
- @par Example
- @code
- static_request<1024> req(method::get, "/index.html");
- @endcode
-
- @par Complexity
- Linear in `obsolete_reason(s).size()`.
-
- @par Exception Safety
- Exception thrown if max capacity exceeded.
-
- @throw std::length_error
- Max capacity would be exceeded.
-
- @param m The method to set.
-
- @param t The string representing a target.
+ /** Constructor (deleted)
*/
static_request(
- http_proto::method m,
- core::string_view t)
- : static_request(
- m, t, http_proto::version::http_1_1)
- {
- }
+ static_request const&) = delete;
/** Constructor.
- The newly constructed object contains
- a copy of `r`.
-
- @par Postconditions
- @code
- this->buffer() == r.buffer() && this->buffer.data() != r.buffer().data()
- @endcode
+ The contents of `r` are transferred
+ to the newly constructed object,
+ which includes the underlying
+ character buffer.
+ After construction, the moved-from
+ object has a valid but unspecified
+ state where the only safe operation
+ is destruction.
@par Complexity
- Linear in `r.size()`.
+ Constant.
- @param r The request to copy.
+ @param r The request to move from.
*/
static_request(
- static_request const& r) noexcept
- : fields_view_base(&this->fields_base::h_)
- , request_base(*r.ph_, buf_, Capacity)
+ static_request&& r) noexcept
+ : request_base()
{
+ h_.swap(r.h_);
+ external_storage_ = true;
+ max_cap_ = r.max_cap_;
+ r.max_cap_ = 0;
}
- /** Constructor.
+ /** Assignment.
- The newly constructed object contains
- a copy of `r`.
+ The contents of `r` are copied and
+ the previous contents of `this` are
+ discarded.
@par Postconditions
@code
- this->buffer() == r.buffer() && this->buffer.data() != r.buffer().data()
+ this->buffer() == r.buffer() && this->buffer().data() != r.buffer().data()
@endcode
@par Complexity
Linear in `r.size()`.
@par Exception Safety
+ Strong guarantee.
Exception thrown if max capacity exceeded.
@throw std::length_error
Max capacity would be exceeded.
@param r The request to copy.
- */
- static_request(
- request_view const& r)
- : fields_view_base(&this->fields_base::h_)
- , request_base(*r.ph_, buf_, Capacity)
- {
- }
-
- /** Assignment.
-
- The contents of `r` are copied and
- the previous contents of `this` are
- discarded.
-
- @par Postconditions
- @code
- this->buffer() == r.buffer() && this->buffer().data() != r.buffer().data()
- @endcode
-
- @par Complexity
- Linear in `r.size()`.
-
- @param r The request to copy.
@return A reference to this object.
*/
static_request&
operator=(
- static_request const& r) noexcept
+ static_request const& r)
{
- copy_impl(*r.ph_);
+ copy_impl(r.h_);
return *this;
}
@@ -306,9 +181,9 @@ class static_request
*/
static_request&
operator=(
- request_view const& r)
+ request_base const& r)
{
- copy_impl(*r.ph_);
+ copy_impl(r.h_);
return *this;
}
};
diff --git a/include/boost/http_proto/static_response.hpp b/include/boost/http_proto/static_response.hpp
index 4efee020..3a9e2702 100644
--- a/include/boost/http_proto/static_response.hpp
+++ b/include/boost/http_proto/static_response.hpp
@@ -17,8 +17,8 @@ namespace http_proto {
/** A modifiable static container for HTTP responses.
- This container owns a response, represented
- by an inline buffer with fixed capacity.
+ This container uses an external memory
+ storage with fixed capacity.
The contents may be inspected and modified,
and the implementation maintains a useful
invariant: changes to the response always
@@ -26,8 +26,10 @@ namespace http_proto {
@par Example
@code
- static_response<1024> res(status::not_found);
+ char buf[1024];
+ static_response res(buf, sizeof(buf));
+ res.set_start_line(status::not_found);
res.set(field::server, "Boost.HttpProto");
res.set(field::content_type, "text/plain");
res.set_content_length(80);
@@ -49,17 +51,12 @@ namespace http_proto {
@see
@ref response,
- @ref response_view.
+ @ref response_base.
*/
-template
class static_response
: public response_base
{
- alignas(entry)
- char buf_[Capacity];
-
public:
-
//--------------------------------------------
//
// Special Members
@@ -68,209 +65,91 @@ class static_response
/** Constructor.
- A default-constructed response contains
- a valid HTTP 200 OK response with no headers.
-
- @par Example
- @code
- static_response<1024> res;
- @endcode
-
- @par Postconditions
- @code
- this->buffer() == "HTTP/1.1 200 OK\r\n\r\n"
- @endcode
-
- @par Complexity
- Constant.
- */
- static_response() noexcept
- : fields_view_base(&this->fields_base::h_)
- , response_base(buf_, Capacity)
- {
- }
-
- /** Constructor.
-
- Constructs a response from the string `s`,
- which must contain valid HTTP response
- or else an exception is thrown.
- The new response retains ownership by
- making a copy of the passed string.
-
- @par Example
- @code
- static_response<1024> res(
- "HTTP/1.1 404 Not Found\r\n"
- "Server: Boost.HttpProto\r\n"
- "Content-Type: text/plain\r\n"
- "\r\n");
- @endcode
-
- @par Postconditions
- @code
- this->buffer.data() != s.data()
- @endcode
-
- @par Complexity
- Linear in `s.size()`.
+ Constructs a response object that uses an
+ external memory storage and does not perform
+ any allocations during its lifetime.
- @par Exception Safety
- Exception thrown on invalid input.
- Exception thrown if max capacity exceeded.
-
- @throw system_error
- The input does not contain a valid response.
-
- @throw std::length_error
- Max capacity would be exceeded.
-
- @param s The string to parse.
- */
- explicit
- static_response(
- core::string_view s)
- : fields_view_base(&this->fields_base::h_)
- , response_base(s, buf_, Capacity)
- {
- }
+ The caller is responsible for ensuring that the
+ lifetime of the storage extends until the
+ response object is destroyed.
- /** Constructor.
-
- The start-line of the response will
- contain the standard text for the
- supplied status code and HTTP version.
-
- @par Example
+ @par Postcondition
@code
- static_response<1024> res(status::not_found, version::http_1_0);
+ this->capacity_in_bytes() == cap
+ this->max_capacity_in_bytes() == cap
@endcode
- @par Complexity
- Linear in `obsolete_reason(s).size()`.
-
- @par Exception Safety
- Exception thrown if max capacity exceeded.
-
- @throw std::length_error
- Max capacity would be exceeded.
-
- @param sc The status code.
-
- @param v The HTTP version.
+ @param storage The storage to use.
+ @param cap The capacity of the storage.
*/
static_response(
- http_proto::status sc,
- http_proto::version v)
- : static_response()
+ void* storage,
+ std::size_t cap)
+ : response_base(storage, cap)
{
- set_start_line(sc, v);
}
- /** Constructor.
-
- The start-line of the response will
- contain the standard text for the
- supplied status code with the HTTP version
- defaulted to `HTTP/1.1`.
-
- @par Example
- @code
- static_response<1024> res(status::not_found);
- @endcode
-
- @par Complexity
- Linear in `obsolete_reason(s).size()`.
-
- @par Exception Safety
- Exception thrown if max capacity exceeded.
-
- @throw std::length_error
- Max capacity would be exceeded.
-
- @param sc The status code.
+ /** Constructor (deleted)
*/
- explicit
static_response(
- http_proto::status sc)
- : static_response(
- sc, http_proto::version::http_1_1)
- {
- }
+ static_response const&) = delete;
/** Constructor.
- The newly constructed object contains
- a copy of `r`.
-
- @par Postconditions
- @code
- this->buffer() == r.buffer() && this->buffer.data() != r.buffer().data()
- @endcode
+ The contents of `r` are transferred
+ to the newly constructed object,
+ which includes the underlying
+ character buffer.
+ After construction, the moved-from
+ object has a valid but unspecified
+ state where the only safe operation
+ is destruction.
@par Complexity
- Linear in `r.size()`.
+ Constant.
- @param r The response to copy.
+ @param r The response to move from.
*/
static_response(
- static_response const& r) noexcept
- : fields_view_base(&this->fields_base::h_)
- , response_base(*r.ph_, buf_, Capacity)
+ static_response&& r) noexcept
+ : response_base()
{
+ h_.swap(r.h_);
+ external_storage_ = true;
+ max_cap_ = r.max_cap_;
+ r.max_cap_ = 0;
}
- /** Constructor.
+ /** Assignment.
- The newly constructed object contains
- a copy of `r`.
+ The contents of `r` are copied and
+ the previous contents of `this` are
+ discarded.
@par Postconditions
@code
- this->buffer() == r.buffer() && this->buffer.data() != r.buffer().data()
+ this->buffer() == r.buffer() && this->buffer().data() != r.buffer().data()
@endcode
@par Complexity
Linear in `r.size()`.
@par Exception Safety
+ Strong guarantee.
Exception thrown if max capacity exceeded.
@throw std::length_error
Max capacity would be exceeded.
@param r The response to copy.
- */
- static_response(
- response_view const& r)
- : fields_view_base(&this->fields_base::h_)
- , response_base(*r.ph_, buf_, Capacity)
- {
- }
-
- /** Assignment.
-
- The contents of `r` are copied and
- the previous contents of `this` are
- discarded.
-
- @par Postconditions
- @code
- this->buffer() == r.buffer() && this->buffer().data() != r.buffer().data()
- @endcode
-
- @par Complexity
- Linear in `r.size()`.
-
- @param r The response to copy.
@return A reference to this object.
*/
static_response&
operator=(
- static_response const& r) noexcept
+ static_response const& r)
{
- copy_impl(*r.ph_);
+ copy_impl(r.h_);
return *this;
}
@@ -301,9 +180,9 @@ class static_response
*/
static_response&
operator=(
- response_view const& r)
+ response_base const& r)
{
- copy_impl(*r.ph_);
+ copy_impl(r.h_);
return *this;
}
};
diff --git a/src/detail/header.cpp b/src/detail/header.cpp
index 7f14f30d..64cfeb79 100644
--- a/src/detail/header.cpp
+++ b/src/detail/header.cpp
@@ -13,7 +13,6 @@
#include
#include
-#include
#include
#include
#include
diff --git a/src/fields.cpp b/src/fields.cpp
deleted file mode 100644
index 5ba67e21..00000000
--- a/src/fields.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
-//
-// Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
-// Copyright (c) 2024 Christian Mazakas
-//
-// 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)
-//
-// Official repository: https://github.com/cppalliance/http_proto
-//
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-namespace boost {
-namespace http_proto {
-
-fields::
-fields() noexcept
- : fields_view_base(
- &this->fields_base::h_)
- , fields_base(
- detail::kind::fields)
-{
-}
-
-fields::
-fields(
- core::string_view s)
- : fields_view_base(
- &this->fields_base::h_)
- , fields_base(
- detail::kind::fields, s)
-{
-}
-
-fields::
-fields(
- std::size_t cap,
- std::size_t max_cap)
- : fields()
-{
- reserve_bytes(cap);
- set_max_capacity_in_bytes(max_cap);
-}
-
-fields::
-fields(
- fields&& other) noexcept
- : fields_view_base(
- &this->fields_base::h_)
- , fields_base(other.h_.kind)
-{
- swap(other);
-}
-
-fields::
-fields(
- fields const& other)
- : fields_view_base(
- &this->fields_base::h_)
- , fields_base(*other.ph_)
-{
-}
-
-fields::
-fields(
- fields_view const& other)
- : fields_view_base(
- &this->fields_base::h_)
- , fields_base(*other.ph_)
-{
-}
-
-fields&
-fields::
-operator=(
- fields&& other) noexcept
-{
- fields tmp(std::move(other));
- tmp.swap(*this);
- return *this;
-}
-
-} // http_proto
-} // boost
diff --git a/src/fields_base.cpp b/src/fields_base.cpp
index c98b9f62..a58e4a81 100644
--- a/src/fields_base.cpp
+++ b/src/fields_base.cpp
@@ -306,15 +306,14 @@ prefix_op_t::
fields_base::
fields_base(
detail::kind k) noexcept
- : fields_view_base(&h_)
- , h_(k)
+ : h_(k)
{
}
fields_base::
fields_base(
detail::kind k,
- char* storage,
+ void* storage,
std::size_t cap) noexcept
: fields_base(
*detail::header::get_default(k), storage, cap)
@@ -326,8 +325,7 @@ fields_base::
fields_base(
detail::kind k,
core::string_view s)
- : fields_view_base(&h_)
- , h_(detail::empty{k})
+ : h_(detail::empty{k})
{
auto n = detail::header::count_crlf(s);
if(h_.kind == detail::kind::fields)
@@ -353,59 +351,11 @@ fields_base(
detail::throw_system_error(ec);
}
-// copy s and parse it
-fields_base::
-fields_base(
- detail::kind k,
- char* storage,
- std::size_t cap,
- core::string_view s)
- : fields_view_base(&h_)
- , h_(detail::empty{k})
- , external_storage_(true)
-{
- h_.cbuf = storage;
- h_.buf = storage;
- h_.cap = align_down(
- storage,
- cap,
- alignof(detail::header::entry));
- max_cap_ = h_.cap;
-
- auto n = detail::header::count_crlf(s);
- if(h_.kind == detail::kind::fields)
- {
- if(n < 1)
- detail::throw_invalid_argument();
- n -= 1;
- }
- else
- {
- if(n < 2)
- detail::throw_invalid_argument();
- n -= 2;
- }
-
- if(detail::header::bytes_needed(
- s.size(), n)
- >= h_.cap)
- detail::throw_length_error();
-
- s.copy(h_.buf, s.size());
- system::error_code ec;
- // VFALCO This is using defaults?
- header_limits lim;
- h_.parse(s.size(), lim, ec);
- if(ec.failed())
- detail::throw_system_error(ec);
-}
-
// construct a complete copy of h
fields_base::
fields_base(
detail::header const& h)
- : fields_view_base(&h_)
- , h_(h.kind)
+ : h_(h.kind)
{
if(h.is_default())
return;
@@ -423,14 +373,13 @@ fields_base(
fields_base::
fields_base(
detail::header const& h,
- char* storage,
+ void* storage,
std::size_t cap)
- : fields_view_base(&h_)
- , h_(h.kind)
+ : h_(h.kind)
, external_storage_(true)
{
- h_.cbuf = storage;
- h_.buf = storage;
+ h_.cbuf = static_cast(storage);
+ h_.buf = static_cast(storage);
h_.cap = align_down(
storage,
cap,
@@ -450,6 +399,12 @@ fields_base(
//------------------------------------------------
+fields_base::
+fields_base(fields_base const& other)
+ : fields_base(other.h_)
+{
+}
+
fields_base::
~fields_base()
{
@@ -526,6 +481,385 @@ set_max_capacity_in_bytes(std::size_t n)
max_cap_ = n;
}
+//--------------------------------------------
+//
+// Observers
+//
+//--------------------------------------------
+
+
+fields_base::
+value_type::
+value_type(
+ reference const& other)
+ : id(other.id)
+ , name(other.name)
+ , value(other.value)
+{
+}
+
+//------------------------------------------------
+
+auto
+fields_base::
+iterator::
+operator*() const noexcept ->
+ reference
+{
+ BOOST_ASSERT(i_ < ph_->count);
+ auto tab =
+ ph_->tab();
+ auto const& e =
+ tab[i_];
+ auto const* p =
+ ph_->cbuf + ph_->prefix;
+ return {
+ (e.id == detail::header::unknown_field)
+ ? optional{} : e.id,
+ core::string_view(
+ p + e.np, e.nn),
+ core::string_view(
+ p + e.vp, e.vn) };
+}
+
+//------------------------------------------------
+
+auto
+fields_base::
+reverse_iterator::
+operator*() const noexcept ->
+ reference
+{
+ BOOST_ASSERT(i_ > 0);
+ auto tab =
+ ph_->tab();
+ auto const& e =
+ tab[i_-1];
+ auto const* p =
+ ph_->cbuf + ph_->prefix;
+ return {
+ (e.id == detail::header::unknown_field)
+ ? optional{} : e.id,
+ core::string_view(
+ p + e.np, e.nn),
+ core::string_view(
+ p + e.vp, e.vn) };
+}
+
+//------------------------------------------------
+
+fields_base::
+subrange::
+iterator::
+iterator(
+ detail::header const* ph,
+ std::size_t i) noexcept
+ : ph_(ph)
+ , i_(i)
+{
+ BOOST_ASSERT(i <= ph_->count);
+}
+
+fields_base::
+subrange::
+iterator::
+iterator(
+ detail::header const* ph) noexcept
+ : ph_(ph)
+ , i_(ph->count)
+{
+}
+
+auto
+fields_base::
+subrange::
+iterator::
+operator*() const noexcept ->
+ reference const
+{
+ auto tab =
+ ph_->tab();
+ auto const& e =
+ tab[i_];
+ auto const p =
+ ph_->cbuf + ph_->prefix;
+ return core::string_view(
+ p + e.vp, e.vn);
+}
+
+auto
+fields_base::
+subrange::
+iterator::
+operator++() noexcept ->
+ iterator&
+{
+ BOOST_ASSERT(i_ < ph_->count);
+ auto const* e = &ph_->tab()[i_];
+ auto const id = e->id;
+ if(id != detail::header::unknown_field)
+ {
+ ++i_;
+ --e;
+ while(i_ != ph_->count)
+ {
+ if(e->id == id)
+ break;
+ ++i_;
+ --e;
+ }
+ return *this;
+ }
+ auto const p =
+ ph_->cbuf + ph_->prefix;
+ auto name = core::string_view(
+ p + e->np, e->nn);
+ ++i_;
+ --e;
+ while(i_ != ph_->count)
+ {
+ if(grammar::ci_is_equal(
+ name, core::string_view(
+ p + e->np, e->nn)))
+ break;
+ ++i_;
+ --e;
+ }
+ return *this;
+}
+
+//------------------------------------------------
+//
+// fields_base
+//
+//------------------------------------------------
+
+core::string_view
+fields_base::
+at(
+ field id) const
+{
+ auto const it = find(id);
+ if(it == end())
+ BOOST_THROW_EXCEPTION(
+ std::out_of_range{ "field not found" });
+ return it->value;
+}
+
+core::string_view
+fields_base::
+at(
+ core::string_view name) const
+{
+ auto const it = find(name);
+ if(it == end())
+ BOOST_THROW_EXCEPTION(
+ std::out_of_range{ "field not found" });
+ return it->value;
+}
+
+bool
+fields_base::
+exists(
+ field id) const noexcept
+{
+ return find(id) != end();
+}
+
+bool
+fields_base::
+exists(
+ core::string_view name) const noexcept
+{
+ return find(name) != end();
+}
+
+std::size_t
+fields_base::
+count(field id) const noexcept
+{
+ std::size_t n = 0;
+ for(auto v : *this)
+ if(v.id == id)
+ ++n;
+ return n;
+}
+
+std::size_t
+fields_base::
+count(
+ core::string_view name) const noexcept
+{
+ std::size_t n = 0;
+ for(auto v : *this)
+ if(grammar::ci_is_equal(
+ v.name, name))
+ ++n;
+ return n;
+}
+
+auto
+fields_base::
+find(field id) const noexcept ->
+ iterator
+{
+ auto it = begin();
+ auto const last = end();
+ while(it != last)
+ {
+ if(it->id == id)
+ break;
+ ++it;
+ }
+ return it;
+}
+
+auto
+fields_base::
+find(
+ core::string_view name) const noexcept ->
+ iterator
+{
+ auto it = begin();
+ auto const last = end();
+ while(it != last)
+ {
+ if(grammar::ci_is_equal(
+ it->name, name))
+ break;
+ ++it;
+ }
+ return it;
+}
+
+auto
+fields_base::
+find(
+ iterator from,
+ field id) const noexcept ->
+ iterator
+{
+ auto const last = end();
+ while(from != last)
+ {
+ if(from->id == id)
+ break;
+ ++from;
+ }
+ return from;
+}
+
+auto
+fields_base::
+find(
+ iterator from,
+ core::string_view name) const noexcept ->
+ iterator
+{
+ auto const last = end();
+ while(from != last)
+ {
+ if(grammar::ci_is_equal(
+ name, from->name))
+ break;
+ ++from;
+ }
+ return from;
+}
+
+auto
+fields_base::
+find_last(
+ iterator it,
+ field id) const noexcept ->
+ iterator
+{
+ auto const it0 = begin();
+ for(;;)
+ {
+ if(it == it0)
+ return end();
+ --it;
+ if(it->id == id)
+ return it;
+ }
+}
+
+auto
+fields_base::
+find_last(
+ iterator it,
+ core::string_view name) const noexcept ->
+ iterator
+{
+ auto const it0 = begin();
+ for(;;)
+ {
+ if(it == it0)
+ return end();
+ --it;
+ if(grammar::ci_is_equal(
+ it->name, name))
+ return it;
+ }
+}
+
+core::string_view
+fields_base::
+value_or(
+ field id,
+ core::string_view s) const noexcept
+{
+ auto it = find(id);
+ if(it != end())
+ return it->value;
+ return s;
+}
+
+core::string_view
+fields_base::
+value_or(
+ core::string_view name,
+ core::string_view s) const noexcept
+{
+ auto it = find(name);
+ if(it != end())
+ return it->value;
+ return s;
+}
+
+//------------------------------------------------
+
+auto
+fields_base::
+find_all(
+ field id) const noexcept ->
+ subrange
+{
+ return subrange(
+ &h_, find(id).i_);
+}
+
+auto
+fields_base::
+find_all(
+ core::string_view name) const noexcept ->
+ subrange
+{
+ return subrange(
+ &h_, find(name).i_);
+}
+
+//------------------------------------------------
+
+std::ostream&
+operator<<(
+ std::ostream& os,
+ const fields_base& f)
+{
+ return os << f.buffer();
+}
+
//------------------------------------------------
//
// Modifiers
@@ -787,6 +1121,83 @@ set(
rv->has_obs_fold);
}
+auto
+fields_base::
+insert(
+ iterator before,
+ field id,
+ core::string_view value)
+ -> iterator
+{
+ system::error_code ec;
+ auto const it = insert(before, id, value, ec);
+ if(ec.failed())
+ detail::throw_system_error(ec);
+ return it;
+}
+
+auto
+fields_base::
+insert(
+ iterator before,
+ field id,
+ core::string_view value,
+ system::error_code& ec)
+ -> iterator
+{
+ insert_impl(
+ id,
+ to_string(id),
+ value,
+ before.i_, ec);
+ return before;
+}
+
+auto
+fields_base::
+insert(
+ iterator before,
+ core::string_view name,
+ core::string_view value)
+ -> iterator
+{
+ system::error_code ec;
+ insert(before, name, value, ec);
+ if(ec.failed())
+ detail::throw_system_error(ec);
+ return before;
+}
+
+auto
+fields_base::
+insert(
+ iterator before,
+ core::string_view name,
+ core::string_view value,
+ system::error_code& ec)
+ -> iterator
+{
+ insert_impl(
+ string_to_field(name),
+ name,
+ value,
+ before.i_,
+ ec);
+ return before;
+}
+
+void
+fields_base::
+set(
+ iterator it,
+ core::string_view value)
+{
+ system::error_code ec;
+ set(it, value, ec);
+ if(ec.failed())
+ detail::throw_system_error(ec);
+}
+
//------------------------------------------------
//
// (implementation)
@@ -800,7 +1211,7 @@ copy_impl(
detail::header const& h)
{
BOOST_ASSERT(
- h.kind == ph_->kind);
+ h.kind == h_.kind);
auto const n =
detail::header::bytes_needed(
diff --git a/src/fields_view_base.cpp b/src/fields_view_base.cpp
deleted file mode 100644
index 49a6d964..00000000
--- a/src/fields_view_base.cpp
+++ /dev/null
@@ -1,395 +0,0 @@
-//
-// Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
-// Copyright (c) 2025 Mohammad Nejati
-//
-// 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)
-//
-// Official repository: https://github.com/cppalliance/http_proto
-//
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-namespace boost {
-namespace http_proto {
-
-fields_view_base::
-value_type::
-value_type(
- reference const& other)
- : id(other.id)
- , name(other.name)
- , value(other.value)
-{
-}
-
-//------------------------------------------------
-
-auto
-fields_view_base::
-iterator::
-operator*() const noexcept ->
- reference
-{
- BOOST_ASSERT(i_ < ph_->count);
- auto tab =
- ph_->tab();
- auto const& e =
- tab[i_];
- auto const* p =
- ph_->cbuf + ph_->prefix;
- return {
- (e.id == detail::header::unknown_field)
- ? optional{} : e.id,
- core::string_view(
- p + e.np, e.nn),
- core::string_view(
- p + e.vp, e.vn) };
-}
-
-//------------------------------------------------
-
-auto
-fields_view_base::
-reverse_iterator::
-operator*() const noexcept ->
- reference
-{
- BOOST_ASSERT(i_ > 0);
- auto tab =
- ph_->tab();
- auto const& e =
- tab[i_-1];
- auto const* p =
- ph_->cbuf + ph_->prefix;
- return {
- (e.id == detail::header::unknown_field)
- ? optional{} : e.id,
- core::string_view(
- p + e.np, e.nn),
- core::string_view(
- p + e.vp, e.vn) };
-}
-
-//------------------------------------------------
-
-fields_view_base::
-subrange::
-iterator::
-iterator(
- detail::header const* ph,
- std::size_t i) noexcept
- : ph_(ph)
- , i_(i)
-{
- BOOST_ASSERT(i <= ph_->count);
-}
-
-fields_view_base::
-subrange::
-iterator::
-iterator(
- detail::header const* ph) noexcept
- : ph_(ph)
- , i_(ph->count)
-{
-}
-
-auto
-fields_view_base::
-subrange::
-iterator::
-operator*() const noexcept ->
- reference const
-{
- auto tab =
- ph_->tab();
- auto const& e =
- tab[i_];
- auto const p =
- ph_->cbuf + ph_->prefix;
- return core::string_view(
- p + e.vp, e.vn);
-}
-
-auto
-fields_view_base::
-subrange::
-iterator::
-operator++() noexcept ->
- iterator&
-{
- BOOST_ASSERT(i_ < ph_->count);
- auto const* e = &ph_->tab()[i_];
- auto const id = e->id;
- if(id != detail::header::unknown_field)
- {
- ++i_;
- --e;
- while(i_ != ph_->count)
- {
- if(e->id == id)
- break;
- ++i_;
- --e;
- }
- return *this;
- }
- auto const p =
- ph_->cbuf + ph_->prefix;
- auto name = core::string_view(
- p + e->np, e->nn);
- ++i_;
- --e;
- while(i_ != ph_->count)
- {
- if(grammar::ci_is_equal(
- name, core::string_view(
- p + e->np, e->nn)))
- break;
- ++i_;
- --e;
- }
- return *this;
-}
-
-//------------------------------------------------
-//
-// fields_view_base
-//
-//------------------------------------------------
-
-core::string_view
-fields_view_base::
-at(
- field id) const
-{
- auto const it = find(id);
- if(it == end())
- BOOST_THROW_EXCEPTION(
- std::out_of_range{ "field not found" });
- return it->value;
-}
-
-core::string_view
-fields_view_base::
-at(
- core::string_view name) const
-{
- auto const it = find(name);
- if(it == end())
- BOOST_THROW_EXCEPTION(
- std::out_of_range{ "field not found" });
- return it->value;
-}
-
-bool
-fields_view_base::
-exists(
- field id) const noexcept
-{
- return find(id) != end();
-}
-
-bool
-fields_view_base::
-exists(
- core::string_view name) const noexcept
-{
- return find(name) != end();
-}
-
-std::size_t
-fields_view_base::
-count(field id) const noexcept
-{
- std::size_t n = 0;
- for(auto v : *this)
- if(v.id == id)
- ++n;
- return n;
-}
-
-std::size_t
-fields_view_base::
-count(
- core::string_view name) const noexcept
-{
- std::size_t n = 0;
- for(auto v : *this)
- if(grammar::ci_is_equal(
- v.name, name))
- ++n;
- return n;
-}
-
-auto
-fields_view_base::
-find(field id) const noexcept ->
- iterator
-{
- auto it = begin();
- auto const last = end();
- while(it != last)
- {
- if(it->id == id)
- break;
- ++it;
- }
- return it;
-}
-
-auto
-fields_view_base::
-find(
- core::string_view name) const noexcept ->
- iterator
-{
- auto it = begin();
- auto const last = end();
- while(it != last)
- {
- if(grammar::ci_is_equal(
- it->name, name))
- break;
- ++it;
- }
- return it;
-}
-
-auto
-fields_view_base::
-find(
- iterator from,
- field id) const noexcept ->
- iterator
-{
- auto const last = end();
- while(from != last)
- {
- if(from->id == id)
- break;
- ++from;
- }
- return from;
-}
-
-auto
-fields_view_base::
-find(
- iterator from,
- core::string_view name) const noexcept ->
- iterator
-{
- auto const last = end();
- while(from != last)
- {
- if(grammar::ci_is_equal(
- name, from->name))
- break;
- ++from;
- }
- return from;
-}
-
-auto
-fields_view_base::
-find_last(
- iterator it,
- field id) const noexcept ->
- iterator
-{
- auto const it0 = begin();
- for(;;)
- {
- if(it == it0)
- return end();
- --it;
- if(it->id == id)
- return it;
- }
-}
-
-auto
-fields_view_base::
-find_last(
- iterator it,
- core::string_view name) const noexcept ->
- iterator
-{
- auto const it0 = begin();
- for(;;)
- {
- if(it == it0)
- return end();
- --it;
- if(grammar::ci_is_equal(
- it->name, name))
- return it;
- }
-}
-
-core::string_view
-fields_view_base::
-value_or(
- field id,
- core::string_view s) const noexcept
-{
- auto it = find(id);
- if(it != end())
- return it->value;
- return s;
-}
-
-core::string_view
-fields_view_base::
-value_or(
- core::string_view name,
- core::string_view s) const noexcept
-{
- auto it = find(name);
- if(it != end())
- return it->value;
- return s;
-}
-
-//------------------------------------------------
-
-auto
-fields_view_base::
-find_all(
- field id) const noexcept ->
- subrange
-{
- return subrange(
- ph_, find(id).i_);
-}
-
-auto
-fields_view_base::
-find_all(
- core::string_view name) const noexcept ->
- subrange
-{
- return subrange(
- ph_, find(name).i_);
-}
-
-//------------------------------------------------
-
-std::ostream&
-operator<<(
- std::ostream& os,
- const fields_view_base& f)
-{
- return os << f.buffer();
-}
-
-} // http_proto
-} // boost
diff --git a/src/message_base.cpp b/src/message_base.cpp
index 5f173fe1..7f5ace2d 100644
--- a/src/message_base.cpp
+++ b/src/message_base.cpp
@@ -73,16 +73,16 @@ void
message_base::
set_keep_alive(bool value)
{
- if(ph_->md.connection.ec.failed())
+ if(h_.md.connection.ec.failed())
{
// throw? return false?
return;
}
- if(ph_->md.connection.count == 0)
+ if(h_.md.connection.count == 0)
{
// no Connection field
- switch(ph_->version)
+ switch(h_.version)
{
default:
case http_proto::version::http_1_1:
@@ -155,22 +155,22 @@ set_keep_alive(bool value)
};
if(value)
{
- if(ph_->md.connection.close)
+ if(h_.md.connection.close)
erase_token("close");
}
else
{
- if(ph_->md.connection.keep_alive)
+ if(h_.md.connection.keep_alive)
erase_token("keep-alive");
}
- switch(ph_->version)
+ switch(h_.version)
{
default:
case http_proto::version::http_1_1:
if(! value)
{
// add one "close" token if needed
- if(! ph_->md.connection.close)
+ if(! h_.md.connection.close)
append(field::connection, "close");
}
break;
@@ -179,7 +179,7 @@ set_keep_alive(bool value)
if(value)
{
// add one "keep-alive" token if needed
- if(! ph_->md.connection.keep_alive)
+ if(! h_.md.connection.keep_alive)
append(field::connection, "keep-alive");
}
break;
diff --git a/src/message_view_base.cpp b/src/message_view_base.cpp
deleted file mode 100644
index 03c78ac1..00000000
--- a/src/message_view_base.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//
-// Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.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)
-//
-// Official repository: https://github.com/cppalliance/http_proto
-//
-
-#include
-
-namespace boost {
-namespace http_proto {
-
-} // http_proto
-} // boost
diff --git a/src/parser.cpp b/src/parser.cpp
index f2a56616..34ab4f12 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -11,6 +11,8 @@
#include
#include
#include
+#include
+#include
#include
#include
@@ -538,7 +540,7 @@ class parser::impl
parser_service& svc_;
detail::workspace ws_;
- detail::header h_;
+ static_request m_;
std::uint64_t body_limit_;
std::uint64_t body_total_;
std::uint64_t payload_remain_;
@@ -571,10 +573,11 @@ class parser::impl
: ctx_(ctx)
, svc_(ctx.get_service())
, ws_(svc_.space_needed)
- , h_(detail::empty{ k })
+ , m_(ws_.data(), ws_.size())
, state_(state::reset)
, got_header_(false)
{
+ m_.h_ = detail::header(detail::empty{ k });
}
bool
@@ -589,14 +592,25 @@ class parser::impl
return state_ >= state::complete_in_place;
}
- detail::header const*
- safe_get_header() const
+ static_request const&
+ safe_get_request() const
{
// headers must be received
if(! got_header_)
detail::throw_logic_error();
- return &h_;
+ return m_;
+ }
+
+ static_response const&
+ safe_get_response() const
+ {
+ // headers must be received
+ if(! got_header_)
+ detail::throw_logic_error();
+
+ // TODO: use a union
+ return reinterpret_cast(m_);
}
bool
@@ -710,12 +724,12 @@ class parser::impl
BOOST_ASSERT(
head_response == false ||
- h_.kind == detail::kind::response);
+ m_.h_.kind == detail::kind::response);
- h_ = detail::header(detail::empty{h_.kind});
- h_.buf = reinterpret_cast(ws_.data());
- h_.cbuf = h_.buf;
- h_.cap = ws_.size();
+ m_.h_ = detail::header(detail::empty{m_.h_.kind});
+ m_.h_.buf = reinterpret_cast(ws_.data());
+ m_.h_.cbuf = m_.h_.buf;
+ m_.h_.cap = ws_.size();
state_ = state::header;
style_ = style::in_place;
@@ -760,7 +774,7 @@ class parser::impl
case state::header:
{
BOOST_ASSERT(
- h_.size < svc_.cfg.headers.max_size);
+ m_.h_.size < svc_.cfg.headers.max_size);
std::size_t n = fb_.capacity() - fb_.size();
BOOST_ASSERT(n <= svc_.max_overread());
n = clamp(n, svc_.cfg.max_prepare);
@@ -801,7 +815,7 @@ class parser::impl
std::size_t n = cb0_.capacity();
n = clamp(n, svc_.cfg.max_prepare);
- if(h_.md.payload == payload::size)
+ if(m_.payload() == payload::size)
{
if(n > payload_remain_)
{
@@ -815,7 +829,7 @@ class parser::impl
else
{
BOOST_ASSERT(
- h_.md.payload == payload::to_eof);
+ m_.payload() == payload::to_eof);
// No more messages can be pipelined, so
// limit the output buffer to the remaining
// body limit plus one byte to detect
@@ -837,7 +851,7 @@ class parser::impl
std::size_t n = svc_.cfg.min_buffer;
- if(h_.md.payload == payload::size)
+ if(m_.payload() == payload::size)
{
// Overreads are not allowed, or
// else the caller will see extra
@@ -847,7 +861,7 @@ class parser::impl
else
{
BOOST_ASSERT(
- h_.md.payload == payload::to_eof);
+ m_.payload() == payload::to_eof);
// No more messages can be pipelined, so
// limit the output buffer to the remaining
// body limit plus one byte to detect
@@ -1050,12 +1064,12 @@ class parser::impl
case state::header:
{
- BOOST_ASSERT(h_.buf == static_cast<
+ BOOST_ASSERT(m_.h_.buf == static_cast<
void const*>(ws_.data()));
- BOOST_ASSERT(h_.cbuf == static_cast<
+ BOOST_ASSERT(m_.h_.cbuf == static_cast<
void const*>(ws_.data()));
- h_.parse(fb_.size(), svc_.cfg.headers, ec);
+ m_.h_.parse(fb_.size(), svc_.cfg.headers, ec);
if(ec == condition::need_more_input)
{
@@ -1095,15 +1109,15 @@ class parser::impl
got_header_ = true;
// reserve headers + table
- ws_.reserve_front(h_.size);
- ws_.reserve_back(h_.table_space());
+ ws_.reserve_front(m_.h_.size);
+ ws_.reserve_back(m_.h_.table_space());
// no payload
- if(h_.md.payload == payload::none ||
+ if(m_.payload() == payload::none ||
head_response_)
{
// octets of the next message
- auto overread = fb_.size() - h_.size;
+ auto overread = fb_.size() - m_.h_.size;
cb0_ = { ws_.data(), overread, overread };
ws_.reserve_front(overread);
state_ = state::complete_in_place;
@@ -1117,7 +1131,7 @@ class parser::impl
case state::header_done:
{
// metadata error
- if(h_.md.payload == payload::error)
+ if(m_.payload() == payload::error)
{
// VFALCO This needs looking at
ec = BOOST_HTTP_PROTO_ERR(
@@ -1131,7 +1145,7 @@ class parser::impl
// this can include associated body octets for the
// current message or octets of the next message in the
// stream, e.g. pipelining is being used
- auto const overread = fb_.size() - h_.size;
+ auto const overread = fb_.size() - m_.h_.size;
BOOST_ASSERT(overread <= svc_.max_overread());
auto cap = fb_.capacity() + overread +
@@ -1141,7 +1155,7 @@ class parser::impl
// must be installed after them.
auto const p = ws_.reserve_front(cap);
- switch(h_.md.content_encoding.coding)
+ switch(m_.metadata().content_encoding.coding)
{
case content_coding::deflate:
if(!svc_.cfg.apply_deflate_decoder)
@@ -1188,17 +1202,17 @@ class parser::impl
cb1_ = { p + n0 , n1 };
}
- if(h_.md.payload == payload::size)
+ if(m_.payload() == payload::size)
{
if(!filter_ &&
- body_limit_ < h_.md.payload_size)
+ body_limit_ < m_.payload_size())
{
ec = BOOST_HTTP_PROTO_ERR(
error::body_too_large);
state_ = state::reset;
return;
}
- payload_remain_ = h_.md.payload_size;
+ payload_remain_ = m_.payload_size();
}
state_ = state::body;
@@ -1209,8 +1223,8 @@ class parser::impl
{
do_body:
BOOST_ASSERT(state_ == state::body);
- BOOST_ASSERT(h_.md.payload != payload::none);
- BOOST_ASSERT(h_.md.payload != payload::error);
+ BOOST_ASSERT(m_.payload() != payload::none);
+ BOOST_ASSERT(m_.payload() != payload::error);
auto set_state_to_complete = [&]()
{
@@ -1222,7 +1236,7 @@ class parser::impl
state_ = state::complete;
};
- if(h_.md.payload == payload::chunked)
+ if(m_.payload() == payload::chunked)
{
for(;;)
{
@@ -1404,7 +1418,7 @@ class parser::impl
auto ret = cb0_.size();
if(!filter_)
ret -= body_avail_;
- if(h_.md.payload == payload::size)
+ if(m_.payload() == payload::size)
return clamp(payload_remain_, ret);
// payload::eof
return ret;
@@ -1412,7 +1426,7 @@ class parser::impl
const bool is_complete = [&]()
{
- if(h_.md.payload == payload::size)
+ if(m_.payload() == payload::size)
return payload_avail == payload_remain_;
// payload::eof
return got_eof_;
@@ -1429,7 +1443,7 @@ class parser::impl
{
// plain body
- if(h_.md.payload == payload::to_eof)
+ if(m_.payload() == payload::to_eof)
{
if(body_limit_remain() < payload_avail)
{
@@ -1510,7 +1524,7 @@ class parser::impl
}
}
- if(h_.md.payload == payload::size && got_eof_)
+ if(m_.payload() == payload::size && got_eof_)
{
ec = BOOST_HTTP_PROTO_ERR(
error::incomplete);
@@ -1693,7 +1707,7 @@ class parser::impl
is_plain() const noexcept
{
return ! filter_ &&
- h_.md.payload != payload::chunked;
+ m_.payload() != payload::chunked;
}
std::uint64_t
@@ -1985,12 +1999,20 @@ start_impl(bool head_response)
impl_->start(head_response);
}
-detail::header const*
+static_request const&
+parser::
+safe_get_request() const
+{
+ BOOST_ASSERT(impl_);
+ return impl_->safe_get_request();
+}
+
+static_response const&
parser::
-safe_get_header() const
+safe_get_response() const
{
BOOST_ASSERT(impl_);
- return impl_->safe_get_header();
+ return impl_->safe_get_response();
}
detail::workspace&
diff --git a/src/request.cpp b/src/request.cpp
deleted file mode 100644
index 09e22987..00000000
--- a/src/request.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-//
-// Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
-// Copyright (c) 2024 Christian Mazakas
-// Copyright (c) 2025 Mohammad Nejati
-//
-// 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)
-//
-// Official repository: https://github.com/cppalliance/http_proto
-//
-
-#include
-
-namespace boost {
-namespace http_proto {
-
-request::
-request() noexcept
- : fields_view_base(
- &this->fields_base::h_)
- , request_base()
-{
-}
-
-request::
-request(
- core::string_view s)
- : fields_view_base(
- &this->fields_base::h_)
- , request_base(s)
-{
-}
-
-request::
-request(
- std::size_t cap,
- std::size_t max_cap)
- : request()
-{
- reserve_bytes(cap);
- set_max_capacity_in_bytes(max_cap);
-}
-
-request::
-request(
- request&& other) noexcept
- : fields_view_base(
- &this->fields_base::h_)
- , request_base()
-{
- swap(other);
-}
-
-request::
-request(
- request const& other)
- : fields_view_base(
- &this->fields_base::h_)
- , request_base(*other.ph_)
-{
-}
-
-request::
-request(
- request_view const& other)
- : fields_view_base(
- &this->fields_base::h_)
- , request_base(*other.ph_)
-{
-}
-
-request&
-request::
-operator=(
- request&& other) noexcept
-{
- request temp(
- std::move(other));
- temp.swap(*this);
- return *this;
-}
-
-} // http_proto
-} // boost
diff --git a/src/request_parser.cpp b/src/request_parser.cpp
index 65e9a194..2834b4ae 100644
--- a/src/request_parser.cpp
+++ b/src/request_parser.cpp
@@ -21,12 +21,11 @@ request_parser(
{
}
-request_view
+static_request const&
request_parser::
get() const
{
- return request_view(
- safe_get_header());
+ return safe_get_request();
}
} // http_proto
diff --git a/src/response.cpp b/src/response.cpp
deleted file mode 100644
index a3449641..00000000
--- a/src/response.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-//
-// Copyright (c) 2021 Vinnie Falco (vinnie.falco@gmail.com)
-// Copyright (c) 2024 Christian Mazakas
-// Copyright (c) 2025 Mohammad Nejati
-//
-// 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)
-//
-// Official repository: https://github.com/cppalliance/http_proto
-//
-
-#include
-#include
-
-#include
-
-namespace boost {
-namespace http_proto {
-
-response::
-response() noexcept
- : fields_view_base(
- &this->fields_base::h_)
- , response_base()
-{
-}
-
-response::
-response(
- core::string_view s)
- : fields_view_base(
- &this->fields_base::h_)
- , response_base(s)
-{
-}
-
-response::
-response(
- std::size_t cap,
- std::size_t max_cap)
- : response()
-{
- reserve_bytes(cap);
- set_max_capacity_in_bytes(max_cap);
-}
-
-response::
-response(
- response&& other) noexcept
- : response()
-{
- swap(other);
-}
-
-response::
-response(
- response const& other)
- : fields_view_base(
- &this->fields_base::h_)
- , response_base(*other.ph_)
-{
-}
-
-response::
-response(
- response_view const& other)
- : fields_view_base(
- &this->fields_base::h_)
- , response_base(*other.ph_)
-{
-}
-
-response&
-response::
-operator=(
- response&& other) noexcept
-{
- response temp(
- std::move(other));
- temp.swap(*this);
- return *this;
-}
-
-response::
-response(
- http_proto::status sc)
- : response(
- sc, http_proto::version::http_1_1)
-{
-}
-
-response::
-response(
- http_proto::status sc,
- http_proto::version v)
- : response()
-{
- set_start_line(sc, v);
-}
-
-} // http_proto
-} // boost
diff --git a/src/response_parser.cpp b/src/response_parser.cpp
index 85cc126f..c1baeefe 100644
--- a/src/response_parser.cpp
+++ b/src/response_parser.cpp
@@ -21,12 +21,11 @@ response_parser(
{
}
-response_view
+static_response const&
response_parser::
get() const
{
- return response_view(
- safe_get_header());
+ return safe_get_response();
}
} // http_proto
diff --git a/src/rfc/combine_field_values.cpp b/src/rfc/combine_field_values.cpp
index cf98e651..53c9d514 100644
--- a/src/rfc/combine_field_values.cpp
+++ b/src/rfc/combine_field_values.cpp
@@ -14,7 +14,7 @@ namespace http_proto {
core::string_view
combine_field_values(
- fields_view_base::subrange const& vr,
+ fields_base::subrange const& vr,
grammar::recycled_ptr& temp)
{
core::string_view result;
diff --git a/src/serializer.cpp b/src/serializer.cpp
index 0a45f146..179cddce 100644
--- a/src/serializer.cpp
+++ b/src/serializer.cpp
@@ -11,7 +11,7 @@
#include
#include
-#include
+#include
#include
#include "src/detail/array_of_const_buffers.hpp"
@@ -633,7 +633,7 @@ class serializer::impl
void
start_init(
- message_view_base const& m)
+ message_base const& m)
{
// Precondition violation
if(state_ != state::start)
@@ -646,7 +646,7 @@ class serializer::impl
// VFALCO what do we do with
// metadata error code failures?
- // m.ph_->md.maybe_throw();
+ // m.h_.md.maybe_throw();
auto const& md = m.metadata();
needs_exp100_continue_ = md.expect.is_100_continue;
@@ -701,7 +701,7 @@ class serializer::impl
void
start_empty(
- message_view_base const& m)
+ message_base const& m)
{
start_init(m);
style_ = style::empty;
@@ -715,13 +715,13 @@ class serializer::impl
if(!filter_)
out_finish();
- prepped_.append({ m.ph_->cbuf, m.ph_->size });
+ prepped_.append({ m.h_.cbuf, m.h_.size });
more_input_ = false;
}
void
start_buffers(
- message_view_base const& m,
+ message_base const& m,
cbs_gen& cbs_gen)
{
// start_init() already called
@@ -738,7 +738,7 @@ class serializer::impl
batch_size + // buffers
(is_chunked_ ? 2 : 0)); // chunk header + final chunk
- prepped_.append({ m.ph_->cbuf, m.ph_->size });
+ prepped_.append({ m.h_.cbuf, m.h_.size });
more_input_ = (batch_size != 0);
if(is_chunked_)
@@ -767,14 +767,14 @@ class serializer::impl
out_init();
- prepped_.append({ m.ph_->cbuf, m.ph_->size });
+ prepped_.append({ m.h_.cbuf, m.h_.size });
tmp_ = {};
more_input_ = true;
}
void
start_source(
- message_view_base const& m,
+ message_base const& m,
source& source)
{
// start_init() already called
@@ -794,12 +794,12 @@ class serializer::impl
out_init();
- prepped_.append({ m.ph_->cbuf, m.ph_->size });
+ prepped_.append({ m.h_.cbuf, m.h_.size });
more_input_ = true;
}
stream
- start_stream(message_view_base const& m)
+ start_stream(message_base const& m)
{
start_init(m);
style_ = style::stream;
@@ -817,7 +817,7 @@ class serializer::impl
out_init();
- prepped_.append({ m.ph_->cbuf, m.ph_->size });
+ prepped_.append({ m.h_.cbuf, m.h_.size });
more_input_ = true;
return stream{ this };
}
@@ -961,7 +961,7 @@ reset() noexcept
void
serializer::
-start(message_view_base const& m)
+start(message_base const& m)
{
BOOST_ASSERT(impl_);
impl_->start_empty(m);
@@ -970,7 +970,7 @@ start(message_view_base const& m)
auto
serializer::
start_stream(
- message_view_base const& m) -> stream
+ message_base const& m) -> stream
{
BOOST_ASSERT(impl_);
return impl_->start_stream(m);
@@ -1013,7 +1013,7 @@ ws()
void
serializer::
-start_init(message_view_base const& m)
+start_init(message_base const& m)
{
BOOST_ASSERT(impl_);
impl_->start_init(m);
@@ -1022,7 +1022,7 @@ start_init(message_view_base const& m)
void
serializer::
start_buffers(
- message_view_base const& m,
+ message_base const& m,
cbs_gen& cbs_gen)
{
BOOST_ASSERT(impl_);
@@ -1032,7 +1032,7 @@ start_buffers(
void
serializer::
start_source(
- message_view_base const& m,
+ message_base const& m,
source& source)
{
BOOST_ASSERT(impl_);
diff --git a/test/unit/Jamfile b/test/unit/Jamfile
index cedad320..0fc028f6 100644
--- a/test/unit/Jamfile
+++ b/test/unit/Jamfile
@@ -35,28 +35,22 @@ local SOURCES =
error.cpp
field.cpp
fields_base.cpp
- fields_view_base.cpp
- fields_view.cpp
fields.cpp
file_mode.cpp
header_limits.cpp
http_proto.cpp
message_base.cpp
- message_view_base.cpp
metadata.cpp
method.cpp
parser.cpp
request_parser.cpp
- request_view.cpp
request.cpp
response_parser.cpp
- response_view.cpp
response.cpp
sandbox.cpp
serializer.cpp
sink.cpp
source.cpp
- static_fields.cpp
static_request.cpp
static_response.cpp
status.cpp
diff --git a/test/unit/compression.cpp b/test/unit/compression.cpp
index ba208c98..5dd75647 100644
--- a/test/unit/compression.cpp
+++ b/test/unit/compression.cpp
@@ -238,7 +238,7 @@ struct zlib_test
static
void
serializer_source(
- response_view res,
+ response const& res,
serializer& sr,
buffers::const_buffer body,
buffers::string_buffer out)
@@ -284,7 +284,7 @@ struct zlib_test
static
void
serializer_stream(
- response_view res,
+ response const& res,
serializer& sr,
buffers::const_buffer body,
buffers::string_buffer out)
@@ -322,7 +322,7 @@ struct zlib_test
static
void
serializer_buffers(
- response_view res,
+ response const& res,
serializer& sr,
buffers::const_buffer body,
buffers::string_buffer out)
@@ -354,7 +354,7 @@ struct zlib_test
static
void
serializer_empty(
- response_view res,
+ response const& res,
serializer& sr,
buffers::const_buffer body,
buffers::string_buffer out)
diff --git a/test/unit/fields.cpp b/test/unit/fields.cpp
index de59faa2..f84df80c 100644
--- a/test/unit/fields.cpp
+++ b/test/unit/fields.cpp
@@ -12,7 +12,6 @@
#include
#include
-#include
#include
#include "test_helpers.hpp"
@@ -110,33 +109,6 @@ struct fields_test
}
}
- // fields(fields_view const&)
- {
- {
- fields f1(cs1);
- fields f2(static_cast<
- fields_view>(f1));
-
- BOOST_TEST_EQ(
- f2.buffer(), cs1);
- BOOST_TEST_NE(
- f2.buffer().data(),
- cs1.data());
- test_fields(f2, cs1);
- }
-
- // default buffer
- {
- fields_view fv;
- fields f(fv);
- BOOST_TEST_EQ(
- f.buffer(), "\r\n");
- BOOST_TEST_EQ(
- f.buffer().data(),
- fv.buffer().data());
- }
- }
-
// operator=(fields&&)
{
{
@@ -202,60 +174,6 @@ struct fields_test
f2.buffer().data());
}
}
-
- // operator=(fields_view)
- {
- {
- fields f1(cs1);
- fields f2;
- f2 = static_cast<
- fields_view>(f1);
- test_fields(f1, cs1);
- test_fields(f2, cs1);
- BOOST_TEST_NE(
- f1.buffer().data(),
- f2.buffer().data());
- }
- {
- fields f1(cs1);
- fields f2(
- "x: 1\r\n"
- "y: 2\r\n"
- "z: 3\r\n"
- "\r\n");
- f2 = static_cast<
- fields_view>(f1);
- test_fields(f1, cs1);
- test_fields(f2, cs1);
- BOOST_TEST_NE(
- f1.buffer().data(),
- f2.buffer().data());
- }
- {
- fields_view f1;
- fields f2(cs1);
- f2 = f1;
- test_fields(f1, "\r\n");
- test_fields(f2, "\r\n");
- BOOST_TEST_EQ(
- f1.buffer().data(),
- f2.buffer().data());
- }
-
- // existing capacity
- {
- fields f1(cs1);
- fields f2;
- f2.reserve_bytes(
- 2 * cs1.size() + 128);
- f2 = static_cast<
- fields_view>(f1);
- test_fields(f2, cs1);
- BOOST_TEST(
- f1.buffer().data() !=
- f2.buffer().data());
- }
- }
}
void
diff --git a/test/unit/fields_base.cpp b/test/unit/fields_base.cpp
index 0c9d2875..3bce305c 100644
--- a/test/unit/fields_base.cpp
+++ b/test/unit/fields_base.cpp
@@ -15,6 +15,8 @@
#include
#include
#include
+
+#include
#include
#include "test_helpers.hpp"
@@ -1462,6 +1464,259 @@ struct fields_base_test
}
}
+ void
+ testIterators()
+ {
+ fields_base const& f = fields(
+ "x: 1\r\n"
+ "Accept: 2\r\n"
+ "z: 3\r\n"
+ "\r\n");
+
+ // iterator
+ // begin()
+ // end()
+ {
+ BOOST_STATIC_ASSERT(std::is_same<
+ fields_base::iterator,
+ fields_base::const_iterator>::value);
+
+ BOOST_TEST(
+ fields_base::iterator() ==
+ fields_base::iterator());
+
+ fields_base::iterator it = f.begin();
+ BOOST_TEST(it == f.begin());
+ BOOST_TEST(it != f.end());
+
+ BOOST_TEST(!it->id.has_value());
+ BOOST_TEST_EQ(it->name, "x");
+ BOOST_TEST_EQ(it->value, "1");
+
+ ++it;
+ BOOST_TEST_EQ(it->id, field::accept);
+ BOOST_TEST_EQ(it->name, "Accept");
+ BOOST_TEST_EQ(it->value, "2");
+
+ {
+ auto it0 = it++; // post-increment
+ BOOST_TEST_EQ(it0->id, field::accept);
+ BOOST_TEST_EQ(it0->name, "Accept");
+ BOOST_TEST_EQ(it0->value, "2");
+ }
+ BOOST_TEST(!it->id.has_value());
+ BOOST_TEST_EQ(it->name, "z");
+ BOOST_TEST_EQ(it->value, "3");
+
+ ++it;
+ BOOST_TEST_EQ(it, f.end());
+
+ --it;
+ BOOST_TEST(!it->id.has_value());
+ BOOST_TEST_EQ(it->name, "z");
+ BOOST_TEST_EQ(it->value, "3");
+
+ {
+ auto it1 = it--; // post-decrement
+ BOOST_TEST(!it1->id.has_value());
+ BOOST_TEST_EQ(it1->name, "z");
+ BOOST_TEST_EQ(it1->value, "3");
+ }
+ BOOST_TEST_EQ(it->id, field::accept);
+ BOOST_TEST_EQ(it->name, "Accept");
+ BOOST_TEST_EQ(it->value, "2");
+
+ --it;
+ BOOST_TEST(!it->id.has_value());
+ BOOST_TEST_EQ(it->name, "x");
+ BOOST_TEST_EQ(it->value, "1");
+
+ BOOST_TEST_EQ(it, f.begin());
+ }
+
+ // reverse_iterator
+ // rbegin()
+ // rend()
+ {
+ BOOST_STATIC_ASSERT(std::is_same<
+ fields_base::reverse_iterator,
+ fields_base::const_reverse_iterator>::value);
+
+ BOOST_TEST(
+ fields_base::reverse_iterator() ==
+ fields_base::reverse_iterator());
+
+ fields_base::reverse_iterator it = f.rbegin();
+ BOOST_TEST(it == f.rbegin());
+ BOOST_TEST(it != f.rend());
+
+ BOOST_TEST(!it->id.has_value());
+ BOOST_TEST_EQ(it->name, "z");
+ BOOST_TEST_EQ(it->value, "3");
+
+ ++it;
+ BOOST_TEST_EQ(it->id, field::accept);
+ BOOST_TEST_EQ(it->name, "Accept");
+ BOOST_TEST_EQ(it->value, "2");
+
+ {
+ auto it0 = it++; // post-increment
+ BOOST_TEST_EQ(it0->id, field::accept);
+ BOOST_TEST_EQ(it0->name, "Accept");
+ BOOST_TEST_EQ(it0->value, "2");
+ }
+ BOOST_TEST(!it->id.has_value());
+ BOOST_TEST_EQ(it->name, "x");
+ BOOST_TEST_EQ(it->value, "1");
+
+ ++it;
+ BOOST_TEST_EQ(it, f.rend());
+
+ --it;
+ BOOST_TEST(!it->id.has_value());
+ BOOST_TEST_EQ(it->name, "x");
+ BOOST_TEST_EQ(it->value, "1");
+
+ {
+ auto it0 = it--; // post-decrement
+ BOOST_TEST(!it0->id.has_value());
+ BOOST_TEST_EQ(it0->name, "x");
+ BOOST_TEST_EQ(it0->value, "1");
+ }
+ BOOST_TEST_EQ(it->id, field::accept);
+ BOOST_TEST_EQ(it->name, "Accept");
+ BOOST_TEST_EQ(it->value, "2");
+
+ --it;
+ BOOST_TEST(!it->id.has_value());
+ BOOST_TEST_EQ(it->name, "z");
+ BOOST_TEST_EQ(it->value, "3");
+
+ BOOST_TEST_EQ(it, f.rbegin());
+ }
+ }
+
+ void
+ testObservers()
+ {
+ fields_base const& f =
+ fields(
+ "Content-Length: 42\r\n"
+ "x: 1\r\n"
+ "y: 2\r\n"
+ "Set-Cookie: a\r\n"
+ "x: 3\r\n"
+ "z: 4\r\n"
+ "Set-Cookie: b\r\n"
+ "x: 5\r\n"
+ "p: 6\r\n"
+ "User-Agent: boost\r\n"
+ "\r\n");
+
+ // size()
+
+ BOOST_TEST(f.size() == 10);
+
+ // at(field)
+ // at(string_view)
+
+ BOOST_TEST(f.at("x") == "1");
+ BOOST_TEST(f.at(field::set_cookie) == "a");
+ BOOST_TEST_THROWS(
+ f.at("accept"),
+ std::out_of_range);
+ BOOST_TEST_THROWS(
+ f.at(field::accept),
+ std::out_of_range);
+
+ // exists(field)
+ // exists(string_view)
+
+ BOOST_TEST(f.exists("x"));
+ BOOST_TEST(f.exists("X"));
+ BOOST_TEST(f.exists("user-agent"));
+ BOOST_TEST(! f.exists("a"));
+ BOOST_TEST(f.exists(field::user_agent));
+ BOOST_TEST(! f.exists(field::range));
+
+ // count(field)
+ // count(string_view)
+
+ BOOST_TEST(f.count("x") == 3);
+ BOOST_TEST(f.count("y") == 1);
+ BOOST_TEST(f.count("q") == 0);
+ BOOST_TEST(f.count(field::range) == 0);
+ BOOST_TEST(f.count(field::user_agent) == 1);
+
+ // find(field)
+ // find(string_view)
+ {
+ BOOST_TEST(f.find("x")->name == "x");
+ BOOST_TEST(f.find("accept") == f.end());
+ BOOST_TEST(f.find(field::range) == f.end());
+ BOOST_TEST(f.find(field::user_agent)->value == "boost");
+ }
+
+ // find(iterator, field)
+ // find(iterator, string_view)
+ {
+ auto const it = f.find("y");
+ BOOST_TEST(it != f.end());
+ BOOST_TEST(it->value == "2");
+
+ BOOST_TEST(f.find(it, "x")->value == "3");
+ BOOST_TEST(f.find(it, "q") == f.end());
+ BOOST_TEST(f.find(it, field::set_cookie)->value == "a");
+ BOOST_TEST(f.find(it, field::range) == f.end());
+ }
+
+ // find_last(iterator, field)
+ // find_last(iterator, string_view)
+ {
+ auto const it = f.find_last(f.end(), "x");
+ BOOST_TEST(it != f.end());
+ BOOST_TEST(it->value == "5");
+
+ BOOST_TEST(f.find_last(it, "x")->value == "3");
+ BOOST_TEST(f.find_last(it, "q") == f.end());
+ BOOST_TEST(f.find_last(it, field::set_cookie)->value == "b");
+ BOOST_TEST(f.find_last(it, field::range) == f.end());
+ }
+
+ // value_or(field, string_view)
+ // value_or(string_view, string_view)
+ {
+ BOOST_TEST(f.value_or(
+ field::set_cookie, "") == "a");
+ BOOST_TEST(f.value_or(
+ field::set_cookie2, "Q") == "Q");
+
+ BOOST_TEST(f.value_or(
+ "set-cookie", "") == "a");
+ BOOST_TEST(f.value_or(
+ "set-cookie2", "Q") == "Q");
+ }
+ }
+
+ void
+ testStream()
+ {
+ // operator<<
+ {
+ std::stringstream ss;
+ fields f;
+ f.set(field::content_length, "42");
+ ss << f;
+ BOOST_TEST_EQ(
+ ss.str(), "Content-Length: 42\r\n\r\n");
+ }
+ }
+
+ void
+ testSubrange()
+ {
+ }
+
void
run()
{
@@ -1471,6 +1726,10 @@ struct fields_base_test
testErase();
testSet();
testExpect();
+ testIterators();
+ testObservers();
+ testStream();
+ testSubrange();
}
};
diff --git a/test/unit/fields_view.cpp b/test/unit/fields_view.cpp
deleted file mode 100644
index 87945ffe..00000000
--- a/test/unit/fields_view.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-//
-// Copyright (c) 2021 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)
-//
-// Official repository: https://github.com/cppalliance/http_proto
-//
-
-// Test that header file is self-contained.
-#include
-
-#include
-
-#include "test_helpers.hpp"
-
-#include
-
-namespace boost {
-namespace http_proto {
-
-struct fields_view_test
-{
- void
- testSpecial()
- {
- // fields_view()
- {
- fields_view fv;
- }
-
- // fields_view(fields_view const&)
- {
- {
- fields_view f1;
- fields_view f2(f1);
- (void)f2;
- }
- }
-
- // operator=(fields_view const&)
- {
- {
- fields_view f1;
- fields_view f2;
- f1 = f2;
- }
- }
- }
-
- void
- run()
- {
- testSpecial();
- }
-};
-
-TEST_SUITE(
- fields_view_test,
- "boost.http_proto.fields_view");
-
-} // http_proto
-} // boost
diff --git a/test/unit/fields_view_base.cpp b/test/unit/fields_view_base.cpp
deleted file mode 100644
index 0e4b1584..00000000
--- a/test/unit/fields_view_base.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-//
-// Copyright (c) 2021 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)
-//
-// Official repository: https://github.com/cppalliance/http_proto
-//
-
-// Test that header file is self-contained.
-#include
-#include
-#include
-#include
-
-#include "test_helpers.hpp"
-
-namespace boost {
-namespace http_proto {
-
-struct fields_view_base_test
-{
- void
- testIterators()
- {
- fields_view_base const& f = fields(
- "x: 1\r\n"
- "Accept: 2\r\n"
- "z: 3\r\n"
- "\r\n");
-
- // iterator
- // begin()
- // end()
- {
- BOOST_STATIC_ASSERT(std::is_same<
- fields_view_base::iterator,
- fields_view_base::const_iterator>::value);
-
- BOOST_TEST(
- fields_view_base::iterator() ==
- fields_view_base::iterator());
-
- fields_view_base::iterator it = f.begin();
- BOOST_TEST(it == f.begin());
- BOOST_TEST(it != f.end());
-
- BOOST_TEST(!it->id.has_value());
- BOOST_TEST_EQ(it->name, "x");
- BOOST_TEST_EQ(it->value, "1");
-
- ++it;
- BOOST_TEST_EQ(it->id, field::accept);
- BOOST_TEST_EQ(it->name, "Accept");
- BOOST_TEST_EQ(it->value, "2");
-
- {
- auto it0 = it++; // post-increment
- BOOST_TEST_EQ(it0->id, field::accept);
- BOOST_TEST_EQ(it0->name, "Accept");
- BOOST_TEST_EQ(it0->value, "2");
- }
- BOOST_TEST(!it->id.has_value());
- BOOST_TEST_EQ(it->name, "z");
- BOOST_TEST_EQ(it->value, "3");
-
- ++it;
- BOOST_TEST_EQ(it, f.end());
-
- --it;
- BOOST_TEST(!it->id.has_value());
- BOOST_TEST_EQ(it->name, "z");
- BOOST_TEST_EQ(it->value, "3");
-
- {
- auto it1 = it--; // post-decrement
- BOOST_TEST(!it1->id.has_value());
- BOOST_TEST_EQ(it1->name, "z");
- BOOST_TEST_EQ(it1->value, "3");
- }
- BOOST_TEST_EQ(it->id, field::accept);
- BOOST_TEST_EQ(it->name, "Accept");
- BOOST_TEST_EQ(it->value, "2");
-
- --it;
- BOOST_TEST(!it->id.has_value());
- BOOST_TEST_EQ(it->name, "x");
- BOOST_TEST_EQ(it->value, "1");
-
- BOOST_TEST_EQ(it, f.begin());
- }
-
- // reverse_iterator
- // rbegin()
- // rend()
- {
- BOOST_STATIC_ASSERT(std::is_same<
- fields_view_base::reverse_iterator,
- fields_view_base::const_reverse_iterator>::value);
-
- BOOST_TEST(
- fields_view_base::reverse_iterator() ==
- fields_view_base::reverse_iterator());
-
- fields_view_base::reverse_iterator it = f.rbegin();
- BOOST_TEST(it == f.rbegin());
- BOOST_TEST(it != f.rend());
-
- BOOST_TEST(!it->id.has_value());
- BOOST_TEST_EQ(it->name, "z");
- BOOST_TEST_EQ(it->value, "3");
-
- ++it;
- BOOST_TEST_EQ(it->id, field::accept);
- BOOST_TEST_EQ(it->name, "Accept");
- BOOST_TEST_EQ(it->value, "2");
-
- {
- auto it0 = it++; // post-increment
- BOOST_TEST_EQ(it0->id, field::accept);
- BOOST_TEST_EQ(it0->name, "Accept");
- BOOST_TEST_EQ(it0->value, "2");
- }
- BOOST_TEST(!it->id.has_value());
- BOOST_TEST_EQ(it->name, "x");
- BOOST_TEST_EQ(it->value, "1");
-
- ++it;
- BOOST_TEST_EQ(it, f.rend());
-
- --it;
- BOOST_TEST(!it->id.has_value());
- BOOST_TEST_EQ(it->name, "x");
- BOOST_TEST_EQ(it->value, "1");
-
- {
- auto it0 = it--; // post-decrement
- BOOST_TEST(!it0->id.has_value());
- BOOST_TEST_EQ(it0->name, "x");
- BOOST_TEST_EQ(it0->value, "1");
- }
- BOOST_TEST_EQ(it->id, field::accept);
- BOOST_TEST_EQ(it->name, "Accept");
- BOOST_TEST_EQ(it->value, "2");
-
- --it;
- BOOST_TEST(!it->id.has_value());
- BOOST_TEST_EQ(it->name, "z");
- BOOST_TEST_EQ(it->value, "3");
-
- BOOST_TEST_EQ(it, f.rbegin());
- }
- }
-
- void
- testObservers()
- {
- fields_view_base const& f =
- fields(
- "Content-Length: 42\r\n"
- "x: 1\r\n"
- "y: 2\r\n"
- "Set-Cookie: a\r\n"
- "x: 3\r\n"
- "z: 4\r\n"
- "Set-Cookie: b\r\n"
- "x: 5\r\n"
- "p: 6\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
-
- // size()
-
- BOOST_TEST(f.size() == 10);
-
- // at(field)
- // at(string_view)
-
- BOOST_TEST(f.at("x") == "1");
- BOOST_TEST(f.at(field::set_cookie) == "a");
- BOOST_TEST_THROWS(
- f.at("accept"),
- std::out_of_range);
- BOOST_TEST_THROWS(
- f.at(field::accept),
- std::out_of_range);
-
- // exists(field)
- // exists(string_view)
-
- BOOST_TEST(f.exists("x"));
- BOOST_TEST(f.exists("X"));
- BOOST_TEST(f.exists("user-agent"));
- BOOST_TEST(! f.exists("a"));
- BOOST_TEST(f.exists(field::user_agent));
- BOOST_TEST(! f.exists(field::range));
-
- // count(field)
- // count(string_view)
-
- BOOST_TEST(f.count("x") == 3);
- BOOST_TEST(f.count("y") == 1);
- BOOST_TEST(f.count("q") == 0);
- BOOST_TEST(f.count(field::range) == 0);
- BOOST_TEST(f.count(field::user_agent) == 1);
-
- // find(field)
- // find(string_view)
- {
- BOOST_TEST(f.find("x")->name == "x");
- BOOST_TEST(f.find("accept") == f.end());
- BOOST_TEST(f.find(field::range) == f.end());
- BOOST_TEST(f.find(field::user_agent)->value == "boost");
- }
-
- // find(iterator, field)
- // find(iterator, string_view)
- {
- auto const it = f.find("y");
- BOOST_TEST(it != f.end());
- BOOST_TEST(it->value == "2");
-
- BOOST_TEST(f.find(it, "x")->value == "3");
- BOOST_TEST(f.find(it, "q") == f.end());
- BOOST_TEST(f.find(it, field::set_cookie)->value == "a");
- BOOST_TEST(f.find(it, field::range) == f.end());
- }
-
- // find_last(iterator, field)
- // find_last(iterator, string_view)
- {
- auto const it = f.find_last(f.end(), "x");
- BOOST_TEST(it != f.end());
- BOOST_TEST(it->value == "5");
-
- BOOST_TEST(f.find_last(it, "x")->value == "3");
- BOOST_TEST(f.find_last(it, "q") == f.end());
- BOOST_TEST(f.find_last(it, field::set_cookie)->value == "b");
- BOOST_TEST(f.find_last(it, field::range) == f.end());
- }
-
- // value_or(field, string_view)
- // value_or(string_view, string_view)
- {
- BOOST_TEST(f.value_or(
- field::set_cookie, "") == "a");
- BOOST_TEST(f.value_or(
- field::set_cookie2, "Q") == "Q");
-
- BOOST_TEST(f.value_or(
- "set-cookie", "") == "a");
- BOOST_TEST(f.value_or(
- "set-cookie2", "Q") == "Q");
- }
- }
-
- void
- testSubrange()
- {
- }
-
- void
- run()
- {
- testIterators();
- testObservers();
- testSubrange();
- }
-};
-
-TEST_SUITE(
- fields_view_base_test,
- "boost.http_proto.fields_view_base");
-
-} // http_proto
-} // boost
diff --git a/test/unit/message_view_base.cpp b/test/unit/message_view_base.cpp
deleted file mode 100644
index 608653cd..00000000
--- a/test/unit/message_view_base.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-//
-// Copyright (c) 2021 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)
-//
-// Official repository: https://github.com/cppalliance/http_proto
-//
-
-// Test that header file is self-contained.
-#include
diff --git a/test/unit/natvis.cpp b/test/unit/natvis.cpp
index 590321d7..6cd93efd 100644
--- a/test/unit/natvis.cpp
+++ b/test/unit/natvis.cpp
@@ -8,11 +8,8 @@
//
#include
-#include
#include
-#include
#include
-#include
#include "test_suite.hpp"
@@ -32,8 +29,7 @@ struct natvis_test
"Connection: keep-alive\r\n"
"Server: localhost\r\n"
"\r\n");
- request_view rv(req);
- ignore_unused(rv);
+ ignore_unused(req);
}
{
std::error_condition ec(std::errc::address_in_use);
@@ -42,8 +38,7 @@ struct natvis_test
"Connection: keep-alive\r\n"
"Server: localhost\r\n"
"\r\n");
- response_view rv(res);
- ignore_unused(rv);
+ ignore_unused(res);
}
}
};
diff --git a/test/unit/request.cpp b/test/unit/request.cpp
index b4e3fe1e..3c008818 100644
--- a/test/unit/request.cpp
+++ b/test/unit/request.cpp
@@ -12,7 +12,6 @@
#include
#include
-#include
#include
@@ -112,6 +111,38 @@ struct request_test
}
}
+ // request(request const&)
+ {
+ {
+ // default
+ request_base const& r1 = request();
+ request r2(r1);
+ check(r2, 0,
+ "GET / HTTP/1.1\r\n"
+ "\r\n");
+ BOOST_TEST(
+ r2.method() == method::get);
+ BOOST_TEST(
+ r2.method_text() == "GET");
+ BOOST_TEST(
+ r2.version() == version::http_1_1);
+ }
+ {
+ request_base const& r1 = request(cs);
+ request r2(r1);
+ check(r2, 2, cs);
+ BOOST_TEST(
+ r2.buffer().data() !=
+ r1.buffer().data());
+ BOOST_TEST(
+ r2.method() == method::post);
+ BOOST_TEST(
+ r2.method_text() == "POST");
+ BOOST_TEST(
+ r2.version() == version::http_1_0);
+ }
+ }
+
// request(request&&)
{
{
@@ -188,6 +219,27 @@ struct request_test
}
}
+ // operator=(request_base const&)
+ {
+ {
+ request r1(cs);
+ request_base const& r2 = request();
+ r1 = r2;
+ check(r1, 0,
+ "GET / HTTP/1.1\r\n"
+ "\r\n");
+ BOOST_TEST(
+ r1.buffer().data() !=
+ r2.buffer().data());
+ BOOST_TEST(
+ r1.method() == method::get);
+ BOOST_TEST(
+ r1.method_text() == "GET");
+ BOOST_TEST(
+ r1.version() == version::http_1_1);
+ }
+ }
+
// operator=(fields&&)
{
{
@@ -247,57 +299,6 @@ struct request_test
}
}
- void
- testViewConstructor()
- {
- {
- request req;
- BOOST_TEST_EQ(
- req.buffer(),
- "GET / HTTP/1.1\r\n\r\n");
-
- request_view req_view(req);
- request req2(req_view);
-
- BOOST_TEST_EQ(
- req2.buffer(),
- "GET / HTTP/1.1\r\n\r\n");
-
- // default-constructed recycles the same string literal
- BOOST_TEST_EQ(
- req2.buffer().data(),
- req.buffer().data());
-
- BOOST_TEST_EQ(
- req2.buffer().data(),
- req_view.buffer().data());
-
- }
-
- {
- request req;
- req.set_method("POST");
- BOOST_TEST_EQ(
- req.buffer(),
- "POST / HTTP/1.1\r\n\r\n");
-
- request_view req_view(req);
- request req2(req_view);
-
- BOOST_TEST_EQ(
- req2.buffer(),
- "POST / HTTP/1.1\r\n\r\n");
-
- BOOST_TEST_NE(
- req2.buffer().data(),
- req.buffer().data());
-
- BOOST_TEST_NE(
- req2.buffer().data(),
- req_view.buffer().data());
- }
- }
-
void
testObservers()
{
@@ -788,7 +789,6 @@ struct request_test
{
testHelpers();
testSpecial();
- testViewConstructor();
testObservers();
testModifiers();
testExpect();
diff --git a/test/unit/request_parser.cpp b/test/unit/request_parser.cpp
index 68f520c0..db960496 100644
--- a/test/unit/request_parser.cpp
+++ b/test/unit/request_parser.cpp
@@ -99,8 +99,8 @@ struct request_parser_test
BOOST_TEST( pr.got_header() );
if( expected.data() )
{
- auto req_view = pr.get();
- BOOST_TEST_EQ(req_view.buffer(), expected);
+ auto const& req = pr.get();
+ BOOST_TEST_EQ(req.buffer(), expected);
}
}
}
@@ -127,7 +127,7 @@ struct request_parser_test
auto const f =
[&](request_parser const& pr)
{
- auto const req = pr.get();
+ auto const& req = pr.get();
BOOST_TEST(req.method() == m);
BOOST_TEST(req.method_text() ==
to_string(m));
@@ -320,40 +320,40 @@ struct request_parser_test
pr.start();
feed(pr, s);
- auto const rv = pr.get();
+ auto const& req = pr.get();
BOOST_TEST(
- rv.method() == method::get);
+ req.method() == method::get);
BOOST_TEST(
- rv.method_text() == "GET");
- BOOST_TEST(rv.target() == "/");
- BOOST_TEST(rv.version() ==
+ req.method_text() == "GET");
+ BOOST_TEST(req.target() == "/");
+ BOOST_TEST(req.version() ==
version::http_1_1);
- BOOST_TEST(rv.buffer() == s);
- BOOST_TEST(rv.size() == 7);
+ BOOST_TEST(req.buffer() == s);
+ BOOST_TEST(req.size() == 7);
BOOST_TEST(
- rv.exists(field::connection));
- BOOST_TEST(! rv.exists(field::age));
- BOOST_TEST(rv.exists("Connection"));
- BOOST_TEST(rv.exists("CONNECTION"));
- BOOST_TEST(! rv.exists("connector"));
- BOOST_TEST(rv.count(field::accept) == 1);
+ req.exists(field::connection));
+ BOOST_TEST(! req.exists(field::age));
+ BOOST_TEST(req.exists("Connection"));
+ BOOST_TEST(req.exists("CONNECTION"));
+ BOOST_TEST(! req.exists("connector"));
+ BOOST_TEST(req.count(field::accept) == 1);
BOOST_TEST(
- rv.count(field::age) == 0);
+ req.count(field::age) == 0);
BOOST_TEST(
- rv.count("connection") == 1);
- BOOST_TEST(rv.count("a") == 2);
- BOOST_TEST(rv.find(
+ req.count("connection") == 1);
+ BOOST_TEST(req.count("a") == 2);
+ BOOST_TEST(req.find(
field::connection)->id ==
field::connection);
BOOST_TEST(
- rv.find("a")->value == "1");
+ req.find("a")->value == "1");
grammar::recycled_ptr temp;
- BOOST_TEST(combine_field_values(rv.find_all(
+ BOOST_TEST(combine_field_values(req.find_all(
field::user_agent), temp) == "x");
- BOOST_TEST(combine_field_values(rv.find_all(
+ BOOST_TEST(combine_field_values(req.find_all(
"b"), temp) == "2");
- BOOST_TEST(combine_field_values(rv.find_all(
+ BOOST_TEST(combine_field_values(req.find_all(
"a"), temp) == "1,3");
}
diff --git a/test/unit/request_view.cpp b/test/unit/request_view.cpp
deleted file mode 100644
index ab976ed1..00000000
--- a/test/unit/request_view.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-//
-// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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)
-//
-// Official repository: https://github.com/cppalliance/http_proto
-//
-
-// Test that header file is self-contained.
-#include
-
-#include "test_helpers.hpp"
-
-namespace boost {
-namespace http_proto {
-
-class request_view_test
-{
-public:
- void
- run()
- {
- // request_view()
- {
- request_view req;
- }
-
- // request_view(request_view const&)
- {
- {
- request_view req1;
- request_view req2(req1);
- }
- }
-
- // operator=(request_view const&)
- {
- {
- request_view req1;
- request_view req2;
- req1 = req2;
- }
- }
- }
-};
-
-TEST_SUITE(
- request_view_test,
- "boost.http_proto.request_view");
-
-} // http_proto
-} // boost
-
diff --git a/test/unit/response.cpp b/test/unit/response.cpp
index 790ed976..3128b090 100644
--- a/test/unit/response.cpp
+++ b/test/unit/response.cpp
@@ -11,7 +11,6 @@
// Test that header file is self-contained.
#include
-#include
#include
#include
@@ -151,6 +150,30 @@ class response_test
}
}
+ // response(response_base const&)
+ {
+ {
+ response_base const& r1 = response();
+ response r2 = response(r1);
+ check(r1, status::ok, 200, "OK", version::http_1_1);
+ check(r2, status::ok, 200, "OK", version::http_1_1);
+ BOOST_TEST(
+ r1.buffer().data() == r2.buffer().data());
+ BOOST_TEST(r1.capacity_in_bytes() == 0);
+ BOOST_TEST(r2.capacity_in_bytes() == 0);
+ }
+ {
+ response_base const& r1 = response(status::not_found, version::http_1_0);
+ response r2 = response(r1);
+ check(r1, status::not_found, 404, "Not Found", version::http_1_0);
+ check(r2, status::not_found, 404, "Not Found", version::http_1_0);
+ BOOST_TEST(
+ r1.buffer().data() != r2.buffer().data());
+ BOOST_TEST(r1.capacity_in_bytes() > 0);
+ BOOST_TEST(r2.capacity_in_bytes() > 0);
+ }
+ }
+
// operator=(response&&)
{
response r1;
@@ -173,67 +196,16 @@ class response_test
BOOST_TEST(r2.capacity_in_bytes() > 0);
}
- //----------------------------------------
-
- // response(response_view const&)
- {
- core::string_view const s =
- "HTTP/1.0 404 Not Found\r\n"
- "Server: test\r\n"
- "\r\n";
- response r(s);
- response_view rv = r;
- response res(rv);
- check(res, status::not_found, 404, "Not Found", version::http_1_0);
- BOOST_TEST_EQ(res.buffer(), s);
- BOOST_TEST(res.buffer().data() != s.data());
- BOOST_TEST(res.begin()->id == field::server);
- BOOST_TEST(res.begin()->name == "Server");
- BOOST_TEST(res.begin()->value == "test");
- }
-
- // operator=(response_view const&)
- {
- core::string_view const s =
- "HTTP/1.1 101 Switching Protocols\r\n"
- "Server: test\r\n"
- "\r\n";
- response r(s);
- response_view rv = r;
- response res(status::not_found);
- res = rv;
- BOOST_TEST_EQ(res.buffer(), s);
- BOOST_TEST(res.buffer().data() != s.data());
- check(res, status::switching_protocols, 101, "Switching Protocols", version::http_1_1);
- BOOST_TEST(res.begin()->id == field::server);
- BOOST_TEST(res.begin()->name == "Server");
- BOOST_TEST(res.begin()->value == "test");
- }
-
- //----------------------------------------
-
- // operator response_view()
+ // operator=(response_base const&)
{
- {
- response res;
- response_view rv(res);
- BOOST_TEST_EQ(rv.version(), version::http_1_1);
- BOOST_TEST_EQ(rv.status(), status::ok);
- BOOST_TEST_EQ(rv.status_int(), 200);
- BOOST_TEST_EQ(rv.reason(), "OK");
- BOOST_TEST_EQ(rv.buffer(), "HTTP/1.1 200 OK\r\n\r\n");
- BOOST_TEST(rv.buffer().data() == res.buffer().data());
- }
- {
- response res(status::not_found, version::http_1_0);
- response_view rv(res);
- BOOST_TEST_EQ(rv.version(), version::http_1_0);
- BOOST_TEST_EQ(rv.status(), status::not_found);
- BOOST_TEST_EQ(rv.status_int(), 404);
- BOOST_TEST_EQ(rv.reason(), "Not Found");
- BOOST_TEST_EQ(rv.buffer(), "HTTP/1.0 404 Not Found\r\n\r\n");
- BOOST_TEST(rv.buffer().data() == res.buffer().data());
- }
+ response r1;
+ response_base const& r2 = response(status::not_found, version::http_1_0);
+ r1 = r2;
+ check(r1, status::not_found, 404, "Not Found", version::http_1_0);
+ BOOST_TEST(
+ r1.buffer().data() != r2.buffer().data());
+ BOOST_TEST(r1.capacity_in_bytes() > 0);
+ BOOST_TEST(r2.capacity_in_bytes() > 0);
}
}
@@ -298,8 +270,7 @@ class response_test
"Content-Length: 0\r\n"
"\r\n";
response r(s);
- response_view rv = r;
- response res(rv);
+ response res(r);
check(res, status::ok, 200, "OK", version::http_1_1);
BOOST_TEST(res.size() == 2);
auto it = res.begin();
diff --git a/test/unit/response_view.cpp b/test/unit/response_view.cpp
deleted file mode 100644
index f578bf51..00000000
--- a/test/unit/response_view.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.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)
-//
-// Official repository: https://github.com/cppalliance/http_proto
-//
-
-// Test that header file is self-contained.
-#include
-
-#include "test_suite.hpp"
-
-namespace boost {
-namespace http_proto {
-
-class response_view_test
-{
-public:
- void
- run()
- {
- // response_view()
- {
- response_view req;
- }
-
- // response_view(response_view const&)
- {
- {
- response_view res1;
- response_view res2(res1);
- (void)res2;
- }
- }
-
- // operator=(response_view const&)
- {
- {
- response_view res1;
- response_view res2;
- res1 = res2;
- }
- }
- }
-};
-
-TEST_SUITE(
- response_view_test,
- "boost.http_proto.response_view");
-
-} // http_proto
-} // boost
-
diff --git a/test/unit/static_fields.cpp b/test/unit/static_fields.cpp
deleted file mode 100644
index 063dea2b..00000000
--- a/test/unit/static_fields.cpp
+++ /dev/null
@@ -1,249 +0,0 @@
-//
-// Copyright (c) 2025 Mohammad Nejati
-//
-// 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)
-//
-// Official repository: https://github.com/cppalliance/http_proto
-//
-
-// Test that header file is self-contained.
-#include
-
-#include
-#include
-#include
-
-#include "test_helpers.hpp"
-#include "test_suite.hpp"
-
-#include
-#include
-
-namespace boost {
-namespace http_proto {
-
-struct static_fields_test
-{
- template
- void
- modify(
- core::string_view before,
- void (*pf)(static_fields<256>&),
- core::string_view after)
- {
- static_fields<256> f0(before);
- static_fields<256> f1(after);
- static_fields<256> f(f0);
- (*pf)(f);
- BOOST_TEST_EQ(f.buffer(),
- f1.buffer());
- }
-
- //--------------------------------------------
-
- void
- testSpecial()
- {
- core::string_view const cs1 =
- "Connection: close\r\n"
- "Set-Cookie: 0\r\n"
- "User-Agent: boost\r\n"
- "Set-Cookie: 1\r\n"
- "\r\n";
-
- // static_fields(static_fields<256> const&)
- {
- {
- static_fields<256> f1(cs1);
- static_fields<256> f2(f1);
- test_fields(f1, cs1);
- test_fields(f2, cs1);
- BOOST_TEST_NE(
- f1.buffer().data(),
- f2.buffer().data());
- }
- }
-
- // static_fields(fields_view const&)
- {
- {
- static_fields<256> f1(cs1);
- static_fields<256> f2(static_cast<
- fields_view>(f1));
-
- BOOST_TEST_EQ(
- f2.buffer(), cs1);
- BOOST_TEST_NE(
- f2.buffer().data(),
- cs1.data());
- test_fields(f2, cs1);
- }
-
- // default buffer
- {
- static_fields<256> f;
- BOOST_TEST_EQ(
- f.buffer(), "\r\n");
- }
- }
-
- // operator=(static_fields<256> const&)
- {
- {
- static_fields<256> f1(cs1);
- static_fields<256> f2;
- f2 = f1;
- test_fields(f1, cs1);
- test_fields(f2, cs1);
- BOOST_TEST_NE(
- f1.buffer().data(),
- f2.buffer().data());
- }
- {
- static_fields<256> f1(cs1);
- static_fields<256> f2(
- "x: 1\r\n"
- "y: 2\r\n"
- "z: 3\r\n"
- "\r\n");
- f2 = f1;
- test_fields(f1, cs1);
- test_fields(f2, cs1);
- BOOST_TEST_NE(
- f1.buffer().data(),
- f2.buffer().data());
- }
- {
- static_fields<256> f1;
- static_fields<256> f2(cs1);
- f2 = f1;
- test_fields(f1, "\r\n");
- test_fields(f2, "\r\n");
- BOOST_TEST_NE(
- f1.buffer().data(),
- f2.buffer().data());
- }
- }
-
- // operator=(fields_view)
- {
- {
- static_fields<256> f1(cs1);
- static_fields<256> f2;
- f2 = static_cast<
- fields_view>(f1);
- test_fields(f1, cs1);
- test_fields(f2, cs1);
- BOOST_TEST_NE(
- f1.buffer().data(),
- f2.buffer().data());
- }
- {
- static_fields<256> f1(cs1);
- static_fields<256> f2(
- "x: 1\r\n"
- "y: 2\r\n"
- "z: 3\r\n"
- "\r\n");
- f2 = static_cast<
- fields_view>(f1);
- test_fields(f1, cs1);
- test_fields(f2, cs1);
- BOOST_TEST_NE(
- f1.buffer().data(),
- f2.buffer().data());
- }
- {
- fields_view f1;
- static_fields<256> f2(cs1);
- f2 = f1;
- test_fields(f1, "\r\n");
- test_fields(f2, "\r\n");
- BOOST_TEST_NE(
- f1.buffer().data(),
- f2.buffer().data());
- }
-
- // existing capacity
- {
- static_fields<256> f1(cs1);
- static_fields<512> f2;
- f2.reserve_bytes(
- 2 * cs1.size() + 128);
- f2 = static_cast<
- fields_view>(f1);
- test_fields(f2, cs1);
- BOOST_TEST_NE(
- f1.buffer().data(),
- f2.buffer().data());
- }
- }
- }
-
- void
- testObservers()
- {
- core::string_view const cs =
- "Connection: close\r\n"
- "Set-Cookie: 0\r\n"
- "User-Agent: boost\r\n"
- "Set-Cookie: 1\r\n"
- "\r\n";
-
- // fields_view_base::string()
- {
- static_fields<256> f1(cs);
- BOOST_TEST_EQ(f1.buffer(), cs);
- }
-
- // fields_base::capacity_in_bytes()
- {
- {
- static_fields<256> f;
- BOOST_TEST_EQ(
- f.capacity_in_bytes(), 256U);
- }
- {
- static_fields<256> f;
- f.reserve_bytes(100);
- BOOST_TEST_EQ(
- f.capacity_in_bytes(), 256U);
- }
- {
- static_fields<256> f;
- f.reserve_bytes(100);
- f.shrink_to_fit();
- BOOST_TEST_EQ(
- f.capacity_in_bytes(), 256U);
- }
- }
- }
-
- void
- testInitialSize()
- {
- {
- static_fields<32> f{};
- BOOST_TEST_THROWS(
- f.append(field::host, "www.google.com"), std::length_error);
- BOOST_TEST_EQ(
- f.max_capacity_in_bytes(), 32);
- }
- }
-
- void
- run()
- {
- testSpecial();
- testObservers();
- testInitialSize();
- }
-};
-
-TEST_SUITE(
- static_fields_test,
- "boost.http_proto.static_fields");
-
-} // http_proto
-} // boost
diff --git a/test/unit/static_request.cpp b/test/unit/static_request.cpp
index aff76eb5..78a1f9ec 100644
--- a/test/unit/static_request.cpp
+++ b/test/unit/static_request.cpp
@@ -10,7 +10,7 @@
// Test that header file is self-contained.
#include
-#include
+#include
#include
@@ -21,51 +21,19 @@ namespace http_proto {
struct static_request_test
{
- template
- static
- void
- check(
- static_request& req,
- std::size_t count,
- core::string_view s)
- {
- req = static_request(s);
- BOOST_TEST(
- req.size() == count);
- }
-
- void
- testHelpers()
- {
- core::string_view const cs =
- "POST /x HTTP/1.0\r\n"
- "User-Agent: boost\r\n"
- "\r\n";
- static_request<64> req(cs);
- BOOST_TEST(req.method() == method::post);
- BOOST_TEST(req.method_text() == "POST");
- BOOST_TEST(req.target() == "/x");
- BOOST_TEST(req.version() == version::http_1_0);
- BOOST_TEST(req.buffer().data() != cs.data());
- BOOST_TEST(req.buffer() == cs);
- }
-
void
testSpecial()
{
-
core::string_view const cs =
"POST /x HTTP/1.0\r\n"
"Content-Length: 42\r\n"
"User-Agent: boost\r\n"
"\r\n";
- // static_request()
+ // static_request(void* storage, std::size_t cap)
{
- static_request<64> req;
- check(req, 0,
- "GET / HTTP/1.1\r\n"
- "\r\n");
+ char buf[64];
+ static_request req(buf, sizeof(buf));
BOOST_TEST(
req.method() == method::get);
BOOST_TEST(
@@ -76,495 +44,55 @@ struct static_request_test
req.version() == version::http_1_1);
}
- // static_request(static_request const&)
- {
- {
- // default
- static_request<64> r1;
- static_request<64> r2(r1);
- check(r2, 0,
- "GET / HTTP/1.1\r\n"
- "\r\n");
- BOOST_TEST(
- r2.method() == method::get);
- BOOST_TEST(
- r2.method_text() == "GET");
- BOOST_TEST(
- r2.version() == version::http_1_1);
- }
- {
- static_request<128> r1(cs);
- static_request<128> r2(r1);
- check(r1, 2, cs);
- check(r2, 2, cs);
- BOOST_TEST(
- r2.buffer().data() !=
- r1.buffer().data());
- BOOST_TEST(
- r2.method() == method::post);
- BOOST_TEST(
- r2.method_text() == "POST");
- BOOST_TEST(
- r2.version() == version::http_1_0);
- }
- }
-
- // operator=(static_request const&)
- {
- {
- // default
- static_request<128> r1;
- static_request<128> r2(cs);
- r1 = r2;
- check(r1, 2, cs);
- check(r2, 2, cs);
- BOOST_TEST(
- r2.buffer().data() !=
- r1.buffer().data());
- BOOST_TEST(
- r1.method() == method::post);
- BOOST_TEST(
- r1.method_text() == "POST");
- BOOST_TEST(
- r1.version() == version::http_1_0);
- }
- {
- static_request<128> r1(cs);
- static_request<128> r2;
- r1 = r2;
- check(r1, 0,
- "GET / HTTP/1.1\r\n"
- "\r\n");
- BOOST_TEST(
- r1.buffer().data() !=
- r2.buffer().data());
- BOOST_TEST(
- r1.method() == method::get);
- BOOST_TEST(
- r1.method_text() == "GET");
- BOOST_TEST(
- r1.version() == version::http_1_1);
- }
- }
- }
-
- void
- testViewConstructor()
- {
- {
- static_request<64> req;
- BOOST_TEST_EQ(
- req.buffer(),
- "GET / HTTP/1.1\r\n\r\n");
-
- request_view req_view(req);
- static_request<64> req2(req_view);
-
- BOOST_TEST_EQ(
- req2.buffer(),
- "GET / HTTP/1.1\r\n\r\n");
-
- BOOST_TEST_NE(
- req2.buffer().data(),
- req.buffer().data());
- }
-
+ // static_request(static_request&&)
{
- static_request<64> req;
- req.set_method("POST");
- BOOST_TEST_EQ(
- req.buffer(),
- "POST / HTTP/1.1\r\n\r\n");
-
- request_view req_view(req);
- static_request<64> req2(req_view);
-
- BOOST_TEST_EQ(
- req2.buffer(),
- "POST / HTTP/1.1\r\n\r\n");
-
- BOOST_TEST_NE(
- req2.buffer().data(),
- req.buffer().data());
-
- BOOST_TEST_NE(
- req2.buffer().data(),
- req_view.buffer().data());
- }
- }
-
- void
- testObservers()
- {
- }
-
- void
- testModifiers()
- {
- // clear()
- {
- {
- static_request<64> req;
- BOOST_TEST(req.capacity_in_bytes() == 64);
- req.clear();
- BOOST_TEST(req.capacity_in_bytes() == 64);
- BOOST_TEST(req.buffer() ==
- "GET / HTTP/1.1\r\n\r\n");
- }
- {
- static_request<128> req(
- "POST /x HTTP/1.1\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
- auto const n =
- req.capacity_in_bytes();
- BOOST_TEST(n > 0);
- req.clear();
- BOOST_TEST(req.size() == 0);
- BOOST_TEST(
- req.capacity_in_bytes() == n);
- BOOST_TEST(
- req.method() == method::get);
- BOOST_TEST(
- req.method_text() == "GET");
- BOOST_TEST(
- req.target() == "/");
- BOOST_TEST(
- req.version() == version::http_1_1);
- BOOST_TEST(req.buffer() ==
- "GET / HTTP/1.1\r\n\r\n");
- }
- }
-
- // set_method(method)
- {
- {
- static_request<64> req;
- req.set_method(method::delete_);
- BOOST_TEST(
- req.method() == method::delete_);
- BOOST_TEST(
- req.method_text() == "DELETE");
- BOOST_TEST(req.buffer() ==
- "DELETE / HTTP/1.1\r\n\r\n");
- }
- {
- static_request<128> req(
- "POST /x HTTP/1.1\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
- req.set_method(method::delete_);
- BOOST_TEST(
- req.method() == method::delete_);
- BOOST_TEST(
- req.method_text() == "DELETE");
- BOOST_TEST(req.buffer() ==
- "DELETE /x HTTP/1.1\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
- }
- }
-
- // set_method(string_view)
- {
- {
- static_request<64> req;
- req.set_method("DELETE");
- BOOST_TEST(
- req.method() == method::delete_);
- BOOST_TEST(
- req.method_text() == "DELETE");
- BOOST_TEST(req.buffer() ==
- "DELETE / HTTP/1.1\r\n\r\n");
- }
- {
- static_request<128> req(
- "POST /abcdefghijklmnopqrstuvwxyz HTTP/1.1\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
- req.set_method("DELETE");
- BOOST_TEST(
- req.method() == method::delete_);
- BOOST_TEST(
- req.method_text() == "DELETE");
- BOOST_TEST(req.buffer() ==
- "DELETE /abcdefghijklmnopqrstuvwxyz HTTP/1.1\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
- }
- {
- static_request<128> req(
- "DELETE /abcdefghijklmnopqrstuvwxyz HTTP/1.1\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
- req.set_method("PUT");
- BOOST_TEST(
- req.method() == method::put);
- BOOST_TEST(
- req.method_text() == "PUT");
- BOOST_TEST(req.buffer() ==
- "PUT /abcdefghijklmnopqrstuvwxyz HTTP/1.1\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
- }
- {
- static_request<128> req(
- "SOMETHINGSUPERLONGHERE /abcdefghijklmnopqrstuvwxyz HTTP/1.1\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
- req.set_method("PUT");
- BOOST_TEST(
- req.method() == method::put);
- BOOST_TEST(
- req.method_text() == "PUT");
- BOOST_TEST_EQ(req.buffer(),
- "PUT /abcdefghijklmnopqrstuvwxyz HTTP/1.1\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
- }
- {
- static_request<128> req(
- "SOMETHINGSUPERLONGHERE /abcdefghijklmnopqrstuvwxyz HTTP/1.1\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
- req.set_method("SOMETHINGSUPERLONGHERE");
- BOOST_TEST(
- req.method() == method::unknown);
- BOOST_TEST(
- req.method_text() == "SOMETHINGSUPERLONGHERE");
- BOOST_TEST(req.buffer() ==
- "SOMETHINGSUPERLONGHERE /abcdefghijklmnopqrstuvwxyz HTTP/1.1\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
- }
- }
-
- // set_target
- {
- {
- static_request<128> req;
- req.set_target("/index.htm");
- BOOST_TEST(
- req.target() == "/index.htm");
- BOOST_TEST(req.buffer() ==
- "GET /index.htm HTTP/1.1\r\n\r\n");
- }
- {
- static_request<128> req(
- "POST /x HTTP/1.1\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
- req.set_target("/index.htm");
- BOOST_TEST(req.buffer() ==
- "POST /index.htm HTTP/1.1\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
- }
- {
- // shrinks
- static_request<128> req(
- "SOMETHINGSUPERLONGHERE /abcdefghijklmnopqrstuvwxyz HTTP/1.1\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
- req.set_target("/abc");
- BOOST_TEST_EQ(
- req.target(), "/abc");
- BOOST_TEST_EQ(req.buffer(),
- "SOMETHINGSUPERLONGHERE /abc HTTP/1.1\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
- }
- {
- // same size
- static_request<128> req(
- "SOMETHINGSUPERLONGHERE /abcdefghijklmnopqrstuvwxyz HTTP/1.1\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
- req.set_target("/zyxwvutsrqponmlkjihgfedcba");
- BOOST_TEST_EQ(
- req.target(), "/zyxwvutsrqponmlkjihgfedcba");
- BOOST_TEST_EQ(req.buffer(),
- "SOMETHINGSUPERLONGHERE /zyxwvutsrqponmlkjihgfedcba HTTP/1.1\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
- }
- {
- // grows
- static_request<128> req(
- "SOMETHINGSUPERLONGHERE /abcdefghijklmnopqrstuvwxyz HTTP/1.1\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
- req.set_target("/abcdefghijklmnopqrstuvwxyzzyxwvutsrqponmlkjihgfedcba");
- BOOST_TEST_EQ(
- req.target(), "/abcdefghijklmnopqrstuvwxyzzyxwvutsrqponmlkjihgfedcba");
- BOOST_TEST_EQ(req.buffer(),
- "SOMETHINGSUPERLONGHERE /abcdefghijklmnopqrstuvwxyzzyxwvutsrqponmlkjihgfedcba HTTP/1.1\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
- }
- }
-
- // set_version
- {
- {
- static_request<128> req;
- req.set_version(version::http_1_0);
- BOOST_TEST(
- req.version() == version::http_1_0);
- BOOST_TEST(req.buffer() ==
- "GET / HTTP/1.0\r\n\r\n");
- }
- {
- static_request<128> req(
- "POST /x HTTP/1.1\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
- req.set_version(version::http_1_0);
- BOOST_TEST(
- req.version() == version::http_1_0);
- BOOST_TEST(req.buffer() ==
- "POST /x HTTP/1.0\r\n"
- "User-Agent: boost\r\n"
- "\r\n");
- }
- }
- }
-
- void
- testExpect()
- {
- {
- static_request<64> req;
- req.set_expect_100_continue(true);
+ char buf[64];
+ static_request r1(buf, sizeof(buf));
+ static_request r2(std::move(r1));
BOOST_TEST(
- req.metadata().expect.is_100_continue);
-
- req.set_expect_100_continue(false);
+ r2.buffer().data() != r1.buffer().data());
BOOST_TEST(
- !req.metadata().expect.is_100_continue);
+ r2.buffer().data() == buf);
}
-
+ // operator=(request_base const&)
{
- static_request<64> req;
- req.set_expect_100_continue(false);
+ char buf1[128];
+ static_request r1(buf1, sizeof(buf1));
+ const request r2(cs);
+ r1 = r2;
BOOST_TEST(
- !req.metadata().expect.is_100_continue);
- }
-
- {
- static_request<64> req;
- req.set_expect_100_continue(true);
- BOOST_TEST(
- req.metadata().expect.is_100_continue);
-
- req.set_expect_100_continue(true);
+ r1.buffer() == cs);
BOOST_TEST(
- req.metadata().expect.is_100_continue);
+ r1.buffer().data() != r2.buffer().data());
}
+ // operator=(static_request const&)
{
- static_request<64> req;
- BOOST_TEST(
- !req.metadata().expect.ec.failed());
-
- req.set("Expect", "101-dalmations");
- BOOST_TEST(
- req.metadata().expect.ec.failed());
-
- req.set_expect_100_continue(true);
- BOOST_TEST(
- !req.metadata().expect.ec.failed());
- BOOST_TEST(
- req.metadata().expect.is_100_continue);
- }
-
- {
- static_request<128> req;
- req.append("Expect", "100-continue");
- req.append("Expect", "101-dalmations");
-
- BOOST_TEST(
- req.metadata().expect.ec.failed());
- BOOST_TEST_EQ(
- req.count("Expect"), 2);
-
- req.set_expect_100_continue(true);
- BOOST_TEST(
- !req.metadata().expect.ec.failed());
- BOOST_TEST(
- req.metadata().expect.is_100_continue);
- BOOST_TEST_EQ(
- req.count("Expect"), 1);
- }
-
- {
- static_request<256> req;
- req.append("Expect", "100-continue");
- req.append("Content-Length", "1234");
- req.append("Expect", "100-continue");
-
- BOOST_TEST(
- req.metadata().expect.ec.failed());
- BOOST_TEST_EQ(
- req.count("Expect"), 2);
-
- req.set_expect_100_continue(true);
- BOOST_TEST(
- !req.metadata().expect.ec.failed());
- BOOST_TEST(
- req.metadata().expect.is_100_continue);
- BOOST_TEST_EQ(
- req.count("Expect"), 1);
- }
-
- {
- static_request<256> req;
- req.append("Expect", "404-not-found");
- req.append("Content-Length", "1234");
- req.append("Expect", "101-dalmations");
-
- BOOST_TEST(
- req.metadata().expect.ec.failed());
- BOOST_TEST_EQ(
- req.count("Expect"), 2);
-
- req.set_expect_100_continue(true);
- BOOST_TEST(
- !req.metadata().expect.ec.failed());
- BOOST_TEST(
- req.metadata().expect.is_100_continue);
- BOOST_TEST_EQ(
- req.count("Expect"), 1);
- }
-
- {
- static_request<256> req;
- req.append("Expect", "100-continue");
- req.append("Content-Length", "1234");
- req.append("Expect", "100-continue");
-
- BOOST_TEST(
- req.metadata().expect.ec.failed());
- BOOST_TEST_EQ(
- req.count("Expect"), 2);
-
- req.set_expect_100_continue(false);
+ char buf1[128];
+ static_request r1(buf1, sizeof(buf1));
+ r1 = request(cs);
+ char buf2[128];
+ static_request r2(buf2, sizeof(buf2));
+ r2 = r1;
BOOST_TEST(
- !req.metadata().expect.ec.failed());
+ r2.buffer() == cs);
BOOST_TEST(
- !req.metadata().expect.is_100_continue);
- BOOST_TEST_EQ(
- req.count("Expect"), 0);
- BOOST_TEST_EQ(
- req.count("Content-Length"), 1);
+ r2.buffer().data() != r1.buffer().data());
}
}
void
- testInitialSize()
+ testCapacity()
{
- static_request<96> r;
+ char buf[96];
+ static_request r(buf, sizeof(buf));
+
+ BOOST_TEST_EQ(
+ r.capacity_in_bytes(), 96);
+ BOOST_TEST_EQ(
+ r.max_capacity_in_bytes(), 96);
+
r.append("T", "*");
r.append("T", "*");
r.append("T", "*");
@@ -583,13 +111,8 @@ struct static_request_test
void
run()
{
- testHelpers();
testSpecial();
- testViewConstructor();
- testObservers();
- testModifiers();
- testExpect();
- testInitialSize();
+ testCapacity();
}
};
diff --git a/test/unit/static_response.cpp b/test/unit/static_response.cpp
index d26c78cd..70b27573 100644
--- a/test/unit/static_response.cpp
+++ b/test/unit/static_response.cpp
@@ -10,11 +10,7 @@
// Test that header file is self-contained.
#include
-#include
-#include
-
-#include
-#include
+#include
#include "test_suite.hpp"
@@ -24,253 +20,75 @@ namespace http_proto {
class static_response_test
{
public:
-
- template
- static
- void
- check(
- static_response const& res,
- status sc,
- unsigned short si,
- core::string_view rs,
- version v)
- {
- BOOST_TEST_EQ(res.version(), v);
- BOOST_TEST_EQ(res.status(), sc);
- BOOST_TEST_EQ(res.status_int(), si);
- BOOST_TEST_EQ(res.reason(), rs);
- }
-
void
testSpecial()
{
- // static_response(status, version)
- {
- {
- static_response<64> res(status::ok);
- check(res, status::ok, 200, "OK", version::http_1_1);
- BOOST_TEST(res.capacity_in_bytes() == 64);
- BOOST_TEST_EQ(res.buffer(), "HTTP/1.1 200 OK\r\n\r\n");
- }
-
- {
- static_response<64> res(status::ok, version::http_1_0);
- check(res, status::ok, 200, "OK", version::http_1_0);
- BOOST_TEST(res.capacity_in_bytes() == 64);
- BOOST_TEST_EQ(res.buffer(), "HTTP/1.0 200 OK\r\n\r\n");
- }
-
- {
- static_response<64> res(status::not_found, version::http_1_0);
- check(res, status::not_found, 404, "Not Found", version::http_1_0);
- BOOST_TEST(res.capacity_in_bytes() == 64);
- }
-
- // different buffer
- {
- static_response<64> r1(status::not_found);
- static_response<64> r2(status::not_found);
- BOOST_TEST(r1.buffer().data() != r2.buffer().data());
- BOOST_TEST(r1.capacity_in_bytes() == 64);
- BOOST_TEST(r2.capacity_in_bytes() == 64);
- }
- }
+ core::string_view const cs =
+ "HTTP/1.1 101 Switching Protocols\r\n"
+ "Server: test\r\n"
+ "\r\n";
- // static_response()
+ // static_response(void* storage, std::size_t cap)
{
- {
- static_response<64> res;
- check(res, status::ok, 200, "OK", version::http_1_1);
- BOOST_TEST(res.capacity_in_bytes() == 64);
- }
+ char buf[64];
+ static_response req(buf, sizeof(buf));
+ BOOST_TEST(
+ req.status_int() == 200);
+ BOOST_TEST(
+ req.status() == status::ok);
+ BOOST_TEST(
+ req.version() == version::http_1_1);
}
- // static_response(static_response<64> const&)
+ // static_response(static_response&&)
{
- {
- static_response<64> r1;
- static_response<64> r2(r1);
- check(r1, status::ok, 200, "OK", version::http_1_1);
- check(r2, status::ok, 200, "OK", version::http_1_1);
- BOOST_TEST_NE(
- r1.buffer().data(),
- r2.buffer().data());
- BOOST_TEST(r1.capacity_in_bytes() == 64);
- BOOST_TEST(r2.capacity_in_bytes() == 64);
- }
- {
- static_response<64> r1(status::not_found, version::http_1_0);
- static_response<64> r2(r1);
- check(r1, status::not_found, 404, "Not Found", version::http_1_0);
- check(r2, status::not_found, 404, "Not Found", version::http_1_0);
- BOOST_TEST(
- r1.buffer().data() != r2.buffer().data());
- BOOST_TEST(r1.capacity_in_bytes() == 64);
- BOOST_TEST(r2.capacity_in_bytes() == 64);
- }
+ char buf[64];
+ static_response r1(buf, sizeof(buf));
+ static_response r2(std::move(r1));
+ BOOST_TEST(
+ r2.buffer().data() != r1.buffer().data());
+ BOOST_TEST(
+ r2.buffer().data() == buf);
}
- // operator=(static_response<64> const&)
+ // operator=(response_base const&)
{
- static_response<64> r1;
- static_response<64> r2(status::not_found, version::http_1_0);
+ char buf1[128];
+ static_response r1(buf1, sizeof(buf1));
+ const response r2(cs);
r1 = r2;
- check(r1, status::not_found, 404, "Not Found", version::http_1_0);
- check(r2, status::not_found, 404, "Not Found", version::http_1_0);
+ BOOST_TEST(
+ r1.buffer() == cs);
BOOST_TEST(
r1.buffer().data() != r2.buffer().data());
- BOOST_TEST(r1.capacity_in_bytes() == 64);
- BOOST_TEST(r2.capacity_in_bytes() == 64);
- }
-
- //----------------------------------------
-
- // static_response(response_view const&)
- {
- core::string_view const s =
- "HTTP/1.0 404 Not Found\r\n"
- "Server: test\r\n"
- "\r\n";
- static_response<64> r(s);
- response_view rv = r;
- static_response<64> res(rv);
- check(res, status::not_found, 404, "Not Found", version::http_1_0);
- BOOST_TEST_EQ(res.buffer(), s);
- BOOST_TEST(res.buffer().data() != s.data());
- BOOST_TEST(res.begin()->id == field::server);
- BOOST_TEST(res.begin()->name == "Server");
- BOOST_TEST(res.begin()->value == "test");
- }
-
- // operator=(response_view const&)
- {
- core::string_view const s =
- "HTTP/1.1 101 Switching Protocols\r\n"
- "Server: test\r\n"
- "\r\n";
- static_response<128> r(s);
- response_view rv = r;
- static_response<128> res(status::not_found);
- res = rv;
- BOOST_TEST_EQ(res.buffer(), s);
- BOOST_TEST(res.buffer().data() != s.data());
- check(res, status::switching_protocols, 101, "Switching Protocols", version::http_1_1);
- BOOST_TEST(res.begin()->id == field::server);
- BOOST_TEST(res.begin()->name == "Server");
- BOOST_TEST(res.begin()->value == "test");
- }
-
- //----------------------------------------
-
- // operator response_view()
- {
- {
- static_response<64> res;
- response_view rv(res);
- BOOST_TEST_EQ(rv.version(), version::http_1_1);
- BOOST_TEST_EQ(rv.status(), status::ok);
- BOOST_TEST_EQ(rv.status_int(), 200);
- BOOST_TEST_EQ(rv.reason(), "OK");
- BOOST_TEST_EQ(rv.buffer(), "HTTP/1.1 200 OK\r\n\r\n");
- BOOST_TEST(rv.buffer().data() == res.buffer().data());
- }
- {
- static_response<64> res(status::not_found, version::http_1_0);
- response_view rv(res);
- BOOST_TEST_EQ(rv.version(), version::http_1_0);
- BOOST_TEST_EQ(rv.status(), status::not_found);
- BOOST_TEST_EQ(rv.status_int(), 404);
- BOOST_TEST_EQ(rv.reason(), "Not Found");
- BOOST_TEST_EQ(rv.buffer(), "HTTP/1.0 404 Not Found\r\n\r\n");
- BOOST_TEST(rv.buffer().data() == res.buffer().data());
- }
}
- }
- void
- testModifiers()
- {
- // clear()
+ // operator=(static_response const&)
{
- {
- static_response<64> res;
- BOOST_TEST(res.capacity_in_bytes() == 64);
- res.clear();
- BOOST_TEST(res.buffer() == "HTTP/1.1 200 OK\r\n\r\n");
- }
- {
- static_response<64> res(status::not_found, version::http_1_0);
- BOOST_TEST(res.capacity_in_bytes() == 64);
- res.clear();
- check(res, status::ok, 200, "OK", version::http_1_1);
- BOOST_TEST(res.capacity_in_bytes() == 64);
- }
+ char buf1[128];
+ static_response r1(buf1, sizeof(buf1));
+ r1 = response(cs);
+ char buf2[128];
+ static_response r2(buf2, sizeof(buf2));
+ r2 = r1;
+ BOOST_TEST(
+ r2.buffer() == cs);
+ BOOST_TEST(
+ r2.buffer().data() != r1.buffer().data());
}
- // set_start_line()
- {
- {
- static_response<64> res;
- res.set_start_line(status::not_found);
- check(res, status::not_found, 404, "Not Found", version::http_1_1);
- }
- {
- static_response<64> res;
- res.set_start_line(status::switching_protocols, version::http_1_0);
- check(res, status::switching_protocols, 101, "Switching Protocols", version::http_1_0);
- }
- {
- static_response<64> res;
- res.set_start_line(199, "Huh", version::http_1_1);
- check(res, status::unknown, 199, "Huh", version::http_1_1);
- }
- {
- static_response<64> res;
- res.set_start_line(199, "Huh", version::http_1_1);
- check(res, status::unknown, 199, "Huh", version::http_1_1);
-
- res.set_start_line(199, "Huh", version::http_1_1);
- check(res, status::unknown, 199, "Huh", version::http_1_1);
-
- res.set_start_line(199, "ab", version::http_1_1);
- check(res, status::unknown, 199, "ab", version::http_1_1);
-
- res.set_start_line(199, "a", version::http_1_1);
- check(res, status::unknown, 199, "a", version::http_1_1);
-
- res.set_start_line(199, "abcdefghijklmnopqrstuvwxyz", version::http_1_1);
- check(res, status::unknown, 199, "abcdefghijklmnopqrstuvwxyz", version::http_1_1);
- }
- {
- core::string_view s =
- "HTTP/1.1 200 OK\r\n"
- "Server: test\r\n"
- "Content-Length: 0\r\n"
- "\r\n";
- static_response<128> r(s);
- response_view rv = r;
- static_response<128> res(rv);
- check(res, status::ok, 200, "OK", version::http_1_1);
- BOOST_TEST(res.size() == 2);
- auto it = res.begin();
- BOOST_TEST_EQ(it->id, field::server);
- BOOST_TEST_EQ(it->name, "Server");
- BOOST_TEST_EQ(it->value, "test");
- ++it;
- BOOST_TEST_EQ(it->id, field::content_length);
- BOOST_TEST_EQ(it->name, "Content-Length");
- BOOST_TEST_EQ(it->value, "0");
- }
- }
}
void
- testInitialSize()
+ testCapacity()
{
- static_response<32> f;
+ char buf[32];
+ static_response f(buf, sizeof(buf));
BOOST_TEST_THROWS(
f.append(field::host, "www.google.com"),
std::length_error);
+ BOOST_TEST_EQ(
+ f.capacity_in_bytes(), 32);
BOOST_TEST_EQ(
f.max_capacity_in_bytes(), 32);
}
@@ -279,8 +97,7 @@ class static_response_test
run()
{
testSpecial();
- testModifiers();
- testInitialSize();
+ testCapacity();
}
};
diff --git a/test/unit/test_helpers.cpp b/test/unit/test_helpers.cpp
index 1f2894f9..6b2e822c 100644
--- a/test/unit/test_helpers.cpp
+++ b/test/unit/test_helpers.cpp
@@ -17,7 +17,7 @@ namespace http_proto {
void
test_fields(
- fields_view_base const& f,
+ fields_base const& f,
core::string_view match)
{
fields r(match);
diff --git a/test/unit/test_helpers.hpp b/test/unit/test_helpers.hpp
index f7a99618..a4a9c7c5 100644
--- a/test/unit/test_helpers.hpp
+++ b/test/unit/test_helpers.hpp
@@ -52,7 +52,7 @@ test_to_string(Buffers const& bs)
// Test that fields equals HTTP string
void
test_fields(
- fields_view_base const& f,
+ fields_base const& f,
core::string_view match);
//------------------------------------------------