mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Back out 2 changesets (bug 1173811
) for test_synthesized_response.js timeouts
CLOSED TREE Backed out changeset 56bc1314e660 (bug1173811
) Backed out changeset 0ad51d302ba9 (bug1173811
)
This commit is contained in:
parent
67c1e9e6a9
commit
6401c0185c
@ -109,19 +109,16 @@ class FinishResponse final : public nsRunnable
|
||||
RefPtr<InternalResponse> mInternalResponse;
|
||||
ChannelInfo mWorkerChannelInfo;
|
||||
const nsCString mScriptSpec;
|
||||
const nsCString mResponseURLSpec;
|
||||
|
||||
public:
|
||||
FinishResponse(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
|
||||
InternalResponse* aInternalResponse,
|
||||
const ChannelInfo& aWorkerChannelInfo,
|
||||
const nsACString& aScriptSpec,
|
||||
const nsACString& aResponseURLSpec)
|
||||
const nsACString& aScriptSpec)
|
||||
: mChannel(aChannel)
|
||||
, mInternalResponse(aInternalResponse)
|
||||
, mWorkerChannelInfo(aWorkerChannelInfo)
|
||||
, mScriptSpec(aScriptSpec)
|
||||
, mResponseURLSpec(aResponseURLSpec)
|
||||
{
|
||||
}
|
||||
|
||||
@ -157,7 +154,7 @@ public:
|
||||
mChannel->SynthesizeHeader(entries[i].mName, entries[i].mValue);
|
||||
}
|
||||
|
||||
rv = mChannel->FinishSynthesizedResponse(mResponseURLSpec);
|
||||
rv = mChannel->FinishSynthesizedResponse();
|
||||
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to finish synthesized response");
|
||||
return rv;
|
||||
}
|
||||
@ -235,18 +232,15 @@ struct RespondWithClosure
|
||||
RefPtr<InternalResponse> mInternalResponse;
|
||||
ChannelInfo mWorkerChannelInfo;
|
||||
const nsCString mScriptSpec;
|
||||
const nsCString mResponseURLSpec;
|
||||
|
||||
RespondWithClosure(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
|
||||
InternalResponse* aInternalResponse,
|
||||
const ChannelInfo& aWorkerChannelInfo,
|
||||
const nsCString& aScriptSpec,
|
||||
const nsACString& aResponseURLSpec)
|
||||
const nsCString& aScriptSpec)
|
||||
: mInterceptedChannel(aChannel)
|
||||
, mInternalResponse(aInternalResponse)
|
||||
, mWorkerChannelInfo(aWorkerChannelInfo)
|
||||
, mScriptSpec(aScriptSpec)
|
||||
, mResponseURLSpec(aResponseURLSpec)
|
||||
{
|
||||
}
|
||||
};
|
||||
@ -259,8 +253,7 @@ void RespondWithCopyComplete(void* aClosure, nsresult aStatus)
|
||||
event = new FinishResponse(data->mInterceptedChannel,
|
||||
data->mInternalResponse,
|
||||
data->mWorkerChannelInfo,
|
||||
data->mScriptSpec,
|
||||
data->mResponseURLSpec);
|
||||
data->mScriptSpec);
|
||||
} else {
|
||||
event = new CancelChannelRunnable(data->mInterceptedChannel,
|
||||
NS_ERROR_INTERCEPTION_FAILED);
|
||||
@ -363,22 +356,9 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValu
|
||||
return;
|
||||
}
|
||||
|
||||
// When an opaque response is encountered, we need the original channel's principal
|
||||
// to reflect the final URL. Non-opaque responses are either same-origin or CORS-enabled
|
||||
// cross-origin responses, which are treated as same-origin by consumers.
|
||||
nsCString responseURL;
|
||||
if (response->Type() == ResponseType::Opaque) {
|
||||
ir->GetUnfilteredUrl(responseURL);
|
||||
if (NS_WARN_IF(responseURL.IsEmpty())) {
|
||||
autoCancel.SetCancelStatus(NS_ERROR_INTERCEPTION_FAILED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoPtr<RespondWithClosure> closure(new RespondWithClosure(mInterceptedChannel, ir,
|
||||
worker->GetChannelInfo(),
|
||||
mScriptSpec,
|
||||
responseURL));
|
||||
mScriptSpec));
|
||||
nsCOMPtr<nsIInputStream> body;
|
||||
ir->GetUnfilteredBody(getter_AddRefs(body));
|
||||
// Errors and redirects may not have a body.
|
||||
|
@ -78,18 +78,12 @@ InterceptedJARChannel::SynthesizeHeader(const nsACString& aName,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
InterceptedJARChannel::FinishSynthesizedResponse(const nsACString& aFinalURLSpec)
|
||||
InterceptedJARChannel::FinishSynthesizedResponse()
|
||||
{
|
||||
if (NS_WARN_IF(!mChannel)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (!aFinalURLSpec.IsEmpty()) {
|
||||
// We don't support rewriting responses for JAR channels where the principal
|
||||
// needs to be modified.
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
mChannel->OverrideWithSynthesizedResponse(mSynthesizedInput, mContentType);
|
||||
|
||||
mResponseBody = nullptr;
|
||||
|
@ -27,7 +27,7 @@ class ChannelInfo;
|
||||
* which do not implement nsIChannel.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(afe6aae6-a80d-405b-856e-df36c19bf3c8)]
|
||||
[scriptable, uuid(6be00c37-2e85-42ee-b53c-e6508ce4cef0)]
|
||||
interface nsIInterceptedChannel : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -51,11 +51,9 @@ interface nsIInterceptedChannel : nsISupports
|
||||
/**
|
||||
* Instruct a channel that has been intercepted that a response has been
|
||||
* synthesized and can now be read. No further header modification is allowed
|
||||
* after this point. The caller may optionally pass a spec for a URL that
|
||||
* this response originates from; an empty string will cause the original
|
||||
* intercepted request's URL to be used instead.
|
||||
* after this point.
|
||||
*/
|
||||
void finishSynthesizedResponse(in ACString finalURLSpec);
|
||||
void finishSynthesizedResponse();
|
||||
|
||||
/**
|
||||
* Cancel the pending intercepted request.
|
||||
|
@ -267,21 +267,6 @@ HttpBaseChannel::GetLoadFlags(nsLoadFlags *aLoadFlags)
|
||||
NS_IMETHODIMP
|
||||
HttpBaseChannel::SetLoadFlags(nsLoadFlags aLoadFlags)
|
||||
{
|
||||
bool synthesized = false;
|
||||
nsresult rv = GetResponseSynthesized(&synthesized);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If this channel is marked as awaiting a synthesized response,
|
||||
// modifying certain load flags can interfere with the implementation
|
||||
// of the network interception logic. This takes care of a couple
|
||||
// known cases that attempt to mark channels as anonymous due
|
||||
// to cross-origin redirects; since the response is entirely synthesized
|
||||
// this is an unnecessary precaution.
|
||||
// This should be removed when bug 1201683 is fixed.
|
||||
if (synthesized && aLoadFlags != mLoadFlags) {
|
||||
aLoadFlags &= ~LOAD_ANONYMOUS;
|
||||
}
|
||||
|
||||
mLoadFlags = aLoadFlags;
|
||||
mForceMainDocumentChannel = (aLoadFlags & LOAD_DOCUMENT_URI);
|
||||
return NS_OK;
|
||||
|
@ -184,8 +184,6 @@ HttpChannelChild::HttpChannelChild()
|
||||
, mFlushedForDiversion(false)
|
||||
, mSuspendSent(false)
|
||||
, mSynthesizedResponse(false)
|
||||
, mShouldInterceptSubsequentRedirect(false)
|
||||
, mRedirectingForSubsequentSynthesizedResponse(false)
|
||||
, mShouldParentIntercept(false)
|
||||
{
|
||||
LOG(("Creating HttpChannelChild @%x\n", this));
|
||||
@ -1159,51 +1157,6 @@ HttpChannelChild::RecvRedirect1Begin(const uint32_t& newChannelId,
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
HttpChannelChild::SetupRedirect(nsIURI* uri,
|
||||
const nsHttpResponseHead* responseHead,
|
||||
nsIChannel** outChannel)
|
||||
{
|
||||
LOG(("HttpChannelChild::SetupRedirect [this=%p]\n", this));
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIIOService> ioService;
|
||||
rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIChannel> newChannel;
|
||||
rv = NS_NewChannelInternal(getter_AddRefs(newChannel),
|
||||
uri,
|
||||
mLoadInfo,
|
||||
nullptr, // aLoadGroup
|
||||
nullptr, // aCallbacks
|
||||
nsIRequest::LOAD_NORMAL,
|
||||
ioService);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// We won't get OnStartRequest, set cookies here.
|
||||
mResponseHead = new nsHttpResponseHead(*responseHead);
|
||||
|
||||
bool rewriteToGET = HttpBaseChannel::ShouldRewriteRedirectToGET(mResponseHead->Status(),
|
||||
mRequestHead.ParsedMethod());
|
||||
|
||||
rv = SetupReplacementChannel(uri, newChannel, !rewriteToGET);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIHttpChannelChild> httpChannelChild = do_QueryInterface(newChannel);
|
||||
if (mShouldInterceptSubsequentRedirect && httpChannelChild) {
|
||||
// In the case where there was a synthesized response that caused a redirection,
|
||||
// we must force the new channel to intercept the request in the parent before a
|
||||
// network transaction is initiated.
|
||||
httpChannelChild->ForceIntercepted();
|
||||
}
|
||||
|
||||
mRedirectChannelChild = do_QueryInterface(newChannel);
|
||||
newChannel.forget(outChannel);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
HttpChannelChild::Redirect1Begin(const uint32_t& newChannelId,
|
||||
const URIParams& newUri,
|
||||
@ -1213,50 +1166,68 @@ HttpChannelChild::Redirect1Begin(const uint32_t& newChannelId,
|
||||
{
|
||||
LOG(("HttpChannelChild::Redirect1Begin [this=%p]\n", this));
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIIOService> ioService;
|
||||
rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
|
||||
if (NS_FAILED(rv)) {
|
||||
// Veto redirect. nsHttpChannel decides to cancel or continue.
|
||||
OnRedirectVerifyCallback(rv);
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri = DeserializeURI(newUri);
|
||||
|
||||
nsCOMPtr<nsIChannel> newChannel;
|
||||
rv = NS_NewChannelInternal(getter_AddRefs(newChannel),
|
||||
uri,
|
||||
mLoadInfo,
|
||||
nullptr, // aLoadGroup
|
||||
nullptr, // aCallbacks
|
||||
nsIRequest::LOAD_NORMAL,
|
||||
ioService);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
// Veto redirect. nsHttpChannel decides to cancel or continue.
|
||||
OnRedirectVerifyCallback(rv);
|
||||
return;
|
||||
}
|
||||
|
||||
// We won't get OnStartRequest, set cookies here.
|
||||
mResponseHead = new nsHttpResponseHead(responseHead);
|
||||
|
||||
if (!securityInfoSerialization.IsEmpty()) {
|
||||
NS_DeserializeObject(securityInfoSerialization,
|
||||
getter_AddRefs(mSecurityInfo));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIChannel> newChannel;
|
||||
nsresult rv = SetupRedirect(uri,
|
||||
&responseHead,
|
||||
getter_AddRefs(newChannel));
|
||||
bool rewriteToGET = HttpBaseChannel::ShouldRewriteRedirectToGET(mResponseHead->Status(),
|
||||
mRequestHead.ParsedMethod());
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (mRedirectChannelChild) {
|
||||
mRedirectChannelChild->ConnectParent(newChannelId);
|
||||
rv = gHttpHandler->AsyncOnChannelRedirect(this,
|
||||
newChannel,
|
||||
redirectFlags);
|
||||
} else {
|
||||
LOG((" redirecting to a protocol that doesn't implement"
|
||||
" nsIChildChannel"));
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
rv = SetupReplacementChannel(uri, newChannel, !rewriteToGET);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Veto redirect. nsHttpChannel decides to cancel or continue.
|
||||
OnRedirectVerifyCallback(rv);
|
||||
return;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
OnRedirectVerifyCallback(rv);
|
||||
}
|
||||
nsCOMPtr<nsIHttpChannelChild> httpChannelChild = do_QueryInterface(newChannel);
|
||||
if (mSynthesizedResponse && httpChannelChild) {
|
||||
// In the case where there was a synthesized response that caused a redirection,
|
||||
// we must force the new channel to intercept the request in the parent before a
|
||||
// network transaction is initiated.
|
||||
httpChannelChild->ForceIntercepted();
|
||||
}
|
||||
|
||||
void
|
||||
HttpChannelChild::BeginNonIPCRedirect(nsIURI* responseURI,
|
||||
const nsHttpResponseHead* responseHead)
|
||||
{
|
||||
LOG(("HttpChannelChild::BeginNonIPCRedirect [this=%p]\n", this));
|
||||
|
||||
nsCOMPtr<nsIChannel> newChannel;
|
||||
nsresult rv = SetupRedirect(responseURI,
|
||||
responseHead,
|
||||
getter_AddRefs(newChannel));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mRedirectChannelChild = do_QueryInterface(newChannel);
|
||||
if (mRedirectChannelChild) {
|
||||
mRedirectChannelChild->ConnectParent(newChannelId);
|
||||
rv = gHttpHandler->AsyncOnChannelRedirect(this,
|
||||
newChannel,
|
||||
nsIChannelEventSink::REDIRECT_INTERNAL);
|
||||
redirectFlags);
|
||||
} else {
|
||||
LOG((" redirecting to a protocol that doesn't implement"
|
||||
" nsIChildChannel"));
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
@ -1464,34 +1435,6 @@ HttpChannelChild::CompleteRedirectSetup(nsIStreamListener *listener,
|
||||
// HttpChannelChild::nsIAsyncVerifyRedirectCallback
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class OverrideRunnable : public nsRunnable {
|
||||
RefPtr<HttpChannelChild> mChannel;
|
||||
RefPtr<HttpChannelChild> mNewChannel;
|
||||
RefPtr<InterceptStreamListener> mListener;
|
||||
nsCOMPtr<nsIInputStream> mInput;
|
||||
nsAutoPtr<nsHttpResponseHead> mHead;
|
||||
|
||||
public:
|
||||
OverrideRunnable(HttpChannelChild* aChannel,
|
||||
HttpChannelChild* aNewChannel,
|
||||
InterceptStreamListener* aListener,
|
||||
nsIInputStream* aInput,
|
||||
nsAutoPtr<nsHttpResponseHead>& aHead)
|
||||
: mChannel(aChannel)
|
||||
, mNewChannel(aNewChannel)
|
||||
, mListener(aListener)
|
||||
, mInput(aInput)
|
||||
, mHead(aHead)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() {
|
||||
mChannel->Redirect3Complete();
|
||||
mNewChannel->OverrideWithSynthesizedResponse(mHead, mInput, mListener);
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpChannelChild::OnRedirectVerifyCallback(nsresult result)
|
||||
{
|
||||
@ -1505,21 +1448,6 @@ HttpChannelChild::OnRedirectVerifyCallback(nsresult result)
|
||||
newHttpChannel->SetOriginalURI(mOriginalURI);
|
||||
}
|
||||
|
||||
if (mRedirectingForSubsequentSynthesizedResponse) {
|
||||
nsCOMPtr<nsIHttpChannelChild> httpChannelChild = do_QueryInterface(mRedirectChannelChild);
|
||||
MOZ_ASSERT(httpChannelChild);
|
||||
RefPtr<HttpChannelChild> redirectedChannel =
|
||||
static_cast<HttpChannelChild*>(httpChannelChild.get());
|
||||
|
||||
RefPtr<InterceptStreamListener> streamListener =
|
||||
new InterceptStreamListener(redirectedChannel, mListenerContext);
|
||||
|
||||
NS_DispatchToMainThread(new OverrideRunnable(this, redirectedChannel,
|
||||
streamListener, mSynthesizedInput,
|
||||
mResponseHead));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RequestHeaderTuples emptyHeaders;
|
||||
RequestHeaderTuples* headerTuples = &emptyHeaders;
|
||||
nsLoadFlags loadFlags = 0;
|
||||
@ -2457,10 +2385,8 @@ HttpChannelChild::GetResponseSynthesized(bool* aSynthesized)
|
||||
void
|
||||
HttpChannelChild::OverrideWithSynthesizedResponse(nsAutoPtr<nsHttpResponseHead>& aResponseHead,
|
||||
nsIInputStream* aSynthesizedInput,
|
||||
InterceptStreamListener* aStreamListener)
|
||||
nsIStreamListener* aStreamListener)
|
||||
{
|
||||
mInterceptListener = aStreamListener;
|
||||
|
||||
// Intercepted responses should already be decoded. If its a redirect,
|
||||
// however, we want to respect the encoding of the final result instead.
|
||||
if (!WillRedirect(aResponseHead)) {
|
||||
@ -2471,7 +2397,6 @@ HttpChannelChild::OverrideWithSynthesizedResponse(nsAutoPtr<nsHttpResponseHead>&
|
||||
mSynthesizedResponse = true;
|
||||
|
||||
if (WillRedirect(mResponseHead)) {
|
||||
mShouldInterceptSubsequentRedirect = true;
|
||||
// Continue with the original cross-process request
|
||||
nsresult rv = ContinueAsyncOpen();
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
@ -2519,20 +2444,6 @@ HttpChannelChild::ForceIntercepted()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HttpChannelChild::ForceIntercepted(uint64_t aInterceptionID)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
void
|
||||
HttpChannelChild::ForceIntercepted(nsIInputStream* aSynthesizedInput)
|
||||
{
|
||||
mSynthesizedInput = aSynthesizedInput;
|
||||
mSynthesizedResponse = true;
|
||||
mRedirectingForSubsequentSynthesizedResponse = true;
|
||||
}
|
||||
|
||||
bool
|
||||
HttpChannelChild::RecvIssueDeprecationWarning(const uint32_t& warning,
|
||||
const bool& asError)
|
||||
|
@ -37,7 +37,6 @@ namespace net {
|
||||
|
||||
class InterceptedChannelContent;
|
||||
class InterceptStreamListener;
|
||||
class OverrideRunnable;
|
||||
|
||||
class HttpChannelChild final : public PHttpChannelChild
|
||||
, public HttpBaseChannel
|
||||
@ -89,7 +88,6 @@ public:
|
||||
NS_IMETHOD GetLocalPort(int32_t* port) override;
|
||||
NS_IMETHOD GetRemoteAddress(nsACString& addr) override;
|
||||
NS_IMETHOD GetRemotePort(int32_t* port) override;
|
||||
NS_IMETHOD ForceIntercepted(uint64_t aInterceptionID) override;
|
||||
// nsISupportsPriority
|
||||
NS_IMETHOD SetPriority(int32_t value) override;
|
||||
// nsIClassOfService
|
||||
@ -176,16 +174,12 @@ private:
|
||||
// asynchronously read from the pump.
|
||||
void OverrideWithSynthesizedResponse(nsAutoPtr<nsHttpResponseHead>& aResponseHead,
|
||||
nsIInputStream* aSynthesizedInput,
|
||||
InterceptStreamListener* aStreamListener);
|
||||
|
||||
void ForceIntercepted(nsIInputStream* aSynthesizedInput);
|
||||
nsIStreamListener* aStreamListener);
|
||||
|
||||
RequestHeaderTuples mClientSetRequestHeaders;
|
||||
nsCOMPtr<nsIChildChannel> mRedirectChannelChild;
|
||||
RefPtr<InterceptStreamListener> mInterceptListener;
|
||||
RefPtr<nsInputStreamPump> mSynthesizedResponsePump;
|
||||
nsAutoPtr<nsHttpResponseHead> mSynthesizedResponseHead;
|
||||
nsCOMPtr<nsIInputStream> mSynthesizedInput;
|
||||
int64_t mSynthesizedStreamLength;
|
||||
|
||||
bool mIsFromCache;
|
||||
@ -220,13 +214,6 @@ private:
|
||||
// should be intercepted.
|
||||
bool mSynthesizedResponse;
|
||||
|
||||
// Set if a synthesized response should cause us to explictly allows intercepting
|
||||
// an expected forthcoming redirect.
|
||||
bool mShouldInterceptSubsequentRedirect;
|
||||
// Set if a redirection is being initiated to facilitate providing a synthesized
|
||||
// response to a channel using a different principal than the current one.
|
||||
bool mRedirectingForSubsequentSynthesizedResponse;
|
||||
|
||||
// Set if the corresponding parent channel should force an interception to occur
|
||||
// before the network transaction is initiated.
|
||||
bool mShouldParentIntercept;
|
||||
@ -272,16 +259,6 @@ private:
|
||||
void Redirect3Complete();
|
||||
void DeleteSelf();
|
||||
|
||||
// Create a a new channel to be used in a redirection, based on the provided
|
||||
// response headers.
|
||||
nsresult SetupRedirect(nsIURI* uri,
|
||||
const nsHttpResponseHead* responseHead,
|
||||
nsIChannel** outChannel);
|
||||
|
||||
// Perform a redirection without communicating with the parent process at all.
|
||||
void BeginNonIPCRedirect(nsIURI* responseURI,
|
||||
const nsHttpResponseHead* responseHead);
|
||||
|
||||
friend class AssociateApplicationCacheEvent;
|
||||
friend class StartRequestEvent;
|
||||
friend class StopRequestEvent;
|
||||
@ -297,7 +274,6 @@ private:
|
||||
friend class HttpAsyncAborter<HttpChannelChild>;
|
||||
friend class InterceptStreamListener;
|
||||
friend class InterceptedChannelContent;
|
||||
friend class OverrideRunnable;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -203,9 +203,7 @@ public:
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
// The URL passed as an argument here doesn't matter, since the child will
|
||||
// receive a redirection notification as a result of this synthesized response.
|
||||
mChannel->FinishSynthesizedResponse(EmptyCString());
|
||||
mChannel->FinishSynthesizedResponse();
|
||||
return NS_OK;
|
||||
}
|
||||
};
|
||||
|
@ -179,7 +179,7 @@ InterceptedChannelChrome::SynthesizeHeader(const nsACString& aName, const nsACSt
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
InterceptedChannelChrome::FinishSynthesizedResponse(const nsACString& aFinalURLSpec)
|
||||
InterceptedChannelChrome::FinishSynthesizedResponse()
|
||||
{
|
||||
if (!mChannel) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
@ -208,38 +208,23 @@ InterceptedChannelChrome::FinishSynthesizedResponse(const nsACString& aFinalURLS
|
||||
mSynthesizedResponseHead.ref(), securityInfo);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIURI> originalURI;
|
||||
mChannel->GetURI(getter_AddRefs(originalURI));
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
mChannel->GetURI(getter_AddRefs(uri));
|
||||
|
||||
nsCOMPtr<nsIURI> responseURI;
|
||||
if (!aFinalURLSpec.IsEmpty()) {
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(responseURI), aFinalURLSpec);
|
||||
bool usingSSL = false;
|
||||
uri->SchemeIs("https", &usingSSL);
|
||||
|
||||
// Then we open a real cache entry to read the synthesized response from.
|
||||
rv = mChannel->OpenCacheEntry(usingSSL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mSynthesizedCacheEntry = nullptr;
|
||||
|
||||
if (!mChannel->AwaitingCacheCallbacks()) {
|
||||
rv = mChannel->ContinueConnect();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
responseURI = originalURI;
|
||||
}
|
||||
|
||||
bool equal = false;
|
||||
originalURI->Equals(responseURI, &equal);
|
||||
if (!equal) {
|
||||
nsresult rv =
|
||||
mChannel->StartRedirectChannelToURI(responseURI, nsIChannelEventSink::REDIRECT_INTERNAL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
bool usingSSL = false;
|
||||
responseURI->SchemeIs("https", &usingSSL);
|
||||
|
||||
// Then we open a real cache entry to read the synthesized response from.
|
||||
rv = mChannel->OpenCacheEntry(usingSSL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mSynthesizedCacheEntry = nullptr;
|
||||
|
||||
if (!mChannel->AwaitingCacheCallbacks()) {
|
||||
rv = mChannel->ContinueConnect();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
mChannel = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
@ -284,7 +269,7 @@ InterceptedChannelChrome::GetInternalContentPolicyType(nsContentPolicyType* aPol
|
||||
|
||||
InterceptedChannelContent::InterceptedChannelContent(HttpChannelChild* aChannel,
|
||||
nsINetworkInterceptController* aController,
|
||||
InterceptStreamListener* aListener)
|
||||
nsIStreamListener* aListener)
|
||||
: InterceptedChannelBase(aController)
|
||||
, mChannel(aChannel)
|
||||
, mStreamListener(aListener)
|
||||
@ -345,7 +330,7 @@ InterceptedChannelContent::SynthesizeHeader(const nsACString& aName, const nsACS
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
InterceptedChannelContent::FinishSynthesizedResponse(const nsACString& aFinalURLSpec)
|
||||
InterceptedChannelContent::FinishSynthesizedResponse()
|
||||
{
|
||||
if (NS_WARN_IF(!mChannel)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
@ -353,27 +338,9 @@ InterceptedChannelContent::FinishSynthesizedResponse(const nsACString& aFinalURL
|
||||
|
||||
EnsureSynthesizedResponse();
|
||||
|
||||
nsCOMPtr<nsIURI> originalURI;
|
||||
mChannel->GetURI(getter_AddRefs(originalURI));
|
||||
|
||||
nsCOMPtr<nsIURI> responseURI;
|
||||
if (!aFinalURLSpec.IsEmpty()) {
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(responseURI), aFinalURLSpec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
} else {
|
||||
responseURI = originalURI;
|
||||
}
|
||||
|
||||
bool equal = false;
|
||||
originalURI->Equals(responseURI, &equal);
|
||||
if (!equal) {
|
||||
mChannel->ForceIntercepted(mSynthesizedInput);
|
||||
mChannel->BeginNonIPCRedirect(responseURI, *mSynthesizedResponseHead.ptr());
|
||||
} else {
|
||||
mChannel->OverrideWithSynthesizedResponse(mSynthesizedResponseHead.ref(),
|
||||
mSynthesizedInput,
|
||||
mStreamListener);
|
||||
}
|
||||
mChannel->OverrideWithSynthesizedResponse(mSynthesizedResponseHead.ref(),
|
||||
mSynthesizedInput,
|
||||
mStreamListener);
|
||||
|
||||
mResponseBody = nullptr;
|
||||
mChannel = nullptr;
|
||||
|
@ -21,7 +21,6 @@ namespace net {
|
||||
class nsHttpChannel;
|
||||
class HttpChannelChild;
|
||||
class nsHttpResponseHead;
|
||||
class InterceptStreamListener;
|
||||
|
||||
// An object representing a channel that has been intercepted. This avoids complicating
|
||||
// the actual channel implementation with the details of synthesizing responses.
|
||||
@ -73,7 +72,7 @@ public:
|
||||
nsICacheEntry* aEntry);
|
||||
|
||||
NS_IMETHOD ResetInterception() override;
|
||||
NS_IMETHOD FinishSynthesizedResponse(const nsACString& aFinalURLSpec) override;
|
||||
NS_IMETHOD FinishSynthesizedResponse() override;
|
||||
NS_IMETHOD GetChannel(nsIChannel** aChannel) override;
|
||||
NS_IMETHOD SynthesizeStatus(uint16_t aStatus, const nsACString& aReason) override;
|
||||
NS_IMETHOD SynthesizeHeader(const nsACString& aName, const nsACString& aValue) override;
|
||||
@ -94,14 +93,14 @@ class InterceptedChannelContent : public InterceptedChannelBase
|
||||
|
||||
// Listener for the synthesized response to fix up the notifications before they reach
|
||||
// the actual channel.
|
||||
RefPtr<InterceptStreamListener> mStreamListener;
|
||||
nsCOMPtr<nsIStreamListener> mStreamListener;
|
||||
public:
|
||||
InterceptedChannelContent(HttpChannelChild* aChannel,
|
||||
nsINetworkInterceptController* aController,
|
||||
InterceptStreamListener* aListener);
|
||||
nsIStreamListener* aListener);
|
||||
|
||||
NS_IMETHOD ResetInterception() override;
|
||||
NS_IMETHOD FinishSynthesizedResponse(const nsACString& aFinalURLSpec) override;
|
||||
NS_IMETHOD FinishSynthesizedResponse() override;
|
||||
NS_IMETHOD GetChannel(nsIChannel** aChannel) override;
|
||||
NS_IMETHOD SynthesizeStatus(uint16_t aStatus, const nsACString& aReason) override;
|
||||
NS_IMETHOD SynthesizeHeader(const nsACString& aName, const nsACString& aValue) override;
|
||||
|
@ -2010,19 +2010,12 @@ nsHttpChannel::StartRedirectChannelToURI(nsIURI *upgradedURI, uint32_t flags)
|
||||
if (!(flags & nsIChannelEventSink::REDIRECT_STS_UPGRADE)) {
|
||||
// Ensure that internally-redirected channels cannot be intercepted, which would look
|
||||
// like two separate requests to the nsINetworkInterceptController.
|
||||
if (mInterceptCache == INTERCEPTED) {
|
||||
nsCOMPtr<nsIHttpChannelInternal> httpRedirect = do_QueryInterface(mRedirectChannel);
|
||||
if (httpRedirect) {
|
||||
httpRedirect->ForceIntercepted(mInterceptionID);
|
||||
}
|
||||
} else {
|
||||
nsLoadFlags loadFlags = nsIRequest::LOAD_NORMAL;
|
||||
rv = mRedirectChannel->GetLoadFlags(&loadFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
loadFlags |= nsIChannel::LOAD_BYPASS_SERVICE_WORKER;
|
||||
rv = mRedirectChannel->SetLoadFlags(loadFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
nsLoadFlags loadFlags = nsIRequest::LOAD_NORMAL;
|
||||
rv = mRedirectChannel->GetLoadFlags(&loadFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
loadFlags |= nsIChannel::LOAD_BYPASS_SERVICE_WORKER;
|
||||
rv = mRedirectChannel->SetLoadFlags(loadFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
PushRedirectAsyncFunc(
|
||||
@ -3000,10 +2993,11 @@ nsHttpChannel::OpenCacheEntry(bool isHttps)
|
||||
if (mLoadFlags & LOAD_BYPASS_LOCAL_CACHE_IF_BUSY)
|
||||
cacheEntryOpenFlags |= nsICacheStorage::OPEN_BYPASS_IF_BUSY;
|
||||
|
||||
if (mPostID) {
|
||||
extension.Append(nsPrintfCString("%d", mPostID));
|
||||
}
|
||||
if (PossiblyIntercepted()) {
|
||||
extension.Append(nsPrintfCString("u%lld", mInterceptionID));
|
||||
} else if (mPostID) {
|
||||
extension.Append(nsPrintfCString("%d", mPostID));
|
||||
}
|
||||
|
||||
// If this channel should be intercepted, we do not open a cache entry for this channel
|
||||
@ -4990,7 +4984,7 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context)
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (mInterceptCache != INTERCEPTED && ShouldIntercept()) {
|
||||
if (ShouldIntercept()) {
|
||||
mInterceptCache = MAYBE_INTERCEPT;
|
||||
SetCouldBeSynthesized();
|
||||
}
|
||||
@ -5350,21 +5344,6 @@ nsHttpChannel::SetupFallbackChannel(const char *aFallbackKey)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHttpChannel::ForceIntercepted(uint64_t aInterceptionID)
|
||||
{
|
||||
ENSURE_CALLED_BEFORE_ASYNC_OPEN();
|
||||
|
||||
if (NS_WARN_IF(mLoadFlags & LOAD_BYPASS_SERVICE_WORKER)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
MarkIntercepted();
|
||||
mResponseCouldBeSynthesized = true;
|
||||
mInterceptionID = aInterceptionID;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsHttpChannel::nsISupportsPriority
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -134,7 +134,6 @@ public:
|
||||
NS_IMETHOD AsyncOpen2(nsIStreamListener *aListener) override;
|
||||
// nsIHttpChannelInternal
|
||||
NS_IMETHOD SetupFallbackChannel(const char *aFallbackKey) override;
|
||||
NS_IMETHOD ForceIntercepted(uint64_t aInterceptionID) override;
|
||||
// nsISupportsPriority
|
||||
NS_IMETHOD SetPriority(int32_t value) override;
|
||||
// nsIClassOfService
|
||||
@ -434,9 +433,8 @@ private:
|
||||
MAYBE_INTERCEPT, // interception in progress, but can be cancelled
|
||||
INTERCEPTED, // a synthesized response has been provided
|
||||
} mInterceptCache;
|
||||
// ID of this channel for the interception purposes. Unique unless this
|
||||
// channel is replacing an intercepted one via an redirection.
|
||||
uint64_t mInterceptionID;
|
||||
// Unique ID of this channel for the interception purposes.
|
||||
const uint64_t mInterceptionID;
|
||||
|
||||
bool PossiblyIntercepted() {
|
||||
return mInterceptCache != DO_NOT_INTERCEPT;
|
||||
|
@ -39,7 +39,7 @@ interface nsIHttpUpgradeListener : nsISupports
|
||||
* using any feature exposed by this interface, be aware that this interface
|
||||
* will change and you will be broken. You have been warned.
|
||||
*/
|
||||
[scriptable, uuid(9eabaac6-cc7c-4ca1-9430-65f2daaa578f)]
|
||||
[scriptable, uuid(99767aaf-937d-4f2f-8990-bc79bd7c0ece)]
|
||||
interface nsIHttpChannelInternal : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -222,13 +222,6 @@ interface nsIHttpChannelInternal : nsISupports
|
||||
|
||||
readonly attribute PRTime lastModifiedTime;
|
||||
|
||||
/**
|
||||
* Force a channel that has not been AsyncOpen'ed to skip any check for possible
|
||||
* interception and proceed immediately to open a previously-synthesized cache
|
||||
* entry using the provided ID.
|
||||
*/
|
||||
void forceIntercepted(in uint64_t aInterceptionID);
|
||||
|
||||
readonly attribute boolean responseSynthesized;
|
||||
|
||||
/**
|
||||
|
@ -106,12 +106,6 @@
|
||||
"url": "/_mozilla/service-workers/service-worker/extendable-event-waituntil.https.html"
|
||||
}
|
||||
],
|
||||
"service-workers/service-worker/fetch-canvas-tainting-cache.https.html": [
|
||||
{
|
||||
"path": "service-workers/service-worker/fetch-canvas-tainting-cache.https.html",
|
||||
"url": "/_mozilla/service-workers/service-worker/fetch-canvas-tainting-cache.https.html"
|
||||
}
|
||||
],
|
||||
"service-workers/service-worker/fetch-canvas-tainting.https.html": [
|
||||
{
|
||||
"path": "service-workers/service-worker/fetch-canvas-tainting.https.html",
|
||||
|
@ -1,5 +0,0 @@
|
||||
[fetch-request-css-base-url.https.html]
|
||||
type: testharness
|
||||
bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1201160
|
||||
[CSS's base URL must be the request URL even when fetched from other URL.]
|
||||
expected: FAIL
|
@ -1,3 +0,0 @@
|
||||
[worker-interception-iframe.https.html]
|
||||
type: testharness
|
||||
disabled: not a test
|
@ -1,38 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<title>Service Worker: canvas tainting of the fetched image using cached responses</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js?pipe=sub"></script>
|
||||
<body>
|
||||
<script>
|
||||
async_test(function(t) {
|
||||
var SCOPE = 'resources/fetch-canvas-tainting-iframe.html?cache';
|
||||
var SCRIPT = 'resources/fetch-rewrite-worker.js';
|
||||
var host_info = get_host_info();
|
||||
|
||||
login_https(t)
|
||||
.then(function() {
|
||||
return service_worker_unregister_and_register(t, SCRIPT, SCOPE);
|
||||
})
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(SCOPE); })
|
||||
.then(function(frame) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = t.step_func(function(e) {
|
||||
assert_equals(e.data.results, 'finish');
|
||||
frame.remove();
|
||||
service_worker_unregister_and_done(t, SCOPE);
|
||||
});
|
||||
frame.contentWindow.postMessage({},
|
||||
host_info['HTTPS_ORIGIN'],
|
||||
[channel.port2]);
|
||||
});
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Verify canvas tainting of fetched image in a Service Worker');
|
||||
</script>
|
||||
</body>
|
@ -65,8 +65,7 @@ function redirect_fetch_test(t, test) {
|
||||
};
|
||||
frame.contentWindow.postMessage({
|
||||
url: url,
|
||||
request_init: test.request_init,
|
||||
redirect_dest: test.redirect_dest,
|
||||
request_init: test.request_init
|
||||
}, '*', [channel.port2]);
|
||||
});
|
||||
|
||||
|
@ -3,26 +3,11 @@
|
||||
<script>
|
||||
var image_path = base_path() + 'fetch-access-control.py?PNGIMAGE';
|
||||
var host_info = get_host_info();
|
||||
var params = get_query_params(location.href);
|
||||
|
||||
var NOT_TAINTED = 'NOT_TAINTED';
|
||||
var TAINTED = 'TAINTED';
|
||||
var LOAD_ERROR = 'LOAD_ERROR';
|
||||
|
||||
function get_query_params(url) {
|
||||
var search = (new URL(url)).search;
|
||||
if (!search) {
|
||||
return {};
|
||||
}
|
||||
var ret = {};
|
||||
var params = search.substring(1).split('&');
|
||||
params.forEach(function(param) {
|
||||
var element = param.split('=');
|
||||
ret[decodeURIComponent(element[0])] = decodeURIComponent(element[1]);
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
function create_test_case_promise(url, cross_origin) {
|
||||
return new Promise(function(resolve) {
|
||||
var img = new Image();
|
||||
@ -50,10 +35,6 @@ function create_test_case_promise(url, cross_origin) {
|
||||
}
|
||||
|
||||
function create_test_promise(url, cross_origin, expected_result) {
|
||||
if (params['cache']) {
|
||||
url += "&cache";
|
||||
}
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
create_test_case_promise(url, cross_origin)
|
||||
.then(function(result) {
|
||||
@ -159,7 +140,7 @@ window.addEventListener('message', function(evt) {
|
||||
remote_image_url +
|
||||
'&mode=same-origin&url=' + encodeURIComponent(image_url),
|
||||
'',
|
||||
TAINTED),
|
||||
NOT_TAINTED),
|
||||
create_test_promise(
|
||||
remote_image_url +
|
||||
'&mode=same-origin&url=' + encodeURIComponent(image_url),
|
||||
@ -210,7 +191,9 @@ window.addEventListener('message', function(evt) {
|
||||
encodeURIComponent(remote_image_url +
|
||||
'&ACAOrigin=' + host_info['HTTPS_ORIGIN']),
|
||||
'',
|
||||
NOT_TAINTED),
|
||||
TAINTED), // We expect TAINTED since the default origin behavior here
|
||||
// is taint, and it doesn't matter what kind of fetch the
|
||||
// SW performs.
|
||||
create_test_promise(
|
||||
image_url +
|
||||
'&mode=cors&url=' +
|
||||
|
@ -3,13 +3,6 @@ window.addEventListener('message', function(evt) {
|
||||
var port = evt.ports[0];
|
||||
var data = evt.data;
|
||||
fetch(new Request(data.url, data.request_init)).then(function(response) {
|
||||
if (data.request_init.mode === 'no-cors' && data.redirect_dest != 'same-origin') {
|
||||
if (response.type === 'opaque') {
|
||||
return {result: 'success', detail: ''};
|
||||
} else {
|
||||
return {result: 'failure', detail: 'expected opaque response'};
|
||||
}
|
||||
}
|
||||
return response.json();
|
||||
}).then(function(body) {
|
||||
port.postMessage({result: body.result, detail: body.detail});
|
||||
|
@ -80,25 +80,7 @@ self.addEventListener('fetch', function(event) {
|
||||
expectedType
|
||||
})));
|
||||
}
|
||||
|
||||
if (params['cache']) {
|
||||
var cacheName = "cached-fetches-" + Date.now();
|
||||
var cache;
|
||||
var cachedResponse;
|
||||
return self.caches.open(cacheName).then(function(opened) {
|
||||
cache = opened;
|
||||
return cache.put(request, response);
|
||||
}).then(function() {
|
||||
return cache.match(request);
|
||||
}).then(function(cached) {
|
||||
cachedResponse = cached;
|
||||
return self.caches.delete(cacheName);
|
||||
}).then(function() {
|
||||
resolve(cachedResponse);
|
||||
});
|
||||
} else {
|
||||
resolve(response);
|
||||
}
|
||||
resolve(response);
|
||||
}, reject)
|
||||
}));
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user