Bug 1800443 - Support the contentType attribute of the Resource Timing API, and have it and the encoded/decoded body size use the CORS check rather than TAO; r=sefeng,valentin,webidl,necko-reviewers,saschanaz,emilio

Differential Revision: https://phabricator.services.mozilla.com/D208965
This commit is contained in:
Thomas Wisniewski
2024-06-13 13:46:05 +00:00
parent 3367c8c203
commit 35368d7f72
20 changed files with 306 additions and 208 deletions

View File

@@ -85,6 +85,8 @@ size_t PerformanceResourceTiming::SizeOfExcludingThis(
mozilla::MallocSizeOf aMallocSizeOf) const {
return PerformanceEntry::SizeOfExcludingThis(aMallocSizeOf) +
mInitiatorType.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
mTimingData->ContentType().SizeOfExcludingThisIfUnshared(
aMallocSizeOf) +
mTimingData->NextHopProtocol().SizeOfExcludingThisIfUnshared(
aMallocSizeOf);
}
@@ -109,6 +111,19 @@ void PerformanceResourceTiming::GetServerTiming(
}
}
nsITimedChannel::BodyInfoAccess
PerformanceResourceTiming::BodyInfoAccessAllowedForCaller(
nsIPrincipal& aCaller) const {
// If the addon has permission to access the cross-origin resource,
// allow it full access to the bodyInfo.
if (mOriginalURI &&
BasePrincipal::Cast(&aCaller)->AddonAllowsLoad(mOriginalURI)) {
return nsITimedChannel::BodyInfoAccess::ALLOW_ALL;
}
return mTimingData->BodyInfoAccessAllowed();
}
bool PerformanceResourceTiming::TimingAllowedForCaller(
nsIPrincipal& aCaller) const {
if (mTimingData->TimingAllowed()) {

View File

@@ -33,6 +33,16 @@ enum class RenderBlockingStatusType : uint8_t;
return allowed ? mTimingData->name() : 0; \
}
#define IMPL_RESOURCE_TIMING_CORS_PROTECTED_SIZE_PROP(name) \
uint64_t name(nsIPrincipal& aSubjectPrincipal) const { \
bool allowed = BodyInfoAccessAllowedForCaller(aSubjectPrincipal); \
if (!allowed && mTimingData->RedirectCountReal()) { \
ReportRedirectForCaller(aSubjectPrincipal, true); \
return 0; \
} \
return allowed ? mTimingData->name() : 0; \
}
// http://www.w3.org/TR/resource-timing/#performanceresourcetiming
class PerformanceResourceTiming : public PerformanceEntry {
public:
@@ -134,11 +144,38 @@ class PerformanceResourceTiming : public PerformanceEntry {
return this;
}
IMPL_RESOURCE_TIMING_TAO_PROTECTED_SIZE_PROP(TransferSize)
IMPL_RESOURCE_TIMING_CORS_PROTECTED_SIZE_PROP(EncodedBodySize);
IMPL_RESOURCE_TIMING_CORS_PROTECTED_SIZE_PROP(DecodedBodySize);
IMPL_RESOURCE_TIMING_TAO_PROTECTED_SIZE_PROP(EncodedBodySize)
uint64_t TransferSize(nsIPrincipal& aSubjectPrincipal) const {
const bool allowed =
!mTimingData->RedirectCountReal()
? TimingAllowedForCaller(aSubjectPrincipal)
: ReportRedirectForCaller(aSubjectPrincipal, false);
if (!allowed) {
return 0;
}
// Resource is cached.
if (!mTimingData->TransferSize()) {
return 0;
}
auto encodedBodySize = EncodedBodySize(aSubjectPrincipal);
// The constant number added to transferSize replaces exposing the
// total byte size of the HTTP headers, as that may expose the
// presence of certain cookies.
// https://github.com/w3c/resource-timing/issues/238
return encodedBodySize + 300;
}
IMPL_RESOURCE_TIMING_TAO_PROTECTED_SIZE_PROP(DecodedBodySize)
void GetContentType(nsAString& aContentType,
nsIPrincipal& aSubjectPrincipal) const {
if (BodyInfoAccessAllowedForCaller(aSubjectPrincipal) ==
nsITimedChannel::BodyInfoAccess::ALLOW_ALL) {
aContentType = mTimingData->ContentType();
} else if (mTimingData->RedirectCountReal()) {
ReportRedirectForCaller(aSubjectPrincipal, true);
}
}
void GetServerTiming(nsTArray<RefPtr<PerformanceServerTiming>>& aRetval,
nsIPrincipal& aSubjectPrincipal);
@@ -152,6 +189,10 @@ class PerformanceResourceTiming : public PerformanceEntry {
size_t SizeOfExcludingThis(
mozilla::MallocSizeOf aMallocSizeOf) const override;
// Check if caller has access to the bodyInfo of the request, per Fetch spec.
nsITimedChannel::BodyInfoAccess BodyInfoAccessAllowedForCaller(
nsIPrincipal& aCaller) const;
// Check if caller has access to cross-origin timings, either by the rules
// from the spec, or based on addon permissions.
bool TimingAllowedForCaller(nsIPrincipal& aCaller) const;

View File

@@ -239,9 +239,11 @@ PerformanceTimingData::PerformanceTimingData(
mRenderBlockingStatus(aIPCData.renderBlocking()
? RenderBlockingStatusType::Blocking
: RenderBlockingStatusType::Non_blocking),
mContentType(aIPCData.contentType()),
mAllRedirectsSameOrigin(aIPCData.allRedirectsSameOrigin()),
mAllRedirectsPassTAO(aIPCData.allRedirectsPassTAO()),
mSecureConnection(aIPCData.secureConnection()),
mBodyInfoAccessAllowed(aIPCData.bodyInfoAccessAllowed()),
mTimingAllowed(aIPCData.timingAllowed()),
mInitialized(aIPCData.initialized()) {
for (const auto& serverTimingData : aIPCData.serverTiming()) {
@@ -273,8 +275,9 @@ IPCPerformanceTimingData PerformanceTimingData::ToIPC() {
mCacheReadStart, mResponseEnd, mCacheReadEnd, mWorkerStart,
mWorkerRequestStart, mWorkerResponseEnd, mZeroTime, mFetchStart,
mEncodedBodySize, mTransferSize, mDecodedBodySize, mRedirectCount,
renderBlocking, mAllRedirectsSameOrigin, mAllRedirectsPassTAO,
mSecureConnection, mTimingAllowed, mInitialized);
renderBlocking, mContentType, mAllRedirectsSameOrigin,
mAllRedirectsPassTAO, mSecureConnection, mBodyInfoAccessAllowed,
mTimingAllowed, mInitialized);
}
void PerformanceTimingData::SetPropertiesFromHttpChannel(
@@ -292,7 +295,13 @@ void PerformanceTimingData::SetPropertiesFromHttpChannel(
mDecodedBodySize = mEncodedBodySize;
}
mTimingAllowed = CheckAllowedOrigin(aHttpChannel, aChannel);
nsAutoCString contentType;
Unused << aHttpChannel->GetContentType(contentType);
CopyUTF8toUTF16(contentType, mContentType);
mBodyInfoAccessAllowed =
CheckBodyInfoAccessAllowedForOrigin(aHttpChannel, aChannel);
mTimingAllowed = CheckTimingAllowedForOrigin(aHttpChannel, aChannel);
aChannel->GetAllRedirectsPassTimingAllowCheck(&mAllRedirectsPassTAO);
aChannel->GetNativeServerTiming(mServerTiming);
@@ -328,13 +337,46 @@ DOMTimeMilliSec PerformanceTiming::FetchStart() {
return static_cast<int64_t>(mTimingData->FetchStartHighRes(mPerformance));
}
bool PerformanceTimingData::CheckAllowedOrigin(nsIHttpChannel* aResourceChannel,
nsITimedChannel* aChannel) {
nsITimedChannel::BodyInfoAccess
PerformanceTimingData::CheckBodyInfoAccessAllowedForOrigin(
nsIHttpChannel* aResourceChannel, nsITimedChannel* aChannel) {
// Check if the resource is either same origin as the page that started
// the load, or if the response contains an Access-Control-Allow-Origin
// header with the domain of the page that started the load.
MOZ_ASSERT(aChannel);
if (!IsInitialized()) {
return nsITimedChannel::BodyInfoAccess::DISALLOWED;
}
// Check that the current document passes the check.
nsCOMPtr<nsILoadInfo> loadInfo = aResourceChannel->LoadInfo();
// TYPE_DOCUMENT loads have no loadingPrincipal.
if (loadInfo->GetExternalContentPolicyType() ==
ExtContentPolicy::TYPE_DOCUMENT) {
return nsITimedChannel::BodyInfoAccess::ALLOW_ALL;
}
nsCOMPtr<nsIPrincipal> principal = loadInfo->GetLoadingPrincipal();
if (!principal) {
return nsITimedChannel::BodyInfoAccess::DISALLOWED;
}
return aChannel->BodyInfoAccessAllowedCheck(principal);
}
bool PerformanceTimingData::CheckTimingAllowedForOrigin(
nsIHttpChannel* aResourceChannel, nsITimedChannel* aChannel) {
// Check if the resource is either same origin as the page that started
// the load, or if the response contains the proper Timing-Allow-Origin
// header with the domain of the page that started the load.
MOZ_ASSERT(aChannel);
if (!IsInitialized()) {
return false;
}
// Check that the current document passes the ckeck.
// Check that the current document passes the check.
nsCOMPtr<nsILoadInfo> loadInfo = aResourceChannel->LoadInfo();
// TYPE_DOCUMENT loads have no loadingPrincipal.
@@ -344,11 +386,7 @@ bool PerformanceTimingData::CheckAllowedOrigin(nsIHttpChannel* aResourceChannel,
}
nsCOMPtr<nsIPrincipal> principal = loadInfo->GetLoadingPrincipal();
// Check if the resource is either same origin as the page that started
// the load, or if the response contains the proper Timing-Allow-Origin
// header with the domain of the page that started the load.
return aChannel->TimingAllowCheck(principal);
return principal && aChannel->TimingAllowCheck(principal);
}
uint8_t PerformanceTimingData::GetRedirectCount() const {

View File

@@ -63,6 +63,8 @@ class PerformanceTimingData final {
uint64_t DecodedBodySize() const { return mDecodedBodySize; }
const nsString& ContentType() const { return mContentType; }
/**
* @param aStamp
* The TimeStamp recorded for a specific event. This TimeStamp can
@@ -159,7 +161,12 @@ class PerformanceTimingData final {
bool ShouldReportCrossOriginRedirect(
bool aEnsureSameOriginAndIgnoreTAO) const;
// Cached result of CheckAllowedOrigin. If false, security sensitive
// Cached result of CheckBodyInfoAccessAllowedForOrigin.
nsITimedChannel::BodyInfoAccess BodyInfoAccessAllowed() const {
return mBodyInfoAccessAllowed;
}
// Cached result of CheckTimingAllowedForOrigin. If false, security sensitive
// attributes of the resourceTiming object will be set to 0
bool TimingAllowed() const { return mTimingAllowed; }
@@ -170,10 +177,15 @@ class PerformanceTimingData final {
}
private:
// Checks if the bodyInfo for Resource and Navigation Timing should be
// kept opaque or exposed, per Fetch spec.
nsITimedChannel::BodyInfoAccess CheckBodyInfoAccessAllowedForOrigin(
nsIHttpChannel* aResourceChannel, nsITimedChannel* aChannel);
// Checks if the resource is either same origin as the page that started
// the load, or if the response contains the Timing-Allow-Origin header
// with a value of * or matching the domain of the loading Principal
bool CheckAllowedOrigin(nsIHttpChannel* aResourceChannel,
bool CheckTimingAllowedForOrigin(nsIHttpChannel* aResourceChannel,
nsITimedChannel* aChannel);
nsTArray<nsCOMPtr<nsIServerTiming>> mServerTiming;
@@ -214,12 +226,17 @@ class PerformanceTimingData final {
RenderBlockingStatusType mRenderBlockingStatus;
nsString mContentType;
bool mAllRedirectsSameOrigin = false;
bool mAllRedirectsPassTAO = false;
bool mSecureConnection = false;
nsITimedChannel::BodyInfoAccess mBodyInfoAccessAllowed =
nsITimedChannel::BodyInfoAccess::DISALLOWED;
bool mTimingAllowed = false;
bool mInitialized = false;
@@ -458,9 +475,11 @@ struct IPDLParamTraits<mozilla::dom::PerformanceTimingData> {
WriteIPDLParam(aWriter, aActor, aParam.mTransferSize);
WriteIPDLParam(aWriter, aActor, aParam.mDecodedBodySize);
WriteIPDLParam(aWriter, aActor, aParam.mRedirectCount);
WriteIPDLParam(aWriter, aActor, aParam.mContentType);
WriteIPDLParam(aWriter, aActor, aParam.mAllRedirectsSameOrigin);
WriteIPDLParam(aWriter, aActor, aParam.mAllRedirectsPassTAO);
WriteIPDLParam(aWriter, aActor, aParam.mSecureConnection);
WriteIPDLParam(aWriter, aActor, aParam.mBodyInfoAccessAllowed);
WriteIPDLParam(aWriter, aActor, aParam.mTimingAllowed);
WriteIPDLParam(aWriter, aActor, aParam.mInitialized);
}
@@ -539,6 +558,9 @@ struct IPDLParamTraits<mozilla::dom::PerformanceTimingData> {
if (!ReadIPDLParam(aReader, aActor, &aResult->mRedirectCount)) {
return false;
}
if (!ReadIPDLParam(aReader, aActor, &aResult->mContentType)) {
return false;
}
if (!ReadIPDLParam(aReader, aActor, &aResult->mAllRedirectsSameOrigin)) {
return false;
}
@@ -548,6 +570,9 @@ struct IPDLParamTraits<mozilla::dom::PerformanceTimingData> {
if (!ReadIPDLParam(aReader, aActor, &aResult->mSecureConnection)) {
return false;
}
if (!ReadIPDLParam(aReader, aActor, &aResult->mBodyInfoAccessAllowed)) {
return false;
}
if (!ReadIPDLParam(aReader, aActor, &aResult->mTimingAllowed)) {
return false;
}

View File

@@ -0,0 +1,21 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef _mozilla_dom_PerformanceTimingIPCUtils_h
#define _mozilla_dom_PerformanceTimingIPCUtils_h
#include "mozilla/EnumTypeTraits.h"
#include "ipc/EnumSerializer.h"
#include "nsITimedChannel.h"
namespace IPC {
template <>
struct ParamTraits<nsITimedChannel::BodyInfoAccess>
: ContiguousEnumSerializerInclusive<
nsITimedChannel::BodyInfoAccess,
nsITimedChannel::BodyInfoAccess::DISALLOWED,
nsITimedChannel::BodyInfoAccess::ALLOW_ALL> {};
} // namespace IPC
#endif // _mozilla_dom_PerformanceTimingIPCUtils_h

View File

@@ -4,6 +4,7 @@
using class mozilla::TimeStamp from "mozilla/TimeStamp.h";
using DOMHighResTimeStamp from "nsDOMNavigationTiming.h";
using nsITimedChannel::BodyInfoAccess from "mozilla/dom/PerformanceTimingIPCUtils.h";
namespace mozilla {
namespace dom {
@@ -40,9 +41,11 @@ struct IPCPerformanceTimingData {
uint64_t decodedBodySize;
uint8_t redirectCount;
bool renderBlocking;
nsString contentType;
bool allRedirectsSameOrigin;
bool allRedirectsPassTAO;
bool secureConnection;
BodyInfoAccess bodyInfoAccessAllowed;
bool timingAllowed;
bool initialized;
};

View File

@@ -27,6 +27,7 @@ EXPORTS.mozilla.dom += [
"PerformanceStorage.h",
"PerformanceStorageWorker.h",
"PerformanceTiming.h",
"PerformanceTimingIPCUtils.h",
"PerformanceWorker.h",
]

View File

@@ -51,6 +51,10 @@ interface PerformanceResourceTiming : PerformanceEntry
[NeedsSubjectPrincipal]
readonly attribute unsigned long long decodedBodySize;
// https://w3c.github.io/server-timing/#extension-to-the-performanceresourcetiming-interface
[NeedsSubjectPrincipal]
readonly attribute DOMString contentType;
// TODO: Use FrozenArray once available. (Bug 1236777)
// readonly attribute FrozenArray<PerformanceServerTiming> serverTiming;
[SecureContext, Frozen, Cached, Pure, NeedsSubjectPrincipal]

View File

@@ -11,6 +11,7 @@ class TimeStamp;
}
#include "nsTArrayForwardDeclare.h"
#include "nsCOMPtr.h"
#include "mozilla/Unused.h"
%}
native TimeStamp(mozilla::TimeStamp);
@@ -85,6 +86,20 @@ interface nsITimedChannel : nsISupports {
return NS_SUCCEEDED(TimingAllowCheck(aOrigin, &allowed)) && allowed;
}
%}
// Determines if bodyInfo should be opaque to the given origin
cenum BodyInfoAccess : 8 {
DISALLOWED = 0,
ALLOW_SIZES = 1,
ALLOW_ALL = 2
};
[noscript] nsITimedChannel_BodyInfoAccess bodyInfoAccessAllowedCheck(in nsIPrincipal origin);
%{C++
inline BodyInfoAccess BodyInfoAccessAllowedCheck(nsIPrincipal* aOrigin) {
BodyInfoAccess allowed = BodyInfoAccess::DISALLOWED;
mozilla::Unused << BodyInfoAccessAllowedCheck(aOrigin, &allowed);
return allowed;
}
%}
// Whether this request is render-blocking:
// https://w3c.github.io/resource-timing/#dom-renderblockingstatustype

View File

@@ -5460,6 +5460,112 @@ HttpBaseChannel::SetAllRedirectsPassTimingAllowCheck(bool aPassesCheck) {
return NS_OK;
}
// https://fetch.spec.whatwg.org/#cors-check
bool HttpBaseChannel::PerformCORSCheck() {
// Step 1
// Let origin be the result of getting `Access-Control-Allow-Origin`
// from responses header list.
nsAutoCString origin;
nsresult rv = GetResponseHeader("Access-Control-Allow-Origin"_ns, origin);
// Step 2
// If origin is null, then return failure. (Note: null, not 'null').
if (NS_FAILED(rv) || origin.IsVoid()) {
return false;
}
// Step 3
// If requests credentials mode is not "include"
// and origin is `*`, then return success.
uint32_t cookiePolicy = mLoadInfo->GetCookiePolicy();
if (cookiePolicy != nsILoadInfo::SEC_COOKIES_INCLUDE &&
origin.EqualsLiteral("*")) {
return true;
}
// Step 4
// If the result of byte-serializing a request origin
// with request is not origin, then return failure.
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
nsCOMPtr<nsIPrincipal> resourcePrincipal;
rv = ssm->GetChannelURIPrincipal(this, getter_AddRefs(resourcePrincipal));
if (NS_FAILED(rv) || !resourcePrincipal) {
return false;
}
nsAutoCString serializedOrigin;
nsContentSecurityManager::GetSerializedOrigin(
mLoadInfo->TriggeringPrincipal(), resourcePrincipal, serializedOrigin,
mLoadInfo);
if (!serializedOrigin.Equals(origin)) {
return false;
}
// Step 5
// If requests credentials mode is not "include", then return success.
if (cookiePolicy != nsILoadInfo::SEC_COOKIES_INCLUDE) {
return true;
}
// Step 6
// Let credentials be the result of getting
// `Access-Control-Allow-Credentials` from responses header list.
nsAutoCString credentials;
rv = GetResponseHeader("Access-Control-Allow-Credentials"_ns, credentials);
// Step 7 and 8
// If credentials is `true`, then return success.
// (else) return failure.
return NS_SUCCEEDED(rv) && credentials.EqualsLiteral("true");
}
NS_IMETHODIMP
HttpBaseChannel::BodyInfoAccessAllowedCheck(nsIPrincipal* aOrigin,
BodyInfoAccess* _retval) {
// Per the Fetch spec, https://fetch.spec.whatwg.org/#response-body-info,
// the bodyInfo for Resource Timing and Navigation Timing info consists of
// encoded size, decoded size, and content type. It is however made opaque
// whenever the response is turned into a network error, which sets its
// bodyInfo to its default values (sizes=0, content-type="").
// Case 1:
// "no-cors" -> Upon success, fetch will return an opaque filtered response.
// An opaque(-redirect) filtered response is a filtered response
// whose ... body info is a new response body info.
auto tainting = mLoadInfo->GetTainting();
if (tainting == mozilla::LoadTainting::Opaque) {
*_retval = BodyInfoAccess::DISALLOWED;
return NS_OK;
}
// Case 2:
// If requests response tainting is "cors" and a CORS check for request
// and response returns failure, then return a network error.
if (tainting == mozilla::LoadTainting::CORS && !PerformCORSCheck()) {
*_retval = BodyInfoAccess::DISALLOWED;
return NS_OK;
}
// Otherwise:
// The fetch response handover, given a fetch params fetchParams
// and a response response, run these steps:
// processResponseEndOfBody:
// - If fetchParamss requests mode is not "navigate" or responses
// has-cross-origin-redirects is false:
// - Let mimeType be the result of extracting a MIME type from
// responses header list.
// - If mimeType is not failure, then set bodyInfos content type to the
// result of minimizing a supported MIME type given mimeType.
dom::RequestMode requestMode;
MOZ_ALWAYS_SUCCEEDS(GetRequestMode(&requestMode));
if (requestMode != RequestMode::Navigate || LoadAllRedirectsSameOrigin()) {
*_retval = BodyInfoAccess::ALLOW_ALL;
return NS_OK;
}
*_retval = BodyInfoAccess::ALLOW_SIZES;
return NS_OK;
}
// https://fetch.spec.whatwg.org/#tao-check
NS_IMETHODIMP
HttpBaseChannel::TimingAllowCheck(nsIPrincipal* aOrigin, bool* _retval) {

View File

@@ -1088,6 +1088,8 @@ class HttpBaseChannel : public nsHashPropertyBag,
void RemoveAsNonTailRequest();
void EnsureBrowserId();
bool PerformCORSCheck();
};
NS_DEFINE_STATIC_IID_ACCESSOR(HttpBaseChannel, HTTP_BASE_CHANNEL_IID)

View File

@@ -741,6 +741,13 @@ NullHttpChannel::SetAllRedirectsPassTimingAllowCheck(
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
NullHttpChannel::BodyInfoAccessAllowedCheck(nsIPrincipal* aOrigin,
BodyInfoAccess* _retval) {
*_retval = BodyInfoAccess::DISALLOWED;
return NS_OK;
}
NS_IMETHODIMP
NullHttpChannel::TimingAllowCheck(nsIPrincipal* aOrigin, bool* _retval) {
*_retval = false;

View File

@@ -1,15 +0,0 @@
[body-size-cross-origin.https.html]
[Retrieving a same-origin resource without Timing-Allow-Origin should expose body size]
expected: FAIL
[Retrieving a same-origin resource with Timing-Allow-Origin should expose body size]
expected: FAIL
[Retrieving a no-cors resource with Timing-Allow-Origin should not expose body size]
expected: FAIL
[Retrieving a cors resource without Timing-Allow-Origin should expose body size]
expected: FAIL
[Retrieving a cors resource with Timing-Allow-Origin should expose body size]
expected: FAIL

View File

@@ -1,16 +1,4 @@
[content-type-parsing.html]
[content-type 0 : ,text/plain]
expected: FAIL
[content-type 1 : text/plain,]
expected: FAIL
[content-type 2 : text/html,text/plain]
expected: FAIL
[content-type 3 : text/plain;charset=gbk,text/html]
expected: FAIL
[content-type 4 : text/plain;charset=gbk,text/html;charset=windows-1254]
expected: FAIL
@@ -26,39 +14,12 @@
[content-type 8 : text/plain;charset=gbk;x=foo,text/plain]
expected: FAIL
[content-type 9 : text/html;charset=gbk,text/plain,text/html]
expected: FAIL
[content-type 10 : text/plain,*/*]
expected: FAIL
[content-type 11 : text/html,*/*]
expected: FAIL
[content-type 12 : */*,text/html]
expected: FAIL
[content-type 13 : text/plain,*/*;charset=gbk]
expected: FAIL
[content-type 14 : text/html,*/*;charset=gbk]
expected: FAIL
[content-type 15 : text/html;x=",text/plain]
expected: FAIL
[content-type 16 : text/html;",text/plain]
expected: FAIL
[content-type 17 : text/html;",\\",text/plain]
expected: FAIL
[content-type 18 : text/html;",\\",text/plain,";charset=GBK]
expected: FAIL
[content-type 19 : text/html;",",text/plain]
expected: FAIL
[mime-type 1 : text/html;charset=gbk]
expected: FAIL
@@ -77,9 +38,6 @@
[mime-type 8 : text/html;charset=();charset=GBK]
expected: FAIL
[mime-type 10 : text/html;charset =gbk]
expected: FAIL
[mime-type 11 : text/html ;charset=gbk]
expected: FAIL
@@ -92,18 +50,6 @@
[mime-type 14 : text/html;charset= "gbk"]
expected: FAIL
[mime-type 16 : text/html;charset=\x0bgbk]
expected: FAIL
[mime-type 17 : text/html;charset=\x0cgbk]
expected: FAIL
[mime-type 18 : text/html;\x0bcharset=gbk]
expected: FAIL
[mime-type 19 : text/html;\x0ccharset=gbk]
expected: FAIL
[mime-type 21 : text/html;charset='gbk']
expected: FAIL

View File

@@ -1,83 +1,3 @@
[content-type.html]
expected:
if (os == "android") and fission: [OK, TIMEOUT]
[This test validates the content-type of resources.]
expected: FAIL
[This test validates the content-type of resources. 1]
expected: FAIL
[This test validates the content-type of resources. 2]
expected: FAIL
[This test validates the content-type of resources. 3]
expected: FAIL
[This test validates the content-type of resources. 4]
expected: FAIL
[This test validates the content-type of resources. 5]
expected: FAIL
[This test validates the content-type of resources. 6]
expected: FAIL
[This test validates the content-type of resources. 7]
expected: FAIL
[This test validates the content-type of resources. 8]
expected: FAIL
[This test validates the content-type of resources. 9]
expected: FAIL
[This test validates the content-type of resources. 10]
expected: FAIL
[This test validates the content-type of resources. 11]
expected: FAIL
[This test validates the content-type of resources. 12]
expected: FAIL
[This test validates the content-type of resources. 13]
expected: FAIL
[This test validates the content-type of resources. 14]
expected: FAIL
[This test validates the content-type of resources. 15]
expected: FAIL
[This test validates the content-type of resources. 16]
expected: FAIL
[This test validates the content-type of resources. 17]
expected: FAIL
[This test validates the content-type of resources. 18]
expected: FAIL
[This test validates the content-type of resources. 19]
expected: FAIL
[This test validates the content-type of resources. 20]
expected: FAIL
[This test validates the content-type of resources. 21]
expected: FAIL
[This test validates the content-type of resources. 22]
expected: FAIL
[This test validates the content-type of resources. 23]
expected: FAIL
[This test validates the content-type of resources. 24]
expected: FAIL
[This test validates the content-type of resources. 25]
expected: FAIL
[This test validates the content-type of resources. 26]
expected: FAIL

View File

@@ -22,12 +22,6 @@
[PerformanceResourceTiming interface: resource must inherit property "firstInterimResponseStart" with the proper type]
expected: FAIL
[PerformanceResourceTiming interface: attribute contentType]
expected: FAIL
[PerformanceResourceTiming interface: resource must inherit property "contentType" with the proper type]
expected: FAIL
[idlharness.any.worker.html]
expected:
@@ -52,9 +46,3 @@
[PerformanceResourceTiming interface: resource must inherit property "firstInterimResponseStart" with the proper type]
expected: FAIL
[PerformanceResourceTiming interface: attribute contentType]
expected: FAIL
[PerformanceResourceTiming interface: resource must inherit property "contentType" with the proper type]
expected: FAIL

View File

@@ -1,17 +1,3 @@
[sizes-redirect-img.html]
expected:
if (os == "android") and fission: [OK, TIMEOUT]
[PerformanceResourceTiming sizes redirect image - direct URL]
expected: FAIL
[PerformanceResourceTiming sizes redirect image - same origin redirect]
expected: FAIL
[PerformanceResourceTiming sizes redirect image - cross origin redirect]
expected: FAIL
[PerformanceResourceTiming sizes redirect image - cross origin to same origin redirect]
expected: FAIL
[PerformanceResourceTiming sizes redirect image - same origin to remote origin to same origin redirect]
expected: FAIL

View File

@@ -11,9 +11,6 @@
[sizes-redirect.any.html]
[PerformanceResourceTiming sizes Fetch with redirect test]
expected: FAIL
[sizes-redirect.any.worker.html]
[PerformanceResourceTiming sizes Fetch with redirect test]

View File

@@ -26,12 +26,6 @@
[PerformanceResourceTiming interface: resource must inherit property "firstInterimResponseStart" with the proper type]
expected: FAIL
[PerformanceResourceTiming interface: attribute contentType]
expected: FAIL
[PerformanceResourceTiming interface: resource must inherit property "contentType" with the proper type]
expected: FAIL
[idlharness.https.any.worker.html]
[PerformanceResourceTiming interface: attribute renderBlockingStatus]
@@ -60,9 +54,3 @@
[PerformanceResourceTiming interface: resource must inherit property "firstInterimResponseStart" with the proper type]
expected: FAIL
[PerformanceResourceTiming interface: attribute contentType]
expected: FAIL
[PerformanceResourceTiming interface: resource must inherit property "contentType" with the proper type]
expected: FAIL

View File

@@ -112,6 +112,16 @@ attribute_test(
`content-type should be exposed for iframes having only same origin redirects`);
});
// Content-type for iframes is not exposed if any redirect is not same origin.
var finalDestUrl = `${SAME_ORIGIN}/resource-timing/resources/content-type.py?content_type=text/html`;
var interimDestUrl = `${REMOTE_ORIGIN}/resource-timing/resources/resources/redirect-cors.py?location=` + encodeURIComponent(finalDestUrl);
var destUrl = `${SAME_ORIGIN}/resource-timing/resources/redirect-cors.py?location=` + encodeURIComponent(interimDestUrl);
attribute_test(
load.iframe, new URL(destUrl),
entry => {
assert_equals(entry.contentType, "",
`content-type should not be exposed for iframes with any non-same-origin redirect`);
});
</script>
</body>
</html>