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 "nsProxyRelease.h"
|
||||||
|
|
||||||
#include "mozilla/ErrorResult.h"
|
#include "mozilla/ErrorResult.h"
|
||||||
|
#include "mozilla/dom/MimeType.h"
|
||||||
#include "mozilla/dom/BindingDeclarations.h"
|
#include "mozilla/dom/BindingDeclarations.h"
|
||||||
#include "mozilla/dom/BodyConsumer.h"
|
#include "mozilla/dom/BodyConsumer.h"
|
||||||
#include "mozilla/dom/Exceptions.h"
|
#include "mozilla/dom/Exceptions.h"
|
||||||
@@ -1259,20 +1260,40 @@ template already_AddRefed<Promise> FetchBody<EmptyBody>::ConsumeBody(
|
|||||||
template <class Derived>
|
template <class Derived>
|
||||||
void FetchBody<Derived>::GetMimeType(nsACString& aMimeType,
|
void FetchBody<Derived>::GetMimeType(nsACString& aMimeType,
|
||||||
nsACString& aMixedCaseMimeType) {
|
nsACString& aMixedCaseMimeType) {
|
||||||
// Extract mime type.
|
|
||||||
ErrorResult result;
|
ErrorResult result;
|
||||||
nsCString contentTypeValues;
|
nsAutoCString contentTypeValues, contentTypeUtf8;
|
||||||
MOZ_ASSERT(DerivedClass()->GetInternalHeaders());
|
MOZ_ASSERT(DerivedClass()->GetInternalHeaders());
|
||||||
DerivedClass()->GetInternalHeaders()->Get("Content-Type"_ns,
|
DerivedClass()->GetInternalHeaders()->Get("Content-Type"_ns,
|
||||||
contentTypeValues, result);
|
contentTypeValues, result);
|
||||||
MOZ_ALWAYS_TRUE(!result.Failed());
|
MOZ_ALWAYS_TRUE(!result.Failed());
|
||||||
|
|
||||||
// HTTP ABNF states Content-Type may have only one value.
|
nsCCharSeparatedTokenizer contentTypeTokens(contentTypeValues, ',');
|
||||||
// This is from the "parse a header value" of the fetch spec.
|
|
||||||
if (!contentTypeValues.IsVoid() && contentTypeValues.Find(",") == -1) {
|
// currently we extract the MIME-type from the first content type header
|
||||||
// Convert from a bytestring to a UTF8 CString.
|
// In order to fully comply with the fetch spec we must be able to
|
||||||
CopyLatin1toUTF8(contentTypeValues, aMimeType);
|
// parse multiple content-type headers and extrace headers from it
|
||||||
aMixedCaseMimeType = aMimeType;
|
// 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);
|
ToLowerCase(aMimeType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,6 @@
|
|||||||
[Request: combined response Content-Type: */* text/html]
|
[Request: combined response Content-Type: */* text/html]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Response: combined response Content-Type: text/html */*]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[fetch(): separate response Content-Type: */* text/html]
|
[fetch(): separate response Content-Type: */* text/html]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
@@ -23,9 +20,6 @@
|
|||||||
[fetch(): combined response Content-Type: */* text/html]
|
[fetch(): combined response Content-Type: */* text/html]
|
||||||
expected: FAIL
|
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]
|
[Request: combined response Content-Type: text/plain;charset=gbk text/plain;charset=windows-1252]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
@@ -50,24 +44,12 @@
|
|||||||
[<iframe>: separate response Content-Type: text/plain;charset=gbk text/html]
|
[<iframe>: separate response Content-Type: text/plain;charset=gbk text/html]
|
||||||
expected: FAIL
|
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]
|
[Request: combined response Content-Type: text/html text/plain]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Request: combined response Content-Type: text/plain */*]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[fetch(): separate response Content-Type: text/html;charset=gbk text/plain text/html]
|
[fetch(): separate response Content-Type: text/html;charset=gbk text/plain text/html]
|
||||||
expected: FAIL
|
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]
|
[fetch(): combined response Content-Type: text/plain;charset=gbk text/html]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
@@ -86,18 +68,9 @@
|
|||||||
[Request: combined response Content-Type: text/html;x=" text/plain]
|
[Request: combined response Content-Type: text/html;x=" text/plain]
|
||||||
expected: FAIL
|
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]
|
[Response: combined response Content-Type: text/html;x=" text/plain]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[fetch(): combined response Content-Type: text/html */*]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[Response: combined response Content-Type: text/html;" text/plain]
|
[Response: combined response Content-Type: text/html;" text/plain]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
@@ -131,45 +104,21 @@
|
|||||||
[fetch(): combined response Content-Type: text/html;charset=gbk text/html;x=",text/plain]
|
[fetch(): combined response Content-Type: text/html;charset=gbk text/html;x=",text/plain]
|
||||||
expected: FAIL
|
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]
|
[fetch(): separate response Content-Type: text/plain;charset=gbk text/html;charset=windows-1254]
|
||||||
expected: FAIL
|
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]
|
[fetch(): combined response Content-Type: text/plain;charset=gbk text/plain;charset=windows-1252]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Response: combined response Content-Type: text/plain;charset=gbk text/plain]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[fetch(): separate response Content-Type: text/html text/plain]
|
[fetch(): separate response Content-Type: text/html text/plain]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Request: combined response Content-Type: text/html;" text/plain]
|
[Request: combined response Content-Type: text/html;" text/plain]
|
||||||
expected: FAIL
|
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]
|
[Request: combined response Content-Type: text/html;charset=gbk text/html;x=",text/plain]
|
||||||
expected: FAIL
|
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]
|
[fetch(): separate response Content-Type: text/plain]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
@@ -182,9 +131,6 @@
|
|||||||
[fetch(): combined response Content-Type: text/plain]
|
[fetch(): combined response Content-Type: text/plain]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Request: combined response Content-Type: text/plain ]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[fetch(): separate response Content-Type: text/html;" \\" text/plain]
|
[fetch(): separate response Content-Type: text/html;" \\" text/plain]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user