Bug 1697421 - improve parsing of content-type headers for fetch r=necko-reviewers,valentin
Differential Revision: https://phabricator.services.mozilla.com/D157115
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include "nsProxyRelease.h"
|
||||
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/MimeType.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/dom/BodyConsumer.h"
|
||||
#include "mozilla/dom/Exceptions.h"
|
||||
@@ -1259,20 +1260,40 @@ template already_AddRefed<Promise> FetchBody<EmptyBody>::ConsumeBody(
|
||||
template <class Derived>
|
||||
void FetchBody<Derived>::GetMimeType(nsACString& aMimeType,
|
||||
nsACString& aMixedCaseMimeType) {
|
||||
// Extract mime type.
|
||||
ErrorResult result;
|
||||
nsCString contentTypeValues;
|
||||
nsAutoCString contentTypeValues, contentTypeUtf8;
|
||||
MOZ_ASSERT(DerivedClass()->GetInternalHeaders());
|
||||
DerivedClass()->GetInternalHeaders()->Get("Content-Type"_ns,
|
||||
contentTypeValues, result);
|
||||
MOZ_ALWAYS_TRUE(!result.Failed());
|
||||
|
||||
// HTTP ABNF states Content-Type may have only one value.
|
||||
// This is from the "parse a header value" of the fetch spec.
|
||||
if (!contentTypeValues.IsVoid() && contentTypeValues.Find(",") == -1) {
|
||||
// Convert from a bytestring to a UTF8 CString.
|
||||
CopyLatin1toUTF8(contentTypeValues, aMimeType);
|
||||
aMixedCaseMimeType = aMimeType;
|
||||
nsCCharSeparatedTokenizer contentTypeTokens(contentTypeValues, ',');
|
||||
|
||||
// currently we extract the MIME-type from the first content type header
|
||||
// In order to fully comply with the fetch spec we must be able to
|
||||
// parse multiple content-type headers and extrace headers from it
|
||||
// To achieve this we need to modify CMimeType::Parse and implement the
|
||||
// algorithm https://fetch.spec.whatwg.org/#concept-header-extract-mime-type
|
||||
// This issue is tracked by
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1510180
|
||||
auto contentStr = contentTypeTokens.nextToken();
|
||||
|
||||
CopyLatin1toUTF8(contentStr, contentTypeUtf8);
|
||||
UniquePtr<CMimeType> contentTypeRecord = CMimeType::Parse(contentTypeUtf8);
|
||||
if (contentTypeRecord) {
|
||||
contentTypeRecord->Serialize(aMixedCaseMimeType);
|
||||
// validate invalid/empty parameter checks
|
||||
// according to https://mimesniff.spec.whatwg.org/#parsing-a-mime-type
|
||||
// CMimeType::Parse parses the parameters and discards ill-formed parameters
|
||||
// If we have invalid/illformed paramters we need to discard the parsed
|
||||
// mime-type
|
||||
if (contentStr.Contains(';') && !aMixedCaseMimeType.Contains(';')) {
|
||||
// parameters were discarded after parsing.
|
||||
// This should result in invalid MimeType
|
||||
aMixedCaseMimeType = "";
|
||||
}
|
||||
|
||||
aMimeType = aMixedCaseMimeType;
|
||||
ToLowerCase(aMimeType);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,6 @@
|
||||
[Request: combined response Content-Type: */* text/html]
|
||||
expected: FAIL
|
||||
|
||||
[Response: combined response Content-Type: text/html */*]
|
||||
expected: FAIL
|
||||
|
||||
[fetch(): separate response Content-Type: */* text/html]
|
||||
expected: FAIL
|
||||
|
||||
@@ -23,9 +20,6 @@
|
||||
[fetch(): combined response Content-Type: */* text/html]
|
||||
expected: FAIL
|
||||
|
||||
[Request: combined response Content-Type: text/html */*]
|
||||
expected: FAIL
|
||||
|
||||
[Request: combined response Content-Type: text/plain;charset=gbk text/plain;charset=windows-1252]
|
||||
expected: FAIL
|
||||
|
||||
@@ -50,24 +44,12 @@
|
||||
[<iframe>: separate response Content-Type: text/plain;charset=gbk text/html]
|
||||
expected: FAIL
|
||||
|
||||
[fetch(): combined response Content-Type: text/html */*;charset=gbk]
|
||||
expected: FAIL
|
||||
|
||||
[fetch(): combined response Content-Type: text/plain;charset=gbk text/plain]
|
||||
expected: FAIL
|
||||
|
||||
[Request: combined response Content-Type: text/html text/plain]
|
||||
expected: FAIL
|
||||
|
||||
[Request: combined response Content-Type: text/plain */*]
|
||||
expected: FAIL
|
||||
|
||||
[fetch(): separate response Content-Type: text/html;charset=gbk text/plain text/html]
|
||||
expected: FAIL
|
||||
|
||||
[Request: combined response Content-Type: text/plain;charset=gbk text/plain]
|
||||
expected: FAIL
|
||||
|
||||
[fetch(): combined response Content-Type: text/plain;charset=gbk text/html]
|
||||
expected: FAIL
|
||||
|
||||
@@ -86,18 +68,9 @@
|
||||
[Request: combined response Content-Type: text/html;x=" text/plain]
|
||||
expected: FAIL
|
||||
|
||||
[Response: combined response Content-Type: text/plain */*]
|
||||
expected: FAIL
|
||||
|
||||
[Request: combined response Content-Type: text/html */*;charset=gbk]
|
||||
expected: FAIL
|
||||
|
||||
[Response: combined response Content-Type: text/html;x=" text/plain]
|
||||
expected: FAIL
|
||||
|
||||
[fetch(): combined response Content-Type: text/html */*]
|
||||
expected: FAIL
|
||||
|
||||
[Response: combined response Content-Type: text/html;" text/plain]
|
||||
expected: FAIL
|
||||
|
||||
@@ -131,45 +104,21 @@
|
||||
[fetch(): combined response Content-Type: text/html;charset=gbk text/html;x=",text/plain]
|
||||
expected: FAIL
|
||||
|
||||
[fetch(): combined response Content-Type: text/plain */*]
|
||||
expected: FAIL
|
||||
|
||||
[Request: combined response Content-Type: text/plain */*;charset=gbk]
|
||||
expected: FAIL
|
||||
|
||||
[fetch(): separate response Content-Type: text/plain;charset=gbk text/html;charset=windows-1254]
|
||||
expected: FAIL
|
||||
|
||||
[fetch(): combined response Content-Type: text/plain */*;charset=gbk]
|
||||
expected: FAIL
|
||||
|
||||
[fetch(): combined response Content-Type: text/plain;charset=gbk text/plain;charset=windows-1252]
|
||||
expected: FAIL
|
||||
|
||||
[Response: combined response Content-Type: text/plain;charset=gbk text/plain]
|
||||
expected: FAIL
|
||||
|
||||
[fetch(): separate response Content-Type: text/html text/plain]
|
||||
expected: FAIL
|
||||
|
||||
[Request: combined response Content-Type: text/html;" text/plain]
|
||||
expected: FAIL
|
||||
|
||||
[Response: combined response Content-Type: text/plain */*;charset=gbk]
|
||||
expected: FAIL
|
||||
|
||||
[Request: combined response Content-Type: text/html;charset=gbk text/html;x=",text/plain]
|
||||
expected: FAIL
|
||||
|
||||
[Response: combined response Content-Type: text/html */*;charset=gbk]
|
||||
expected: FAIL
|
||||
|
||||
[fetch(): combined response Content-Type: text/plain ]
|
||||
expected: FAIL
|
||||
|
||||
[Response: combined response Content-Type: text/plain ]
|
||||
expected: FAIL
|
||||
|
||||
[fetch(): separate response Content-Type: text/plain]
|
||||
expected: FAIL
|
||||
|
||||
@@ -182,9 +131,6 @@
|
||||
[fetch(): combined response Content-Type: text/plain]
|
||||
expected: FAIL
|
||||
|
||||
[Request: combined response Content-Type: text/plain ]
|
||||
expected: FAIL
|
||||
|
||||
[fetch(): separate response Content-Type: text/html;" \\" text/plain]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user