diff --git a/dom/fetch/Fetch.cpp b/dom/fetch/Fetch.cpp index e2775159f045..51f74798e927 100644 --- a/dom/fetch/Fetch.cpp +++ b/dom/fetch/Fetch.cpp @@ -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 FetchBody::ConsumeBody( template void FetchBody::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 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); } } diff --git a/testing/web-platform/meta/fetch/content-type/response.window.js.ini b/testing/web-platform/meta/fetch/content-type/response.window.js.ini index 285b87544be3..d5ddba1a3adc 100644 --- a/testing/web-platform/meta/fetch/content-type/response.window.js.ini +++ b/testing/web-platform/meta/fetch/content-type/response.window.js.ini @@ -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 @@ [