-
Notifications
You must be signed in to change notification settings - Fork 63
Closed
Description
The new 5.6.0 version has some degradation in dealing with the accepted content type, when followSpec == true (sorry for that, I've missed all these cases myself):
- Running
dotnet graphql update -u http://localhost:5656/graphql(see here: https://chillicream.com/docs/strawberryshake/v13/tooling), sets a single accepted content type (i.e..Count == 1), but it's actually multiple values, comma separated. In other words,context.Request.Headers.Accept == "application/graphql-response+json, application/json, text/event-stream"
So it should be split, and each sub-string should be checked. - Postman with introspection sends this accepted content type:
*/*(indicating all media types). That also isn't accepted well, and 406 is received.
I've solved it locally with:
var acceptedContentType = context.Request.Headers.Accept;
if (followSpec)
{
if (acceptedContentType.Count > 0 && acceptedContentType.Any(ct => ct == "*/*"))
{
acceptedContentType = $"{APP_GQL_TYPE_START}";
}
// https://github.com/graphql/graphql-over-http/blob/main/spec/GraphQLOverHTTP.md
// "May reply with error if not supplied" choosing not to
else if (
acceptedContentType.Count > 0 // each accept header can have multiple values, comma separated
&& !acceptedContentType.Any(ct =>
ct is not null && ct.Split(",",
StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)
.Any(h => h.StartsWith(APP_JSON_TYPE_START, StringComparison.InvariantCulture)))
&& !acceptedContentType.Any(ct => ct is not null && ct
.Split(",", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).Any(h =>
h.StartsWith(APP_GQL_TYPE_START, StringComparison.InvariantCulture)))
)
{
context.Response.StatusCode = StatusCodes.Status406NotAcceptable;
return;
}
}then:
if (followSpec)
{
var requestedType = acceptedContentType.FirstOrDefault(ct =>
ct?.Split(",", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)
.FirstOrDefault(t =>
t.StartsWith(APP_JSON_TYPE_START, StringComparison.InvariantCulture) ||
t.StartsWith(APP_GQL_TYPE_START, StringComparison.InvariantCulture)) != null
);
requestedType = requestedType?.Split(",",
StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)
.FirstOrDefault(t =>
t.StartsWith(APP_JSON_TYPE_START, StringComparison.InvariantCulture) ||
t.StartsWith(APP_GQL_TYPE_START, StringComparison.InvariantCulture));
context.Response.ContentType = requestedType ?? $"{APP_GQL_TYPE_START}; charset=utf-8";
}
else
{
context.Response.ContentType = $"{APP_JSON_TYPE_START}; charset=utf-8";
}I'm sure the above can be prettified, but in general, I'm checking if any of the received accepted content-type headers (so far, only one has been received) is */*. If yes, I use application/graphql-response+json, hopefully, that's generally correct. If not, I'm checking each one (again, so far, only one is received in my setup), splitting it by ",", removing spaces, and then I do the original logic on each sub-section.
Metadata
Metadata
Assignees
Labels
No labels