Fix content-type return behavior for */*
An HTTP header of Accepts: */* throws a big wrench into our
implementation for a couple reasons. First, because it's the default in
a lot of commonly-used libraries, and second, because clients use it
when they certainly don't mean what the specification says it should
mean "ie, I accept ANY type".
This commit tries to address some of that, by making an explicit option
for content-type="ANY" and pushes it to the individual callers to handle
explicitly as if it were yet another type. In most protocols, there's a
"most common" representation, so protocols are free to use that, or to
explicitly handle it, and require that the user be explicit.
Tested:
Redfish Protocol Validator no longer locks up. (TBD, getting bugs filed
with protocol validator for this missing Accepts header).
For ServiceRoot
GET /redfish/v1 Accepts: application/json - returns json
GET /redfish/v1 Accepts: */* - returns json
GET /redfish/v1 Accepts: text/html - returns html
GET /redfish/v1 no-accepts header - returns json
Redfish-service-validator passes.
Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: Iae6711ae587115d3e159a48a6fc46a903ed6c403
diff --git a/include/forward_unauthorized.hpp b/include/forward_unauthorized.hpp
index 75f2dae..2fc3ee4 100644
--- a/include/forward_unauthorized.hpp
+++ b/include/forward_unauthorized.hpp
@@ -14,8 +14,8 @@
{
// If it's a browser connecting, don't send the HTTP authenticate
// header, to avoid possible CSRF attacks with basic auth
- if (http_helpers::isContentTypeAllowed(accept,
- http_helpers::ContentType::HTML))
+ if (http_helpers::isContentTypeAllowed(
+ accept, http_helpers::ContentType::HTML, false /*allowWildcard*/))
{
// If we have a webui installed, redirect to that login page
if (hasWebuiRoute)
diff --git a/include/http_utility.hpp b/include/http_utility.hpp
index f091760..cd1be3e 100644
--- a/include/http_utility.hpp
+++ b/include/http_utility.hpp
@@ -21,6 +21,7 @@
enum class ContentType
{
NoMatch,
+ ANY, // Accepts: */*
CBOR,
HTML,
JSON,
@@ -70,10 +71,7 @@
// servers list
if (encoding == "*/*")
{
- if (!preferedOrder.empty())
- {
- return preferedOrder[0];
- }
+ return ContentType::ANY;
}
const auto* knownContentType =
std::find_if(contentTypes.begin(), contentTypes.end(),
@@ -98,10 +96,17 @@
return ContentType::NoMatch;
}
-inline bool isContentTypeAllowed(std::string_view header, ContentType type)
+inline bool isContentTypeAllowed(std::string_view header, ContentType type,
+ bool allowWildcard)
{
auto types = std::to_array({type});
- return getPreferedContentType(header, types) == type;
+ ContentType allowed = getPreferedContentType(header, types);
+ if (allowed == ContentType::ANY)
+ {
+ return allowWildcard;
+ }
+
+ return type == allowed;
}
inline std::string urlEncode(const std::string_view value)