0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2025-01-12 16:03:55 +01:00

ircd::resource: Split mime and content length nego branches into functions.

This commit is contained in:
Jason Volk 2020-06-08 14:59:12 -07:00
parent ee4d64ff28
commit 84491464d6
2 changed files with 56 additions and 21 deletions

View file

@ -29,6 +29,9 @@ struct ircd::resource::method
std::unique_ptr<struct stats> stats;
unique_const_iterator<decltype(resource::methods)> methods_it;
bool content_length_acceptable(const http::request::head &) const;
bool mime_type_acceptable(const http::request::head &) const;
void handle_timeout(client &) const;
response call_handler(client &, request &);

View file

@ -447,15 +447,8 @@ try
stats->pending
};
const auto &method_payload_max
{
opts->payload_max != -1UL?
opts->payload_max:
size_t(default_payload_max)
};
// Bail out if the method limited the amount of content and it was exceeded.
if(head.content_length > method_payload_max)
if(!content_length_acceptable(head))
throw http::error
{
http::PAYLOAD_TOO_LARGE
@ -463,19 +456,11 @@ try
// Check if the resource method wants a specific MIME type. If no option
// is given by the resource then any Content-Type by the client will pass.
if(opts->mime.first)
{
const auto &ct(split(head.content_type, ';'));
const auto &supplied(split(ct.first, '/'));
const auto &charset(ct.second);
const auto &required(opts->mime);
if(required.first != supplied.first
||(required.second && required.second != supplied.second))
throw http::error
{
http::UNSUPPORTED_MEDIA_TYPE
};
}
if(!mime_type_acceptable(head))
throw http::error
{
http::UNSUPPORTED_MEDIA_TYPE
};
// This timer will keep the request from hanging forever for whatever
// reason. The resource method may want to do its own timing and can
@ -651,6 +636,53 @@ const
client.close(net::dc::RST, net::close_ignore);
}
bool
ircd::resource::method::mime_type_acceptable(const http::request::head &head)
const
{
assert(opts);
const auto &[required_registry, required_format]
{
opts->mime
};
const auto &[supplied, charset]
{
split(head.content_type, ';')
};
const auto &[supplied_registry, supplied_format]
{
split(supplied, '/')
};
const bool match[]
{
!required_registry || iequals(required_registry, supplied_registry),
!required_format || iequals(required_format, supplied_format),
};
return all(match);
}
bool
ircd::resource::method::content_length_acceptable(const http::request::head &head)
const
{
assert(opts);
assert(opts->payload_max != 0UL);
const auto &payload_max
{
opts->payload_max != -1UL?
opts->payload_max:
size_t(default_payload_max)
};
return head.content_length <= payload_max;
}
///////////////////////////////////////////////////////////////////////////////
//
// resource/response.h