mirror of
https://github.com/matrix-construct/construct
synced 2024-12-25 23:14:13 +01:00
ircd::http: Add more functionality to headers class.
This commit is contained in:
parent
27bd661e5a
commit
57079c0276
2 changed files with 125 additions and 14 deletions
|
@ -30,11 +30,12 @@ namespace ircd::http
|
|||
void writeline(window_buffer &, const window_buffer::closure &);
|
||||
void write(window_buffer &, const header &);
|
||||
void write(window_buffer &, const vector_view<const header> &);
|
||||
bool has(const vector_view<const header> &, const string_view &key);
|
||||
size_t serialized(const vector_view<const header> &);
|
||||
std::string strung(const vector_view<const header> &);
|
||||
void writechunk(window_buffer &, const uint32_t &size);
|
||||
const_buffer writechunk(const mutable_buffer &, const uint32_t &size);
|
||||
bool has(const headers &, const string_view &key);
|
||||
bool has(const vector_view<const header> &, const string_view &key);
|
||||
}
|
||||
|
||||
/// Root exception for HTTP.
|
||||
|
@ -158,6 +159,7 @@ struct ircd::http::header
|
|||
{
|
||||
bool operator<(const string_view &s) const { return iless(first, s); }
|
||||
bool operator==(const string_view &s) const { return iequals(first, s); }
|
||||
bool operator!=(const string_view &s) const { return !operator==(s); }
|
||||
|
||||
using std::pair<string_view, string_view>::pair;
|
||||
header(const line &);
|
||||
|
@ -174,8 +176,20 @@ struct ircd::http::headers
|
|||
:string_view
|
||||
{
|
||||
using closure = std::function<void (const header &)>;
|
||||
using closure_bool = std::function<bool (const header &)>;
|
||||
|
||||
bool for_each(const closure_bool &) const;
|
||||
string_view operator[](const string_view &key) const;
|
||||
string_view at(const string_view &key) const;
|
||||
bool has(const string_view &key) const;
|
||||
|
||||
using string_view::string_view;
|
||||
headers(parse::capstan &, closure_bool);
|
||||
headers(parse::capstan &, const closure & = {});
|
||||
headers() = default;
|
||||
|
||||
friend bool has(const headers &, const string_view &key);
|
||||
friend bool has(const vector_view<const header> &, const string_view &key);
|
||||
};
|
||||
|
||||
/// HTTP request suite. Functionality to send and receive requests.
|
||||
|
|
123
ircd/http.cc
123
ircd/http.cc
|
@ -428,22 +428,130 @@ catch(const qi::expectation_failure<const char *> &e)
|
|||
throw_error(e, true);
|
||||
}
|
||||
|
||||
//
|
||||
// headers
|
||||
//
|
||||
|
||||
bool
|
||||
ircd::http::has(const vector_view<const header> &headers,
|
||||
const string_view &key)
|
||||
{
|
||||
return end(headers) != std::find_if(begin(headers), end(headers), [&key]
|
||||
(const header &header)
|
||||
{
|
||||
return header == key;
|
||||
});
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::http::has(const headers &headers,
|
||||
const string_view &key)
|
||||
{
|
||||
return headers.has(key);
|
||||
}
|
||||
|
||||
//
|
||||
// headers::headers
|
||||
//
|
||||
|
||||
ircd::http::headers::headers(parse::capstan &pc,
|
||||
const closure &c)
|
||||
:headers
|
||||
{
|
||||
pc, closure_bool{[&c](const auto &header)
|
||||
{
|
||||
if(c)
|
||||
c(header);
|
||||
|
||||
return true;
|
||||
}}
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
ircd::http::headers::headers(parse::capstan &pc,
|
||||
closure_bool c)
|
||||
:string_view{[&pc, &c]
|
||||
() -> string_view
|
||||
{
|
||||
header h{pc};
|
||||
const char *const &started{h.first.data()}, *stopped{started};
|
||||
for(; !h.first.empty(); stopped = h.second.data() + h.second.size(), h = header{pc})
|
||||
if(c)
|
||||
c(h);
|
||||
if(c && !c(h))
|
||||
c = {};
|
||||
|
||||
return { started, stopped };
|
||||
}()}
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::http::headers::has(const string_view &key)
|
||||
const
|
||||
{
|
||||
// has header if break early from for_each
|
||||
return !for_each([&key]
|
||||
(const header &header)
|
||||
{
|
||||
// true to continue; false to break (for_each protocol)
|
||||
return header != key;
|
||||
});
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::http::headers::at(const string_view &key)
|
||||
const
|
||||
{
|
||||
const string_view ret
|
||||
{
|
||||
this->operator[](key)
|
||||
};
|
||||
|
||||
if(unlikely(!ret))
|
||||
throw std::out_of_range{key};
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ircd::string_view
|
||||
ircd::http::headers::operator[](const string_view &key)
|
||||
const
|
||||
{
|
||||
string_view ret;
|
||||
for_each([&key, &ret](const auto &header)
|
||||
{
|
||||
if(header == key)
|
||||
{
|
||||
ret = header.second;
|
||||
return false;
|
||||
}
|
||||
else return true;
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::http::headers::for_each(const closure_bool &closure)
|
||||
const
|
||||
{
|
||||
if(empty())
|
||||
return true;
|
||||
|
||||
parse::buffer pb{const_buffer{*this}};
|
||||
parse::capstan pc{pb};
|
||||
header h{pc};
|
||||
for(; !h.first.empty(); h = header{pc})
|
||||
if(!closure(h))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// header
|
||||
//
|
||||
|
||||
ircd::http::header::header(const line &line)
|
||||
try
|
||||
{
|
||||
|
@ -617,17 +725,6 @@ ircd::http::writechunk(window_buffer &buf,
|
|||
});
|
||||
}
|
||||
|
||||
bool
|
||||
ircd::http::has(const vector_view<const header> &headers,
|
||||
const string_view &key)
|
||||
{
|
||||
return end(headers) != std::find_if(begin(headers), end(headers), [&key]
|
||||
(const header &header)
|
||||
{
|
||||
return iequals(header.first, key);
|
||||
});
|
||||
}
|
||||
|
||||
std::string
|
||||
ircd::http::strung(const vector_view<const header> &headers)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue