From c66a858d3a2e435c1f4b641d73620f202cbd4e3a Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Mon, 25 May 2015 14:21:05 -0400 Subject: [PATCH] Bug 1168208 - Refactor the existing logic for syncing the security info between Response and channel objects into a new helper class; r=nsm,jdm,bkelly --HG-- rename : dom/fetch/InternalResponse.cpp => dom/fetch/ChannelInfo.cpp rename : dom/fetch/Response.h => dom/fetch/ChannelInfo.h --- dom/cache/CacheTypes.ipdlh | 3 +- dom/cache/DBSchema.cpp | 18 ++-- dom/cache/TypeUtils.cpp | 4 +- dom/fetch/ChannelInfo.cpp | 94 +++++++++++++++++++ dom/fetch/ChannelInfo.h | 87 +++++++++++++++++ dom/fetch/ChannelInfo.ipdlh | 14 +++ dom/fetch/FetchDriver.cpp | 6 +- dom/fetch/InternalResponse.cpp | 20 ---- dom/fetch/InternalResponse.h | 29 ++++-- dom/fetch/Response.h | 12 ++- dom/fetch/moz.build | 12 +++ dom/workers/ScriptLoader.cpp | 41 +++----- dom/workers/ServiceWorkerEvents.cpp | 36 ++++--- dom/workers/ServiceWorkerScriptCache.cpp | 20 +--- dom/workers/WorkerPrivate.cpp | 12 --- dom/workers/WorkerPrivate.h | 24 +++-- dom/workers/Workers.h | 3 +- .../base/nsINetworkInterceptController.idl | 17 +++- netwerk/protocol/http/InterceptedChannel.cpp | 9 +- netwerk/protocol/http/InterceptedChannel.h | 4 +- netwerk/protocol/http/TunnelUtils.h | 1 + netwerk/protocol/http/nsHttpConnectionInfo.h | 1 + 22 files changed, 327 insertions(+), 140 deletions(-) create mode 100644 dom/fetch/ChannelInfo.cpp create mode 100644 dom/fetch/ChannelInfo.h create mode 100644 dom/fetch/ChannelInfo.ipdlh diff --git a/dom/cache/CacheTypes.ipdlh b/dom/cache/CacheTypes.ipdlh index 43f8a38b5dee..a98d94ca8c34 100644 --- a/dom/cache/CacheTypes.ipdlh +++ b/dom/cache/CacheTypes.ipdlh @@ -6,6 +6,7 @@ include protocol PCache; include protocol PCachePushStream; include protocol PCacheStreamControl; include InputStreamParams; +include ChannelInfo; using HeadersGuardEnum from "mozilla/dom/cache/IPCUtils.h"; using RequestCredentials from "mozilla/dom/cache/IPCUtils.h"; @@ -81,7 +82,7 @@ struct CacheResponse HeadersEntry[] headers; HeadersGuardEnum headersGuard; CacheReadStreamOrVoid body; - nsCString securityInfo; + IPCChannelInfo channelInfo; }; union CacheResponseOrVoid diff --git a/dom/cache/DBSchema.cpp b/dom/cache/DBSchema.cpp index 3e98db6adb22..c2bed77f63f1 100644 --- a/dom/cache/DBSchema.cpp +++ b/dom/cache/DBSchema.cpp @@ -175,8 +175,8 @@ static nsresult DeleteEntries(mozIStorageConnection* aConn, nsTArray& aDeletedBodyIdListOut, nsTArray& aDeletedSecurityIdListOut, uint32_t aPos=0, int32_t aLen=-1); -static nsresult InsertSecurity(mozIStorageConnection* aConn, - const nsACString& aData, int32_t *aIdOut); +static nsresult InsertSecurityInfo(mozIStorageConnection* aConn, + const nsACString& aData, int32_t *aIdOut); static nsresult DeleteSecurityInfo(mozIStorageConnection* aConn, int32_t aId, int32_t aCount); static nsresult DeleteSecurityInfoList(mozIStorageConnection* aConn, @@ -1194,8 +1194,8 @@ DeleteEntries(mozIStorageConnection* aConn, } nsresult -InsertSecurity(mozIStorageConnection* aConn, const nsACString& aData, - int32_t *aIdOut) +InsertSecurityInfo(mozIStorageConnection* aConn, const nsACString& aData, + int32_t *aIdOut) { MOZ_ASSERT(aConn); MOZ_ASSERT(aIdOut); @@ -1394,8 +1394,10 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId, nsresult rv = NS_OK; int32_t securityId = -1; - if (!aResponse.securityInfo().IsEmpty()) { - rv = InsertSecurity(aConn, aResponse.securityInfo(), &securityId); + if (!aResponse.channelInfo().securityInfo().IsEmpty()) { + rv = InsertSecurityInfo(aConn, + aResponse.channelInfo().securityInfo(), + &securityId); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } @@ -1511,7 +1513,7 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId, rv = BindId(state, NS_LITERAL_CSTRING("response_body_id"), aResponseBodyId); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } - if (aResponse.securityInfo().IsEmpty()) { + if (aResponse.channelInfo().securityInfo().IsEmpty()) { rv = state->BindNullByName(NS_LITERAL_CSTRING("response_security_info_id")); } else { rv = state->BindInt32ByName(NS_LITERAL_CSTRING("response_security_info_id"), @@ -1657,7 +1659,7 @@ ReadResponse(mozIStorageConnection* aConn, EntryId aEntryId, if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } - rv = state->GetBlobAsUTF8String(6, aSavedResponseOut->mValue.securityInfo()); + rv = state->GetBlobAsUTF8String(6, aSavedResponseOut->mValue.channelInfo().securityInfo()); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } rv = aConn->CreateStatement(NS_LITERAL_CSTRING( diff --git a/dom/cache/TypeUtils.cpp b/dom/cache/TypeUtils.cpp index e6ee8f98b3bf..0d7c618a239d 100644 --- a/dom/cache/TypeUtils.cpp +++ b/dom/cache/TypeUtils.cpp @@ -224,7 +224,7 @@ TypeUtils::ToCacheResponseWithoutBody(CacheResponse& aOut, } ToHeadersEntryList(aOut.headers(), headers); aOut.headersGuard() = headers->Guard(); - aOut.securityInfo() = aIn.GetSecurityInfo(); + aOut.channelInfo() = aIn.GetChannelInfo().AsIPCChannelInfo(); } void @@ -290,7 +290,7 @@ TypeUtils::ToResponse(const CacheResponse& aIn) ir->Headers()->Fill(*internalHeaders, result); MOZ_ASSERT(!result.Failed()); - ir->SetSecurityInfo(aIn.securityInfo()); + ir->InitChannelInfo(aIn.channelInfo()); nsCOMPtr stream = ReadStream::Create(aIn.body()); ir->SetBody(stream); diff --git a/dom/fetch/ChannelInfo.cpp b/dom/fetch/ChannelInfo.cpp new file mode 100644 index 000000000000..5e49503b73fc --- /dev/null +++ b/dom/fetch/ChannelInfo.cpp @@ -0,0 +1,94 @@ +/* -*- 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/. */ + +#include "mozilla/dom/ChannelInfo.h" +#include "nsCOMPtr.h" +#include "nsIChannel.h" +#include "nsIHttpChannel.h" +#include "nsSerializationHelper.h" +#include "mozilla/net/HttpBaseChannel.h" +#include "mozilla/ipc/ChannelInfo.h" + +using namespace mozilla; +using namespace mozilla::dom; + +void +ChannelInfo::InitFromChannel(nsIChannel* aChannel) +{ + MOZ_ASSERT(!mInited, "Cannot initialize the object twice"); + + nsCOMPtr securityInfo; + aChannel->GetSecurityInfo(getter_AddRefs(securityInfo)); + if (securityInfo) { + SetSecurityInfo(securityInfo); + } + + mInited = true; +} + +void +ChannelInfo::InitFromIPCChannelInfo(const ipc::IPCChannelInfo& aChannelInfo) +{ + MOZ_ASSERT(!mInited, "Cannot initialize the object twice"); + + mSecurityInfo = aChannelInfo.securityInfo(); + + mInited = true; +} + +void +ChannelInfo::SetSecurityInfo(nsISupports* aSecurityInfo) +{ + MOZ_ASSERT(mSecurityInfo.IsEmpty(), "security info should only be set once"); + nsCOMPtr serializable = do_QueryInterface(aSecurityInfo); + if (!serializable) { + NS_WARNING("A non-serializable object was passed to InternalResponse::SetSecurityInfo"); + return; + } + NS_SerializeToString(serializable, mSecurityInfo); +} + +nsresult +ChannelInfo::ResurrectInfoOnChannel(nsIChannel* aChannel) +{ + MOZ_ASSERT(mInited); + + if (!mSecurityInfo.IsEmpty()) { + nsCOMPtr infoObj; + nsresult rv = NS_DeserializeObject(mSecurityInfo, getter_AddRefs(infoObj)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + nsCOMPtr httpChannel = + do_QueryInterface(aChannel); + if (NS_WARN_IF(!httpChannel)) { + return NS_ERROR_FAILURE; + } + net::HttpBaseChannel* httpBaseChannel = + static_cast(httpChannel.get()); + rv = httpBaseChannel->OverrideSecurityInfo(infoObj); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + } + + return NS_OK; +} + +ipc::IPCChannelInfo +ChannelInfo::AsIPCChannelInfo() const +{ + // This may be called when mInited is false, for example if we try to store + // a synthesized Response object into the Cache. Uninitialized and empty + // ChannelInfo objects are indistinguishable at the IPC level, so this is + // fine. + + IPCChannelInfo ipcInfo; + + ipcInfo.securityInfo() = mSecurityInfo; + + return ipcInfo; +} diff --git a/dom/fetch/ChannelInfo.h b/dom/fetch/ChannelInfo.h new file mode 100644 index 000000000000..f365fdf0fcdc --- /dev/null +++ b/dom/fetch/ChannelInfo.h @@ -0,0 +1,87 @@ +/* -*- 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_ChannelInfo_h +#define mozilla_dom_ChannelInfo_h + +#include "nsString.h" + +class nsIChannel; + +namespace mozilla { +namespace ipc { +class IPCChannelInfo; +} // namespace ipc + +namespace dom { + +// This class represents the information related to a Response that we +// retrieve from the corresponding channel that is used to perform the fetch. +// +// When adding new members to this object, the following code needs to be +// updated: +// * IPCChannelInfo +// * InitFromChannel and InitFromIPCChannelInfo members +// * ResurrectInfoOnChannel member +// * AsIPCChannelInfo member +// * constructors and assignment operators for this class. +// * DOM Cache schema code (in dom/cache/DBSchema.cpp) to ensure that the newly +// added member is saved into the DB and loaded from it properly. +// +// Care must be taken when initializing this object, or when calling +// ResurrectInfoOnChannel(). This object cannot be initialized twice, and +// ResurrectInfoOnChannel() cannot be called on it before it has been +// initialized. There are assertions ensuring these invariants. +class ChannelInfo final +{ +public: + typedef mozilla::ipc::IPCChannelInfo IPCChannelInfo; + + ChannelInfo() + : mInited(false) + { + } + + ChannelInfo(const ChannelInfo& aRHS) + : mSecurityInfo(aRHS.mSecurityInfo) + , mInited(aRHS.mInited) + { + } + + ChannelInfo& + operator=(const ChannelInfo& aRHS) + { + mSecurityInfo = aRHS.mSecurityInfo; + mInited = aRHS.mInited; + return *this; + } + + void InitFromChannel(nsIChannel* aChannel); + void InitFromIPCChannelInfo(const IPCChannelInfo& aChannelInfo); + + // This restores every possible information stored from a previous channel + // object on a new one. + nsresult ResurrectInfoOnChannel(nsIChannel* aChannel); + + bool IsInitialized() const + { + return mInited; + } + + IPCChannelInfo AsIPCChannelInfo() const; + +private: + void SetSecurityInfo(nsISupports* aSecurityInfo); + +private: + nsCString mSecurityInfo; + bool mInited; +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_ChannelInfo_h diff --git a/dom/fetch/ChannelInfo.ipdlh b/dom/fetch/ChannelInfo.ipdlh new file mode 100644 index 000000000000..605009e120dd --- /dev/null +++ b/dom/fetch/ChannelInfo.ipdlh @@ -0,0 +1,14 @@ +/* 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/. */ + +namespace mozilla { +namespace ipc { + +struct IPCChannelInfo +{ + nsCString securityInfo; +}; + +} // namespace ipc +} // namespace mozilla diff --git a/dom/fetch/FetchDriver.cpp b/dom/fetch/FetchDriver.cpp index 909dbedaa7ac..4f2381da8852 100644 --- a/dom/fetch/FetchDriver.cpp +++ b/dom/fetch/FetchDriver.cpp @@ -706,12 +706,8 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest, } response->SetBody(pipeInputStream); - nsCOMPtr securityInfo; nsCOMPtr channel = do_QueryInterface(aRequest); - rv = channel->GetSecurityInfo(getter_AddRefs(securityInfo)); - if (securityInfo) { - response->SetSecurityInfo(securityInfo); - } + response->InitChannelInfo(channel); // Resolves fetch() promise which may trigger code running in a worker. Make // sure the Response is fully initialized before calling this. diff --git a/dom/fetch/InternalResponse.cpp b/dom/fetch/InternalResponse.cpp index 6ee065c7bc36..2791a013e2da 100644 --- a/dom/fetch/InternalResponse.cpp +++ b/dom/fetch/InternalResponse.cpp @@ -8,7 +8,6 @@ #include "mozilla/dom/InternalHeaders.h" #include "nsStreamUtils.h" -#include "nsSerializationHelper.h" namespace mozilla { namespace dom { @@ -75,24 +74,5 @@ InternalResponse::CORSResponse() return cors.forget(); } -void -InternalResponse::SetSecurityInfo(nsISupports* aSecurityInfo) -{ - MOZ_ASSERT(mSecurityInfo.IsEmpty(), "security info should only be set once"); - nsCOMPtr serializable = do_QueryInterface(aSecurityInfo); - if (!serializable) { - NS_WARNING("A non-serializable object was passed to InternalResponse::SetSecurityInfo"); - return; - } - NS_SerializeToString(serializable, mSecurityInfo); -} - -void -InternalResponse::SetSecurityInfo(const nsCString& aSecurityInfo) -{ - MOZ_ASSERT(mSecurityInfo.IsEmpty(), "security info should only be set once"); - mSecurityInfo = aSecurityInfo; -} - } // namespace dom } // namespace mozilla diff --git a/dom/fetch/InternalResponse.h b/dom/fetch/InternalResponse.h index 0d5203da8a58..9b88de778ccd 100644 --- a/dom/fetch/InternalResponse.h +++ b/dom/fetch/InternalResponse.h @@ -11,6 +11,7 @@ #include "nsISupportsImpl.h" #include "mozilla/dom/ResponseBinding.h" +#include "mozilla/dom/ChannelInfo.h" namespace mozilla { namespace dom { @@ -48,7 +49,7 @@ public: response->mTerminationReason = mTerminationReason; response->mURL = mURL; response->mFinalURL = mFinalURL; - response->mSecurityInfo = mSecurityInfo; + response->mChannelInfo = mChannelInfo; response->mWrappedResponse = this; return response.forget(); } @@ -156,17 +157,29 @@ public: mBody = aBody; } - const nsCString& - GetSecurityInfo() const + void + InitChannelInfo(nsIChannel* aChannel) { - return mSecurityInfo; + mChannelInfo.InitFromChannel(aChannel); } void - SetSecurityInfo(nsISupports* aSecurityInfo); + InitChannelInfo(const mozilla::ipc::IPCChannelInfo& aChannelInfo) + { + mChannelInfo.InitFromIPCChannelInfo(aChannelInfo); + } void - SetSecurityInfo(const nsCString& aSecurityInfo); + InitChannelInfo(const ChannelInfo& aChannelInfo) + { + mChannelInfo = aChannelInfo; + } + + const ChannelInfo& + GetChannelInfo() const + { + return mChannelInfo; + } private: ~InternalResponse() @@ -185,7 +198,7 @@ private: copy->mTerminationReason = mTerminationReason; copy->mURL = mURL; copy->mFinalURL = mFinalURL; - copy->mSecurityInfo = mSecurityInfo; + copy->mChannelInfo = mChannelInfo; return copy.forget(); } @@ -197,7 +210,7 @@ private: const nsCString mStatusText; nsRefPtr mHeaders; nsCOMPtr mBody; - nsCString mSecurityInfo; + ChannelInfo mChannelInfo; // For filtered responses. // Cache, and SW interception should always serialize/access the underlying diff --git a/dom/fetch/Response.h b/dom/fetch/Response.h index 51340a0325e5..5692d70eae7e 100644 --- a/dom/fetch/Response.h +++ b/dom/fetch/Response.h @@ -78,10 +78,16 @@ public: return mInternalResponse->Headers(); } - const nsCString& - GetSecurityInfo() const + void + InitChannelInfo(nsIChannel* aChannel) { - return mInternalResponse->GetSecurityInfo(); + mInternalResponse->InitChannelInfo(aChannel); + } + + const ChannelInfo& + GetChannelInfo() const + { + return mInternalResponse->GetChannelInfo(); } Headers* Headers_(); diff --git a/dom/fetch/moz.build b/dom/fetch/moz.build index 316f84b1f1c9..4bab581d5609 100644 --- a/dom/fetch/moz.build +++ b/dom/fetch/moz.build @@ -5,6 +5,7 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. EXPORTS.mozilla.dom += [ + 'ChannelInfo.h', 'Fetch.h', 'FetchDriver.h', 'Headers.h', @@ -16,6 +17,7 @@ EXPORTS.mozilla.dom += [ ] UNIFIED_SOURCES += [ + 'ChannelInfo.cpp', 'Fetch.cpp', 'FetchDriver.cpp', 'Headers.cpp', @@ -26,11 +28,21 @@ UNIFIED_SOURCES += [ 'Response.cpp', ] +IPDL_SOURCES += [ + 'ChannelInfo.ipdlh', +] + LOCAL_INCLUDES += [ '../workers', + # For HttpBaseChannel.h dependencies + '/netwerk/base', # For nsDataHandler.h '/netwerk/protocol/data', + # For HttpBaseChannel.h + '/netwerk/protocol/http', ] FAIL_ON_WARNINGS = True FINAL_LIBRARY = 'xul' + +include('/ipc/chromium/chromium-config.mozbuild') diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp index 84f651d10f72..4398d4161f26 100644 --- a/dom/workers/ScriptLoader.cpp +++ b/dom/workers/ScriptLoader.cpp @@ -14,7 +14,6 @@ #include "nsIIOService.h" #include "nsIProtocolHandler.h" #include "nsIScriptSecurityManager.h" -#include "nsISerializable.h" #include "nsIStreamLoader.h" #include "nsIStreamListenerTee.h" #include "nsIThreadRetargetableRequest.h" @@ -422,7 +421,7 @@ private: bool mFailed; nsCOMPtr mPump; nsCOMPtr mBaseURI; - nsCString mSecurityInfo; + ChannelInfo mChannelInfo; }; NS_IMPL_ISUPPORTS(CacheScriptLoader, nsIStreamLoaderObserver) @@ -589,19 +588,9 @@ private: new InternalResponse(200, NS_LITERAL_CSTRING("OK")); ir->SetBody(mReader); - // Set the security info of the channel on the response so that it's + // Set the channel info of the channel on the response so that it's // saved in the cache. - nsCOMPtr infoObj; - channel->GetSecurityInfo(getter_AddRefs(infoObj)); - if (infoObj) { - nsCOMPtr serializable = do_QueryInterface(infoObj); - if (serializable) { - ir->SetSecurityInfo(serializable); - MOZ_ASSERT(!ir->GetSecurityInfo().IsEmpty()); - } else { - NS_WARNING("A non-serializable object was obtained from nsIChannel::GetSecurityInfo()!"); - } - } + ir->InitChannelInfo(channel); nsRefPtr response = new Response(mCacheCreator->Global(), ir); @@ -965,18 +954,9 @@ private: // Take care of the base URI first. mWorkerPrivate->SetBaseURI(finalURI); - // Store the security info if needed. + // Store the channel info if needed. if (mWorkerPrivate->IsServiceWorker()) { - nsCOMPtr infoObj; - channel->GetSecurityInfo(getter_AddRefs(infoObj)); - if (infoObj) { - nsCOMPtr serializable = do_QueryInterface(infoObj); - if (serializable) { - mWorkerPrivate->SetSecurityInfo(serializable); - } else { - NS_WARNING("A non-serializable object was obtained from nsIChannel::GetSecurityInfo()!"); - } - } + mWorkerPrivate->InitChannelInfo(channel); } // Now to figure out which principal to give this worker. @@ -1047,7 +1027,8 @@ private: void DataReceivedFromCache(uint32_t aIndex, const uint8_t* aString, - uint32_t aStringLen, const nsCString& aSecurityInfo) + uint32_t aStringLen, + const ChannelInfo& aChannelInfo) { AssertIsOnMainThread(); MOZ_ASSERT(aIndex < mLoadInfos.Length()); @@ -1075,7 +1056,7 @@ private: MOZ_ASSERT(principal); nsILoadGroup* loadGroup = mWorkerPrivate->GetLoadGroup(); MOZ_ASSERT(loadGroup); - mWorkerPrivate->SetSecurityInfo(aSecurityInfo); + mWorkerPrivate->InitChannelInfo(aChannelInfo); // Needed to initialize the principal info. This is fine because // the cache principal cannot change, unlike the channel principal. mWorkerPrivate->SetPrincipal(principal, loadGroup); @@ -1429,11 +1410,11 @@ CacheScriptLoader::ResolvedCallback(JSContext* aCx, nsCOMPtr inputStream; response->GetBody(getter_AddRefs(inputStream)); - mSecurityInfo = response->GetSecurityInfo(); + mChannelInfo = response->GetChannelInfo(); if (!inputStream) { mLoadInfo.mCacheStatus = ScriptLoadInfo::Cached; - mRunnable->DataReceivedFromCache(mIndex, (uint8_t*)"", 0, mSecurityInfo); + mRunnable->DataReceivedFromCache(mIndex, (uint8_t*)"", 0, mChannelInfo); return; } @@ -1489,7 +1470,7 @@ CacheScriptLoader::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aCont mLoadInfo.mCacheStatus = ScriptLoadInfo::Cached; - mRunnable->DataReceivedFromCache(mIndex, aString, aStringLen, mSecurityInfo); + mRunnable->DataReceivedFromCache(mIndex, aString, aStringLen, mChannelInfo); return NS_OK; } diff --git a/dom/workers/ServiceWorkerEvents.cpp b/dom/workers/ServiceWorkerEvents.cpp index 694173b0e9f5..72e34a4be111 100644 --- a/dom/workers/ServiceWorkerEvents.cpp +++ b/dom/workers/ServiceWorkerEvents.cpp @@ -98,14 +98,14 @@ class FinishResponse final : public nsRunnable { nsMainThreadPtrHandle mChannel; nsRefPtr mInternalResponse; - nsCString mWorkerSecurityInfo; + ChannelInfo mWorkerChannelInfo; public: FinishResponse(nsMainThreadPtrHandle& aChannel, InternalResponse* aInternalResponse, - const nsCString& aWorkerSecurityInfo) + const ChannelInfo& aWorkerChannelInfo) : mChannel(aChannel) , mInternalResponse(aInternalResponse) - , mWorkerSecurityInfo(aWorkerSecurityInfo) + , mWorkerChannelInfo(aWorkerChannelInfo) { } @@ -114,19 +114,17 @@ public: { AssertIsOnMainThread(); - nsCOMPtr infoObj; - nsAutoCString securityInfo(mInternalResponse->GetSecurityInfo()); - if (securityInfo.IsEmpty()) { + ChannelInfo channelInfo; + if (mInternalResponse->GetChannelInfo().IsInitialized()) { + channelInfo = mInternalResponse->GetChannelInfo(); + } else { // We are dealing with a synthesized response here, so fall back to the - // security info for the worker script. - securityInfo = mWorkerSecurityInfo; + // channel info for the worker script. + channelInfo = mWorkerChannelInfo; } - nsresult rv = NS_DeserializeObject(securityInfo, getter_AddRefs(infoObj)); - if (NS_SUCCEEDED(rv)) { - rv = mChannel->SetSecurityInfo(infoObj); - if (NS_WARN_IF(NS_FAILED(rv))) { - return rv; - } + nsresult rv = mChannel->SetChannelInfo(&channelInfo); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; } mChannel->SynthesizeStatus(mInternalResponse->GetStatus(), mInternalResponse->GetStatusText()); @@ -169,14 +167,14 @@ struct RespondWithClosure { nsMainThreadPtrHandle mInterceptedChannel; nsRefPtr mInternalResponse; - nsCString mWorkerSecurityInfo; + ChannelInfo mWorkerChannelInfo; RespondWithClosure(nsMainThreadPtrHandle& aChannel, InternalResponse* aInternalResponse, - const nsCString& aWorkerSecurityInfo) + const ChannelInfo& aWorkerChannelInfo) : mInterceptedChannel(aChannel) , mInternalResponse(aInternalResponse) - , mWorkerSecurityInfo(aWorkerSecurityInfo) + , mWorkerChannelInfo(aWorkerChannelInfo) { } }; @@ -188,7 +186,7 @@ void RespondWithCopyComplete(void* aClosure, nsresult aStatus) if (NS_SUCCEEDED(aStatus)) { event = new FinishResponse(data->mInterceptedChannel, data->mInternalResponse, - data->mWorkerSecurityInfo); + data->mWorkerChannelInfo); } else { event = new CancelChannelRunnable(data->mInterceptedChannel); } @@ -255,7 +253,7 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle aValu worker->AssertIsOnWorkerThread(); nsAutoPtr closure( - new RespondWithClosure(mInterceptedChannel, ir, worker->GetSecurityInfo())); + new RespondWithClosure(mInterceptedChannel, ir, worker->GetChannelInfo())); nsCOMPtr body; response->GetBody(getter_AddRefs(body)); // Errors and redirects may not have a body. diff --git a/dom/workers/ServiceWorkerScriptCache.cpp b/dom/workers/ServiceWorkerScriptCache.cpp index 15d3824264b5..cf1c999c4f1b 100644 --- a/dom/workers/ServiceWorkerScriptCache.cpp +++ b/dom/workers/ServiceWorkerScriptCache.cpp @@ -10,7 +10,6 @@ #include "mozilla/dom/cache/CacheStorage.h" #include "mozilla/dom/cache/Cache.h" #include "nsIThreadRetargetableRequest.h" -#include "nsSerializationHelper.h" #include "nsIPrincipal.h" #include "Workers.h" @@ -446,9 +445,9 @@ public: } void - SetSecurityInfo(nsISerializable* aSecurityInfo) + InitChannelInfo(nsIChannel* aChannel) { - NS_SerializeToString(aSecurityInfo, mSecurityInfo); + mChannelInfo.InitFromChannel(aChannel); } private: @@ -545,7 +544,7 @@ private: new InternalResponse(200, NS_LITERAL_CSTRING("OK")); ir->SetBody(body); - ir->SetSecurityInfo(mSecurityInfo); + ir->InitChannelInfo(mChannelInfo); nsRefPtr response = new Response(aCache->GetGlobalObject(), ir); @@ -577,7 +576,7 @@ private: // Only used if the network script has changed and needs to be cached. nsString mNewCacheName; - nsCString mSecurityInfo; + ChannelInfo mChannelInfo; nsCString mMaxScope; @@ -606,16 +605,7 @@ CompareNetwork::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext) MOZ_ASSERT(channel == mChannel); #endif - nsCOMPtr infoObj; - mChannel->GetSecurityInfo(getter_AddRefs(infoObj)); - if (infoObj) { - nsCOMPtr serializable = do_QueryInterface(infoObj); - if (serializable) { - mManager->SetSecurityInfo(serializable); - } else { - NS_WARNING("A non-serializable object was obtained from nsIChannel::GetSecurityInfo()!"); - } - } + mManager->InitChannelInfo(mChannel); return NS_OK; } diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index b1f6b96d5e7c..5db34b0d211c 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -32,7 +32,6 @@ #include "nsIXPConnect.h" #include "nsPerformance.h" #include "nsPIDOMWindow.h" -#include "nsSerializationHelper.h" #include #include "jsfriendapi.h" @@ -4075,17 +4074,6 @@ WorkerPrivateParent::SetPrincipal(nsIPrincipal* aPrincipal, PrincipalToPrincipalInfo(aPrincipal, mLoadInfo.mPrincipalInfo))); } -template -void -WorkerPrivateParent::SetSecurityInfo(nsISerializable* aSerializable) -{ - MOZ_ASSERT(IsServiceWorker()); - AssertIsOnMainThread(); - nsAutoCString securityInfo; - NS_SerializeToString(aSerializable, securityInfo); - SetSecurityInfo(securityInfo); -} - template JSContext* WorkerPrivateParent::ParentJSContext() const diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h index 7f48b95da1e0..ef04c31ba4e1 100644 --- a/dom/workers/WorkerPrivate.h +++ b/dom/workers/WorkerPrivate.h @@ -498,24 +498,34 @@ public: return mLoadInfo.mServiceWorkerCacheName; } - const nsCString& - GetSecurityInfo() const + const ChannelInfo& + GetChannelInfo() const { MOZ_ASSERT(IsServiceWorker()); - return mLoadInfo.mSecurityInfo; + return mLoadInfo.mChannelInfo; } void - SetSecurityInfo(const nsCString& aSecurityInfo) + SetChannelInfo(const ChannelInfo& aChannelInfo) { MOZ_ASSERT(IsServiceWorker()); AssertIsOnMainThread(); - MOZ_ASSERT(mLoadInfo.mSecurityInfo.IsEmpty()); - mLoadInfo.mSecurityInfo = aSecurityInfo; + MOZ_ASSERT(!mLoadInfo.mChannelInfo.IsInitialized()); + MOZ_ASSERT(aChannelInfo.IsInitialized()); + mLoadInfo.mChannelInfo = aChannelInfo; } void - SetSecurityInfo(nsISerializable* aSerializable); + InitChannelInfo(nsIChannel* aChannel) + { + mLoadInfo.mChannelInfo.InitFromChannel(aChannel); + } + + void + InitChannelInfo(const ChannelInfo& aChannelInfo) + { + mLoadInfo.mChannelInfo = aChannelInfo; + } // This is used to handle importScripts(). When the worker is first loaded // and executed, it happens in a sync loop. At this point it sets diff --git a/dom/workers/Workers.h b/dom/workers/Workers.h index 19029ec629db..c25c11f45af1 100644 --- a/dom/workers/Workers.h +++ b/dom/workers/Workers.h @@ -20,6 +20,7 @@ #include "nsILoadContext.h" #include "nsIWeakReferenceUtils.h" #include "nsIInterfaceRequestor.h" +#include "mozilla/dom/ChannelInfo.h" #define BEGIN_WORKERS_NAMESPACE \ namespace mozilla { namespace dom { namespace workers { @@ -244,7 +245,7 @@ struct WorkerLoadInfo nsString mServiceWorkerCacheName; - nsCString mSecurityInfo; + ChannelInfo mChannelInfo; uint64_t mWindowID; uint64_t mServiceWorkerID; diff --git a/netwerk/base/nsINetworkInterceptController.idl b/netwerk/base/nsINetworkInterceptController.idl index 6295fc38c2a7..a816931ae485 100644 --- a/netwerk/base/nsINetworkInterceptController.idl +++ b/netwerk/base/nsINetworkInterceptController.idl @@ -9,6 +9,16 @@ interface nsIChannel; interface nsIOutputStream; interface nsIURI; +%{C++ +namespace mozilla { +namespace dom { +class ChannelInfo; +} +} +%} + +[ptr] native ChannelInfo(mozilla::dom::ChannelInfo); + /** * Interface to allow implementors of nsINetworkInterceptController to control the behaviour * of intercepted channels without tying implementation details of the interception to @@ -16,7 +26,7 @@ interface nsIURI; * which do not implement nsIChannel. */ -[scriptable, uuid(2fc1170c-4f9d-4c9e-8e5d-2d351dbe03f2)] +[scriptable, uuid(f2c07a6b-366d-4ef4-85ab-a77f4bcb1646)] interface nsIInterceptedChannel : nsISupports { /** @@ -67,9 +77,10 @@ interface nsIInterceptedChannel : nsISupports readonly attribute bool isNavigation; /** - * This method allows to override the security info for the channel. + * This method allows to override the channel info for the channel. */ - void setSecurityInfo(in nsISupports securityInfo); + [noscript] + void setChannelInfo(in ChannelInfo channelInfo); }; /** diff --git a/netwerk/protocol/http/InterceptedChannel.cpp b/netwerk/protocol/http/InterceptedChannel.cpp index 6e2dd240789f..2518fcb9c6b7 100644 --- a/netwerk/protocol/http/InterceptedChannel.cpp +++ b/netwerk/protocol/http/InterceptedChannel.cpp @@ -13,6 +13,7 @@ #include "nsHttpChannel.h" #include "HttpChannelChild.h" #include "nsHttpResponseHead.h" +#include "mozilla/dom/ChannelInfo.h" namespace mozilla { namespace net { @@ -233,13 +234,13 @@ InterceptedChannelChrome::Cancel() } NS_IMETHODIMP -InterceptedChannelChrome::SetSecurityInfo(nsISupports* aSecurityInfo) +InterceptedChannelChrome::SetChannelInfo(dom::ChannelInfo* aChannelInfo) { if (!mChannel) { return NS_ERROR_FAILURE; } - return mChannel->OverrideSecurityInfo(aSecurityInfo); + return aChannelInfo->ResurrectInfoOnChannel(mChannel); } InterceptedChannelContent::InterceptedChannelContent(HttpChannelChild* aChannel, @@ -340,13 +341,13 @@ InterceptedChannelContent::Cancel() } NS_IMETHODIMP -InterceptedChannelContent::SetSecurityInfo(nsISupports* aSecurityInfo) +InterceptedChannelContent::SetChannelInfo(dom::ChannelInfo* aChannelInfo) { if (!mChannel) { return NS_ERROR_FAILURE; } - return mChannel->OverrideSecurityInfo(aSecurityInfo); + return aChannelInfo->ResurrectInfoOnChannel(mChannel); } } // namespace net diff --git a/netwerk/protocol/http/InterceptedChannel.h b/netwerk/protocol/http/InterceptedChannel.h index c98d78a12ecc..0131633be256 100644 --- a/netwerk/protocol/http/InterceptedChannel.h +++ b/netwerk/protocol/http/InterceptedChannel.h @@ -82,7 +82,7 @@ public: NS_IMETHOD SynthesizeStatus(uint16_t aStatus, const nsACString& aReason) override; NS_IMETHOD SynthesizeHeader(const nsACString& aName, const nsACString& aValue) override; NS_IMETHOD Cancel() override; - NS_IMETHOD SetSecurityInfo(nsISupports* aSecurityInfo) override; + NS_IMETHOD SetChannelInfo(mozilla::dom::ChannelInfo* aChannelInfo) override; virtual void NotifyController() override; }; @@ -109,7 +109,7 @@ public: NS_IMETHOD SynthesizeStatus(uint16_t aStatus, const nsACString& aReason) override; NS_IMETHOD SynthesizeHeader(const nsACString& aName, const nsACString& aValue) override; NS_IMETHOD Cancel() override; - NS_IMETHOD SetSecurityInfo(nsISupports* aSecurityInfo) override; + NS_IMETHOD SetChannelInfo(mozilla::dom::ChannelInfo* aChannelInfo) override; virtual void NotifyController() override; }; diff --git a/netwerk/protocol/http/TunnelUtils.h b/netwerk/protocol/http/TunnelUtils.h index 2c2ef663348d..553697aadac0 100644 --- a/netwerk/protocol/http/TunnelUtils.h +++ b/netwerk/protocol/http/TunnelUtils.h @@ -15,6 +15,7 @@ #include "nsITimer.h" #include "NullHttpTransaction.h" #include "mozilla/TimeStamp.h" +#include "prio.h" // a TLSFilterTransaction wraps another nsAHttpTransaction but // applies a encode/decode filter of TLS onto the ReadSegments diff --git a/netwerk/protocol/http/nsHttpConnectionInfo.h b/netwerk/protocol/http/nsHttpConnectionInfo.h index d25f2e12721c..5682bd191938 100644 --- a/netwerk/protocol/http/nsHttpConnectionInfo.h +++ b/netwerk/protocol/http/nsHttpConnectionInfo.h @@ -11,6 +11,7 @@ #include "nsProxyInfo.h" #include "nsCOMPtr.h" #include "nsStringFwd.h" +#include "mozilla/Logging.h" extern PRLogModuleInfo *gHttpLog;