0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-06-02 18:18:56 +02:00

ircd::http: Minor cleanup/reorg; use c_str() assertion in places.

This commit is contained in:
Jason Volk 2017-12-12 13:38:16 -07:00
parent b167ed217c
commit ada2b4ad17
2 changed files with 104 additions and 114 deletions

View file

@ -247,6 +247,63 @@ struct ircd::http::content
content() = default;
};
/// HTTP request suite. Functionality to send and receive requests.
///
struct ircd::http::request
{
struct head;
struct content;
using write_closure = std::function<void (const ilist<const_buffer> &)>;
using proffer = std::function<void (const head &)>;
using header = line::header;
request(const string_view &host = {},
const string_view &method = "GET",
const string_view &path = "/",
const string_view &query = {},
const string_view &content = {},
const write_closure & = nullptr,
const vector_view<const header> & = {});
request(parse::capstan &,
content *const & = nullptr,
const write_closure & = nullptr,
const proffer & = nullptr,
const headers::closure & = {});
};
/// Represents an HTTP request head. This is only for receiving requests.
///
struct ircd::http::request::head
:line::request
{
string_view host;
string_view expect;
string_view te;
string_view authorization;
string_view connection;
size_t content_length {0};
string_view headers;
head(parse::capstan &pc, const headers::closure &c = {});
};
/// Represents an HTTP request content. This is only for receiving content.
///
struct ircd::http::request::content
:http::content
{
content(parse::capstan &pc, const head &h, discard_t)
:http::content{pc, h.content_length, discard}
{}
content(parse::capstan &pc, const head &h)
:http::content{pc, h.content_length}
{}
};
/// HTTP response suite. Functionality to send and receive responses.
///
struct ircd::http::response
@ -324,60 +381,3 @@ struct ircd::http::response::content
content() = default;
};
/// HTTP request suite. Functionality to send and receive requests.
///
struct ircd::http::request
{
struct head;
struct content;
using write_closure = std::function<void (const ilist<const_buffer> &)>;
using proffer = std::function<void (const head &)>;
using header = line::header;
request(const string_view &host = {},
const string_view &method = "GET",
const string_view &path = "/",
const string_view &query = {},
const string_view &content = {},
const write_closure & = nullptr,
const vector_view<const header> & = {});
request(parse::capstan &,
content *const & = nullptr,
const write_closure & = nullptr,
const proffer & = nullptr,
const headers::closure & = {});
};
/// Represents an HTTP request head. This is only for receiving requests.
///
struct ircd::http::request::head
:line::request
{
string_view host;
string_view expect;
string_view te;
string_view authorization;
string_view connection;
size_t content_length {0};
string_view headers;
head(parse::capstan &pc, const headers::closure &c = {});
};
/// Represents an HTTP request content. This is only for receiving content.
///
struct ircd::http::request::content
:http::content
{
content(parse::capstan &pc, const head &h, discard_t)
:http::content{pc, h.content_length, discard}
{}
content(parse::capstan &pc, const head &h)
:http::content{pc, h.content_length}
{}
};

View file

@ -54,6 +54,38 @@ namespace ircd::http
extern const std::unordered_map<ircd::http::code, ircd::string_view> reason;
}
BOOST_FUSION_ADAPT_STRUCT
(
ircd::http::line::request,
( decltype(ircd::http::line::request::method), method )
( decltype(ircd::http::line::request::path), path )
( decltype(ircd::http::line::request::query), query )
( decltype(ircd::http::line::request::fragment), fragment )
( decltype(ircd::http::line::request::version), version )
)
BOOST_FUSION_ADAPT_STRUCT
(
ircd::http::line::response,
( decltype(ircd::http::line::response::version), version )
( decltype(ircd::http::line::response::status), status )
( decltype(ircd::http::line::response::reason), reason )
)
BOOST_FUSION_ADAPT_STRUCT
(
ircd::http::line::header,
( decltype(ircd::http::line::header::first), first )
( decltype(ircd::http::line::header::second), second )
)
BOOST_FUSION_ADAPT_STRUCT
(
ircd::http::query,
( decltype(ircd::http::query::first), first )
( decltype(ircd::http::query::second), second )
)
const decltype(ircd::http::reason) ircd::http::reason
{
{ code::CONTINUE, "Continue" },
@ -95,38 +127,6 @@ const decltype(ircd::http::reason) ircd::http::reason
{ code::INSUFFICIENT_STORAGE, "Insufficient Storage" },
};
BOOST_FUSION_ADAPT_STRUCT
(
ircd::http::line::request,
( decltype(ircd::http::line::request::method), method )
( decltype(ircd::http::line::request::path), path )
( decltype(ircd::http::line::request::query), query )
( decltype(ircd::http::line::request::fragment), fragment )
( decltype(ircd::http::line::request::version), version )
)
BOOST_FUSION_ADAPT_STRUCT
(
ircd::http::line::response,
( decltype(ircd::http::line::response::version), version )
( decltype(ircd::http::line::response::status), status )
( decltype(ircd::http::line::response::reason), reason )
)
BOOST_FUSION_ADAPT_STRUCT
(
ircd::http::line::header,
( decltype(ircd::http::line::header::first), first )
( decltype(ircd::http::line::header::second), second )
)
BOOST_FUSION_ADAPT_STRUCT
(
ircd::http::query,
( decltype(ircd::http::query::first), first )
( decltype(ircd::http::query::second), second )
)
template<class it,
class top>
struct ircd::http::grammar
@ -171,17 +171,17 @@ struct ircd::http::grammar
rule<string_view> query_key { raw[+(char_ - query_illegal)] ,"query key" };
rule<string_view> query_val { raw[*(char_ - query_illegal)] ,"query value" };
rule<string_view> method { token ,"method" };
rule<string_view> path { raw[-slash >> *(char_ - query_illegal)] ,"path" };
rule<string_view> fragment { pound >> -token ,"fragment" };
rule<string_view> version { token ,"version" };
rule<size_t> chunk_size
{
qi::uint_parser<size_t, 16, 1, 8>{} >> CRLF
,"chunk size"
};
rule<string_view> method { token ,"method" };
rule<string_view> path { raw[-slash >> *(char_ - query_illegal)] ,"path" };
rule<string_view> fragment { pound >> -token ,"fragment" };
rule<string_view> version { token ,"version" };
rule<http::query> query
{
query_key >> -(equal >> query_val)
@ -321,17 +321,17 @@ ircd::http::request::request(const string_view &host,
char request_line[2048]; const auto request_line_len
{
snprintf(request_line, sizeof(request_line), "%s /%s%s%s %s\r\n",
method.data(),
path.data(),
method.c_str(),
path.c_str(),
query.empty()? "" : "?",
query.empty()? "" : query.data(),
query.empty()? "" : query.c_str(),
version)
};
char host_line[128] {"Host: "}; const auto host_line_len
{
6 + snprintf(host_line + 6, std::min(sizeof(host_line) - 6, host.size() + 3), "%s\r\n",
host.data())
host.c_str())
};
char content_len[64]; const auto content_len_len
@ -431,22 +431,12 @@ ircd::http::response::response(const code &code,
0
};
fixed_buffer<mutable_buffer, 128> date_line_buf;
const string_view date_line
char date_line[128], date_buf[96]; const auto date_line_len
{
[&date_line_buf, &code]() -> string_view
{
if(code >= 400)
return {};
fixed_buffer<mutable_buffer, 128> date_buf;
const auto datestr{timef(date_buf, ircd::localtime)};
date_buf[std::min(date_buf.size() - 1, datestr.size())] = '\0';
const mutable_buffer line{date_line_buf};
const auto length{snprintf(data(line), size(line), "Date: %s\r\n", datestr.data())};
return { data(line), size_t(length) };
}()
code < 400?
snprintf(data(date_line), size(date_line), "Date: %s\r\n",
timef(date_buf, ircd::localtime).c_str()):
0
};
char cache_line[64]; const auto cache_line_len
@ -489,7 +479,7 @@ ircd::http::response::response(const code &code,
{
{ status_line, size_t(status_line_len) },
{ server_line, size_t(server_line_len) },
{ date_line },
{ date_line, size_t(date_line_len) },
{ cache_line, size_t(cache_line_len) },
{ user_headers, size_t(user_headers_len) },
{ content_len, size_t(content_len_len) },