mirror of
https://github.com/matrix-construct/construct
synced 2024-12-26 15:33:54 +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 writeline(window_buffer &, const window_buffer::closure &);
|
||||||
void write(window_buffer &, const header &);
|
void write(window_buffer &, const header &);
|
||||||
void write(window_buffer &, const vector_view<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> &);
|
size_t serialized(const vector_view<const header> &);
|
||||||
std::string strung(const vector_view<const header> &);
|
std::string strung(const vector_view<const header> &);
|
||||||
void writechunk(window_buffer &, const uint32_t &size);
|
void writechunk(window_buffer &, const uint32_t &size);
|
||||||
const_buffer writechunk(const mutable_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.
|
/// 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 iless(first, s); }
|
||||||
bool operator==(const string_view &s) const { return iequals(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;
|
using std::pair<string_view, string_view>::pair;
|
||||||
header(const line &);
|
header(const line &);
|
||||||
|
@ -174,8 +176,20 @@ struct ircd::http::headers
|
||||||
:string_view
|
:string_view
|
||||||
{
|
{
|
||||||
using closure = std::function<void (const header &)>;
|
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(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.
|
/// 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);
|
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,
|
ircd::http::headers::headers(parse::capstan &pc,
|
||||||
const closure &c)
|
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{[&pc, &c]
|
||||||
() -> string_view
|
() -> string_view
|
||||||
{
|
{
|
||||||
header h{pc};
|
header h{pc};
|
||||||
const char *const &started{h.first.data()}, *stopped{started};
|
const char *const &started{h.first.data()}, *stopped{started};
|
||||||
for(; !h.first.empty(); stopped = h.second.data() + h.second.size(), h = header{pc})
|
for(; !h.first.empty(); stopped = h.second.data() + h.second.size(), h = header{pc})
|
||||||
if(c)
|
if(c && !c(h))
|
||||||
c(h);
|
c = {};
|
||||||
|
|
||||||
return { started, stopped };
|
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)
|
ircd::http::header::header(const line &line)
|
||||||
try
|
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
|
std::string
|
||||||
ircd::http::strung(const vector_view<const header> &headers)
|
ircd::http::strung(const vector_view<const header> &headers)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue