diff --git a/include/ircd/resource.h b/include/ircd/resource.h index 12283e036..96061c50f 100644 --- a/include/ircd/resource.h +++ b/include/ircd/resource.h @@ -194,6 +194,9 @@ struct ircd::resource::method /// larger will be summarily rejected with a 413. size_t payload_max {128_KiB}; + /// MIME type; first part is the Registry (i.e application) and second + /// part is the format (i.e json). Empty value means nothing rejected. + std::pair mime; }; string_view name; diff --git a/ircd/resource.cc b/ircd/resource.cc index 0448e4300..b278cace3 100644 --- a/ircd/resource.cc +++ b/ircd/resource.cc @@ -278,6 +278,22 @@ ircd::resource::operator()(client &client, http::PAYLOAD_TOO_LARGE }; + // 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(method.opts.mime.first) + { + const auto &ct(split(head.content_type, ';')); + const auto &supplied(split(ct.first, '/')); + const auto &charset(ct.second); + const auto &required(method.opts.mime); + if(required.first != supplied.first || + (required.second && required.second != supplied.second)) + 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 // disable this in its options structure.