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

This commit is contained in:
Ehsan Akhgari
2015-05-25 14:21:05 -04:00
parent 070caf25e5
commit f770eb78bf
22 changed files with 327 additions and 140 deletions

View File

@@ -6,6 +6,7 @@ include protocol PCache;
include protocol PCachePushStream; include protocol PCachePushStream;
include protocol PCacheStreamControl; include protocol PCacheStreamControl;
include InputStreamParams; include InputStreamParams;
include ChannelInfo;
using HeadersGuardEnum from "mozilla/dom/cache/IPCUtils.h"; using HeadersGuardEnum from "mozilla/dom/cache/IPCUtils.h";
using RequestCredentials from "mozilla/dom/cache/IPCUtils.h"; using RequestCredentials from "mozilla/dom/cache/IPCUtils.h";
@@ -81,7 +82,7 @@ struct CacheResponse
HeadersEntry[] headers; HeadersEntry[] headers;
HeadersGuardEnum headersGuard; HeadersGuardEnum headersGuard;
CacheReadStreamOrVoid body; CacheReadStreamOrVoid body;
nsCString securityInfo; IPCChannelInfo channelInfo;
}; };
union CacheResponseOrVoid union CacheResponseOrVoid

View File

@@ -175,7 +175,7 @@ static nsresult DeleteEntries(mozIStorageConnection* aConn,
nsTArray<nsID>& aDeletedBodyIdListOut, nsTArray<nsID>& aDeletedBodyIdListOut,
nsTArray<IdCount>& aDeletedSecurityIdListOut, nsTArray<IdCount>& aDeletedSecurityIdListOut,
uint32_t aPos=0, int32_t aLen=-1); uint32_t aPos=0, int32_t aLen=-1);
static nsresult InsertSecurity(mozIStorageConnection* aConn, static nsresult InsertSecurityInfo(mozIStorageConnection* aConn,
const nsACString& aData, int32_t *aIdOut); const nsACString& aData, int32_t *aIdOut);
static nsresult DeleteSecurityInfo(mozIStorageConnection* aConn, int32_t aId, static nsresult DeleteSecurityInfo(mozIStorageConnection* aConn, int32_t aId,
int32_t aCount); int32_t aCount);
@@ -1194,7 +1194,7 @@ DeleteEntries(mozIStorageConnection* aConn,
} }
nsresult nsresult
InsertSecurity(mozIStorageConnection* aConn, const nsACString& aData, InsertSecurityInfo(mozIStorageConnection* aConn, const nsACString& aData,
int32_t *aIdOut) int32_t *aIdOut)
{ {
MOZ_ASSERT(aConn); MOZ_ASSERT(aConn);
@@ -1394,8 +1394,10 @@ InsertEntry(mozIStorageConnection* aConn, CacheId aCacheId,
nsresult rv = NS_OK; nsresult rv = NS_OK;
int32_t securityId = -1; int32_t securityId = -1;
if (!aResponse.securityInfo().IsEmpty()) { if (!aResponse.channelInfo().securityInfo().IsEmpty()) {
rv = InsertSecurity(aConn, aResponse.securityInfo(), &securityId); rv = InsertSecurityInfo(aConn,
aResponse.channelInfo().securityInfo(),
&securityId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } 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); rv = BindId(state, NS_LITERAL_CSTRING("response_body_id"), aResponseBodyId);
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } 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")); rv = state->BindNullByName(NS_LITERAL_CSTRING("response_security_info_id"));
} else { } else {
rv = state->BindInt32ByName(NS_LITERAL_CSTRING("response_security_info_id"), 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; } 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; } if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
rv = aConn->CreateStatement(NS_LITERAL_CSTRING( rv = aConn->CreateStatement(NS_LITERAL_CSTRING(

View File

@@ -224,7 +224,7 @@ TypeUtils::ToCacheResponseWithoutBody(CacheResponse& aOut,
} }
ToHeadersEntryList(aOut.headers(), headers); ToHeadersEntryList(aOut.headers(), headers);
aOut.headersGuard() = headers->Guard(); aOut.headersGuard() = headers->Guard();
aOut.securityInfo() = aIn.GetSecurityInfo(); aOut.channelInfo() = aIn.GetChannelInfo().AsIPCChannelInfo();
} }
void void
@@ -290,7 +290,7 @@ TypeUtils::ToResponse(const CacheResponse& aIn)
ir->Headers()->Fill(*internalHeaders, result); ir->Headers()->Fill(*internalHeaders, result);
MOZ_ASSERT(!result.Failed()); MOZ_ASSERT(!result.Failed());
ir->SetSecurityInfo(aIn.securityInfo()); ir->InitChannelInfo(aIn.channelInfo());
nsCOMPtr<nsIInputStream> stream = ReadStream::Create(aIn.body()); nsCOMPtr<nsIInputStream> stream = ReadStream::Create(aIn.body());
ir->SetBody(stream); ir->SetBody(stream);

94
dom/fetch/ChannelInfo.cpp Normal file
View File

@@ -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<nsISupports> 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<nsISerializable> 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<nsISupports> infoObj;
nsresult rv = NS_DeserializeObject(mSecurityInfo, getter_AddRefs(infoObj));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<nsIHttpChannel> httpChannel =
do_QueryInterface(aChannel);
if (NS_WARN_IF(!httpChannel)) {
return NS_ERROR_FAILURE;
}
net::HttpBaseChannel* httpBaseChannel =
static_cast<net::HttpBaseChannel*>(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;
}

87
dom/fetch/ChannelInfo.h Normal file
View File

@@ -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

View File

@@ -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

View File

@@ -706,12 +706,8 @@ FetchDriver::OnStartRequest(nsIRequest* aRequest,
} }
response->SetBody(pipeInputStream); response->SetBody(pipeInputStream);
nsCOMPtr<nsISupports> securityInfo;
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest); nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
rv = channel->GetSecurityInfo(getter_AddRefs(securityInfo)); response->InitChannelInfo(channel);
if (securityInfo) {
response->SetSecurityInfo(securityInfo);
}
// Resolves fetch() promise which may trigger code running in a worker. Make // Resolves fetch() promise which may trigger code running in a worker. Make
// sure the Response is fully initialized before calling this. // sure the Response is fully initialized before calling this.

View File

@@ -8,7 +8,6 @@
#include "mozilla/dom/InternalHeaders.h" #include "mozilla/dom/InternalHeaders.h"
#include "nsStreamUtils.h" #include "nsStreamUtils.h"
#include "nsSerializationHelper.h"
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
@@ -75,24 +74,5 @@ InternalResponse::CORSResponse()
return cors.forget(); return cors.forget();
} }
void
InternalResponse::SetSecurityInfo(nsISupports* aSecurityInfo)
{
MOZ_ASSERT(mSecurityInfo.IsEmpty(), "security info should only be set once");
nsCOMPtr<nsISerializable> 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 dom
} // namespace mozilla } // namespace mozilla

View File

@@ -11,6 +11,7 @@
#include "nsISupportsImpl.h" #include "nsISupportsImpl.h"
#include "mozilla/dom/ResponseBinding.h" #include "mozilla/dom/ResponseBinding.h"
#include "mozilla/dom/ChannelInfo.h"
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {
@@ -48,7 +49,7 @@ public:
response->mTerminationReason = mTerminationReason; response->mTerminationReason = mTerminationReason;
response->mURL = mURL; response->mURL = mURL;
response->mFinalURL = mFinalURL; response->mFinalURL = mFinalURL;
response->mSecurityInfo = mSecurityInfo; response->mChannelInfo = mChannelInfo;
response->mWrappedResponse = this; response->mWrappedResponse = this;
return response.forget(); return response.forget();
} }
@@ -156,17 +157,29 @@ public:
mBody = aBody; mBody = aBody;
} }
const nsCString& void
GetSecurityInfo() const InitChannelInfo(nsIChannel* aChannel)
{ {
return mSecurityInfo; mChannelInfo.InitFromChannel(aChannel);
} }
void void
SetSecurityInfo(nsISupports* aSecurityInfo); InitChannelInfo(const mozilla::ipc::IPCChannelInfo& aChannelInfo)
{
mChannelInfo.InitFromIPCChannelInfo(aChannelInfo);
}
void void
SetSecurityInfo(const nsCString& aSecurityInfo); InitChannelInfo(const ChannelInfo& aChannelInfo)
{
mChannelInfo = aChannelInfo;
}
const ChannelInfo&
GetChannelInfo() const
{
return mChannelInfo;
}
private: private:
~InternalResponse() ~InternalResponse()
@@ -185,7 +198,7 @@ private:
copy->mTerminationReason = mTerminationReason; copy->mTerminationReason = mTerminationReason;
copy->mURL = mURL; copy->mURL = mURL;
copy->mFinalURL = mFinalURL; copy->mFinalURL = mFinalURL;
copy->mSecurityInfo = mSecurityInfo; copy->mChannelInfo = mChannelInfo;
return copy.forget(); return copy.forget();
} }
@@ -197,7 +210,7 @@ private:
const nsCString mStatusText; const nsCString mStatusText;
nsRefPtr<InternalHeaders> mHeaders; nsRefPtr<InternalHeaders> mHeaders;
nsCOMPtr<nsIInputStream> mBody; nsCOMPtr<nsIInputStream> mBody;
nsCString mSecurityInfo; ChannelInfo mChannelInfo;
// For filtered responses. // For filtered responses.
// Cache, and SW interception should always serialize/access the underlying // Cache, and SW interception should always serialize/access the underlying

View File

@@ -78,10 +78,16 @@ public:
return mInternalResponse->Headers(); return mInternalResponse->Headers();
} }
const nsCString& void
GetSecurityInfo() const InitChannelInfo(nsIChannel* aChannel)
{ {
return mInternalResponse->GetSecurityInfo(); mInternalResponse->InitChannelInfo(aChannel);
}
const ChannelInfo&
GetChannelInfo() const
{
return mInternalResponse->GetChannelInfo();
} }
Headers* Headers_(); Headers* Headers_();

View File

@@ -5,6 +5,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS.mozilla.dom += [ EXPORTS.mozilla.dom += [
'ChannelInfo.h',
'Fetch.h', 'Fetch.h',
'FetchDriver.h', 'FetchDriver.h',
'Headers.h', 'Headers.h',
@@ -16,6 +17,7 @@ EXPORTS.mozilla.dom += [
] ]
UNIFIED_SOURCES += [ UNIFIED_SOURCES += [
'ChannelInfo.cpp',
'Fetch.cpp', 'Fetch.cpp',
'FetchDriver.cpp', 'FetchDriver.cpp',
'Headers.cpp', 'Headers.cpp',
@@ -26,11 +28,21 @@ UNIFIED_SOURCES += [
'Response.cpp', 'Response.cpp',
] ]
IPDL_SOURCES += [
'ChannelInfo.ipdlh',
]
LOCAL_INCLUDES += [ LOCAL_INCLUDES += [
'../workers', '../workers',
# For HttpBaseChannel.h dependencies
'/netwerk/base',
# For nsDataHandler.h # For nsDataHandler.h
'/netwerk/protocol/data', '/netwerk/protocol/data',
# For HttpBaseChannel.h
'/netwerk/protocol/http',
] ]
FAIL_ON_WARNINGS = True FAIL_ON_WARNINGS = True
FINAL_LIBRARY = 'xul' FINAL_LIBRARY = 'xul'
include('/ipc/chromium/chromium-config.mozbuild')

View File

@@ -14,7 +14,6 @@
#include "nsIIOService.h" #include "nsIIOService.h"
#include "nsIProtocolHandler.h" #include "nsIProtocolHandler.h"
#include "nsIScriptSecurityManager.h" #include "nsIScriptSecurityManager.h"
#include "nsISerializable.h"
#include "nsIStreamLoader.h" #include "nsIStreamLoader.h"
#include "nsIStreamListenerTee.h" #include "nsIStreamListenerTee.h"
#include "nsIThreadRetargetableRequest.h" #include "nsIThreadRetargetableRequest.h"
@@ -422,7 +421,7 @@ private:
bool mFailed; bool mFailed;
nsCOMPtr<nsIInputStreamPump> mPump; nsCOMPtr<nsIInputStreamPump> mPump;
nsCOMPtr<nsIURI> mBaseURI; nsCOMPtr<nsIURI> mBaseURI;
nsCString mSecurityInfo; ChannelInfo mChannelInfo;
}; };
NS_IMPL_ISUPPORTS(CacheScriptLoader, nsIStreamLoaderObserver) NS_IMPL_ISUPPORTS(CacheScriptLoader, nsIStreamLoaderObserver)
@@ -589,19 +588,9 @@ private:
new InternalResponse(200, NS_LITERAL_CSTRING("OK")); new InternalResponse(200, NS_LITERAL_CSTRING("OK"));
ir->SetBody(mReader); 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. // saved in the cache.
nsCOMPtr<nsISupports> infoObj; ir->InitChannelInfo(channel);
channel->GetSecurityInfo(getter_AddRefs(infoObj));
if (infoObj) {
nsCOMPtr<nsISerializable> 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()!");
}
}
nsRefPtr<Response> response = new Response(mCacheCreator->Global(), ir); nsRefPtr<Response> response = new Response(mCacheCreator->Global(), ir);
@@ -965,18 +954,9 @@ private:
// Take care of the base URI first. // Take care of the base URI first.
mWorkerPrivate->SetBaseURI(finalURI); mWorkerPrivate->SetBaseURI(finalURI);
// Store the security info if needed. // Store the channel info if needed.
if (mWorkerPrivate->IsServiceWorker()) { if (mWorkerPrivate->IsServiceWorker()) {
nsCOMPtr<nsISupports> infoObj; mWorkerPrivate->InitChannelInfo(channel);
channel->GetSecurityInfo(getter_AddRefs(infoObj));
if (infoObj) {
nsCOMPtr<nsISerializable> serializable = do_QueryInterface(infoObj);
if (serializable) {
mWorkerPrivate->SetSecurityInfo(serializable);
} else {
NS_WARNING("A non-serializable object was obtained from nsIChannel::GetSecurityInfo()!");
}
}
} }
// Now to figure out which principal to give this worker. // Now to figure out which principal to give this worker.
@@ -1047,7 +1027,8 @@ private:
void void
DataReceivedFromCache(uint32_t aIndex, const uint8_t* aString, DataReceivedFromCache(uint32_t aIndex, const uint8_t* aString,
uint32_t aStringLen, const nsCString& aSecurityInfo) uint32_t aStringLen,
const ChannelInfo& aChannelInfo)
{ {
AssertIsOnMainThread(); AssertIsOnMainThread();
MOZ_ASSERT(aIndex < mLoadInfos.Length()); MOZ_ASSERT(aIndex < mLoadInfos.Length());
@@ -1075,7 +1056,7 @@ private:
MOZ_ASSERT(principal); MOZ_ASSERT(principal);
nsILoadGroup* loadGroup = mWorkerPrivate->GetLoadGroup(); nsILoadGroup* loadGroup = mWorkerPrivate->GetLoadGroup();
MOZ_ASSERT(loadGroup); MOZ_ASSERT(loadGroup);
mWorkerPrivate->SetSecurityInfo(aSecurityInfo); mWorkerPrivate->InitChannelInfo(aChannelInfo);
// Needed to initialize the principal info. This is fine because // Needed to initialize the principal info. This is fine because
// the cache principal cannot change, unlike the channel principal. // the cache principal cannot change, unlike the channel principal.
mWorkerPrivate->SetPrincipal(principal, loadGroup); mWorkerPrivate->SetPrincipal(principal, loadGroup);
@@ -1429,11 +1410,11 @@ CacheScriptLoader::ResolvedCallback(JSContext* aCx,
nsCOMPtr<nsIInputStream> inputStream; nsCOMPtr<nsIInputStream> inputStream;
response->GetBody(getter_AddRefs(inputStream)); response->GetBody(getter_AddRefs(inputStream));
mSecurityInfo = response->GetSecurityInfo(); mChannelInfo = response->GetChannelInfo();
if (!inputStream) { if (!inputStream) {
mLoadInfo.mCacheStatus = ScriptLoadInfo::Cached; mLoadInfo.mCacheStatus = ScriptLoadInfo::Cached;
mRunnable->DataReceivedFromCache(mIndex, (uint8_t*)"", 0, mSecurityInfo); mRunnable->DataReceivedFromCache(mIndex, (uint8_t*)"", 0, mChannelInfo);
return; return;
} }
@@ -1489,7 +1470,7 @@ CacheScriptLoader::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aCont
mLoadInfo.mCacheStatus = ScriptLoadInfo::Cached; mLoadInfo.mCacheStatus = ScriptLoadInfo::Cached;
mRunnable->DataReceivedFromCache(mIndex, aString, aStringLen, mSecurityInfo); mRunnable->DataReceivedFromCache(mIndex, aString, aStringLen, mChannelInfo);
return NS_OK; return NS_OK;
} }

View File

@@ -98,14 +98,14 @@ class FinishResponse final : public nsRunnable
{ {
nsMainThreadPtrHandle<nsIInterceptedChannel> mChannel; nsMainThreadPtrHandle<nsIInterceptedChannel> mChannel;
nsRefPtr<InternalResponse> mInternalResponse; nsRefPtr<InternalResponse> mInternalResponse;
nsCString mWorkerSecurityInfo; ChannelInfo mWorkerChannelInfo;
public: public:
FinishResponse(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel, FinishResponse(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
InternalResponse* aInternalResponse, InternalResponse* aInternalResponse,
const nsCString& aWorkerSecurityInfo) const ChannelInfo& aWorkerChannelInfo)
: mChannel(aChannel) : mChannel(aChannel)
, mInternalResponse(aInternalResponse) , mInternalResponse(aInternalResponse)
, mWorkerSecurityInfo(aWorkerSecurityInfo) , mWorkerChannelInfo(aWorkerChannelInfo)
{ {
} }
@@ -114,20 +114,18 @@ public:
{ {
AssertIsOnMainThread(); AssertIsOnMainThread();
nsCOMPtr<nsISupports> infoObj; ChannelInfo channelInfo;
nsAutoCString securityInfo(mInternalResponse->GetSecurityInfo()); if (mInternalResponse->GetChannelInfo().IsInitialized()) {
if (securityInfo.IsEmpty()) { channelInfo = mInternalResponse->GetChannelInfo();
} else {
// We are dealing with a synthesized response here, so fall back to the // We are dealing with a synthesized response here, so fall back to the
// security info for the worker script. // channel info for the worker script.
securityInfo = mWorkerSecurityInfo; channelInfo = mWorkerChannelInfo;
} }
nsresult rv = NS_DeserializeObject(securityInfo, getter_AddRefs(infoObj)); nsresult rv = mChannel->SetChannelInfo(&channelInfo);
if (NS_SUCCEEDED(rv)) {
rv = mChannel->SetSecurityInfo(infoObj);
if (NS_WARN_IF(NS_FAILED(rv))) { if (NS_WARN_IF(NS_FAILED(rv))) {
return rv; return rv;
} }
}
mChannel->SynthesizeStatus(mInternalResponse->GetStatus(), mInternalResponse->GetStatusText()); mChannel->SynthesizeStatus(mInternalResponse->GetStatus(), mInternalResponse->GetStatusText());
@@ -169,14 +167,14 @@ struct RespondWithClosure
{ {
nsMainThreadPtrHandle<nsIInterceptedChannel> mInterceptedChannel; nsMainThreadPtrHandle<nsIInterceptedChannel> mInterceptedChannel;
nsRefPtr<InternalResponse> mInternalResponse; nsRefPtr<InternalResponse> mInternalResponse;
nsCString mWorkerSecurityInfo; ChannelInfo mWorkerChannelInfo;
RespondWithClosure(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel, RespondWithClosure(nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
InternalResponse* aInternalResponse, InternalResponse* aInternalResponse,
const nsCString& aWorkerSecurityInfo) const ChannelInfo& aWorkerChannelInfo)
: mInterceptedChannel(aChannel) : mInterceptedChannel(aChannel)
, mInternalResponse(aInternalResponse) , mInternalResponse(aInternalResponse)
, mWorkerSecurityInfo(aWorkerSecurityInfo) , mWorkerChannelInfo(aWorkerChannelInfo)
{ {
} }
}; };
@@ -188,7 +186,7 @@ void RespondWithCopyComplete(void* aClosure, nsresult aStatus)
if (NS_SUCCEEDED(aStatus)) { if (NS_SUCCEEDED(aStatus)) {
event = new FinishResponse(data->mInterceptedChannel, event = new FinishResponse(data->mInterceptedChannel,
data->mInternalResponse, data->mInternalResponse,
data->mWorkerSecurityInfo); data->mWorkerChannelInfo);
} else { } else {
event = new CancelChannelRunnable(data->mInterceptedChannel); event = new CancelChannelRunnable(data->mInterceptedChannel);
} }
@@ -255,7 +253,7 @@ RespondWithHandler::ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValu
worker->AssertIsOnWorkerThread(); worker->AssertIsOnWorkerThread();
nsAutoPtr<RespondWithClosure> closure( nsAutoPtr<RespondWithClosure> closure(
new RespondWithClosure(mInterceptedChannel, ir, worker->GetSecurityInfo())); new RespondWithClosure(mInterceptedChannel, ir, worker->GetChannelInfo()));
nsCOMPtr<nsIInputStream> body; nsCOMPtr<nsIInputStream> body;
response->GetBody(getter_AddRefs(body)); response->GetBody(getter_AddRefs(body));
// Errors and redirects may not have a body. // Errors and redirects may not have a body.

View File

@@ -10,7 +10,6 @@
#include "mozilla/dom/cache/CacheStorage.h" #include "mozilla/dom/cache/CacheStorage.h"
#include "mozilla/dom/cache/Cache.h" #include "mozilla/dom/cache/Cache.h"
#include "nsIThreadRetargetableRequest.h" #include "nsIThreadRetargetableRequest.h"
#include "nsSerializationHelper.h"
#include "nsIPrincipal.h" #include "nsIPrincipal.h"
#include "Workers.h" #include "Workers.h"
@@ -446,9 +445,9 @@ public:
} }
void void
SetSecurityInfo(nsISerializable* aSecurityInfo) InitChannelInfo(nsIChannel* aChannel)
{ {
NS_SerializeToString(aSecurityInfo, mSecurityInfo); mChannelInfo.InitFromChannel(aChannel);
} }
private: private:
@@ -545,7 +544,7 @@ private:
new InternalResponse(200, NS_LITERAL_CSTRING("OK")); new InternalResponse(200, NS_LITERAL_CSTRING("OK"));
ir->SetBody(body); ir->SetBody(body);
ir->SetSecurityInfo(mSecurityInfo); ir->InitChannelInfo(mChannelInfo);
nsRefPtr<Response> response = new Response(aCache->GetGlobalObject(), ir); nsRefPtr<Response> response = new Response(aCache->GetGlobalObject(), ir);
@@ -577,7 +576,7 @@ private:
// Only used if the network script has changed and needs to be cached. // Only used if the network script has changed and needs to be cached.
nsString mNewCacheName; nsString mNewCacheName;
nsCString mSecurityInfo; ChannelInfo mChannelInfo;
nsCString mMaxScope; nsCString mMaxScope;
@@ -606,16 +605,7 @@ CompareNetwork::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
MOZ_ASSERT(channel == mChannel); MOZ_ASSERT(channel == mChannel);
#endif #endif
nsCOMPtr<nsISupports> infoObj; mManager->InitChannelInfo(mChannel);
mChannel->GetSecurityInfo(getter_AddRefs(infoObj));
if (infoObj) {
nsCOMPtr<nsISerializable> serializable = do_QueryInterface(infoObj);
if (serializable) {
mManager->SetSecurityInfo(serializable);
} else {
NS_WARNING("A non-serializable object was obtained from nsIChannel::GetSecurityInfo()!");
}
}
return NS_OK; return NS_OK;
} }

View File

@@ -32,7 +32,6 @@
#include "nsIXPConnect.h" #include "nsIXPConnect.h"
#include "nsPerformance.h" #include "nsPerformance.h"
#include "nsPIDOMWindow.h" #include "nsPIDOMWindow.h"
#include "nsSerializationHelper.h"
#include <algorithm> #include <algorithm>
#include "jsfriendapi.h" #include "jsfriendapi.h"
@@ -4075,17 +4074,6 @@ WorkerPrivateParent<Derived>::SetPrincipal(nsIPrincipal* aPrincipal,
PrincipalToPrincipalInfo(aPrincipal, mLoadInfo.mPrincipalInfo))); PrincipalToPrincipalInfo(aPrincipal, mLoadInfo.mPrincipalInfo)));
} }
template <class Derived>
void
WorkerPrivateParent<Derived>::SetSecurityInfo(nsISerializable* aSerializable)
{
MOZ_ASSERT(IsServiceWorker());
AssertIsOnMainThread();
nsAutoCString securityInfo;
NS_SerializeToString(aSerializable, securityInfo);
SetSecurityInfo(securityInfo);
}
template <class Derived> template <class Derived>
JSContext* JSContext*
WorkerPrivateParent<Derived>::ParentJSContext() const WorkerPrivateParent<Derived>::ParentJSContext() const

View File

@@ -498,24 +498,34 @@ public:
return mLoadInfo.mServiceWorkerCacheName; return mLoadInfo.mServiceWorkerCacheName;
} }
const nsCString& const ChannelInfo&
GetSecurityInfo() const GetChannelInfo() const
{ {
MOZ_ASSERT(IsServiceWorker()); MOZ_ASSERT(IsServiceWorker());
return mLoadInfo.mSecurityInfo; return mLoadInfo.mChannelInfo;
} }
void void
SetSecurityInfo(const nsCString& aSecurityInfo) SetChannelInfo(const ChannelInfo& aChannelInfo)
{ {
MOZ_ASSERT(IsServiceWorker()); MOZ_ASSERT(IsServiceWorker());
AssertIsOnMainThread(); AssertIsOnMainThread();
MOZ_ASSERT(mLoadInfo.mSecurityInfo.IsEmpty()); MOZ_ASSERT(!mLoadInfo.mChannelInfo.IsInitialized());
mLoadInfo.mSecurityInfo = aSecurityInfo; MOZ_ASSERT(aChannelInfo.IsInitialized());
mLoadInfo.mChannelInfo = aChannelInfo;
} }
void 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 // 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 // and executed, it happens in a sync loop. At this point it sets

View File

@@ -20,6 +20,7 @@
#include "nsILoadContext.h" #include "nsILoadContext.h"
#include "nsIWeakReferenceUtils.h" #include "nsIWeakReferenceUtils.h"
#include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestor.h"
#include "mozilla/dom/ChannelInfo.h"
#define BEGIN_WORKERS_NAMESPACE \ #define BEGIN_WORKERS_NAMESPACE \
namespace mozilla { namespace dom { namespace workers { namespace mozilla { namespace dom { namespace workers {
@@ -244,7 +245,7 @@ struct WorkerLoadInfo
nsString mServiceWorkerCacheName; nsString mServiceWorkerCacheName;
nsCString mSecurityInfo; ChannelInfo mChannelInfo;
uint64_t mWindowID; uint64_t mWindowID;
uint64_t mServiceWorkerID; uint64_t mServiceWorkerID;

View File

@@ -9,6 +9,16 @@ interface nsIChannel;
interface nsIOutputStream; interface nsIOutputStream;
interface nsIURI; 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 * Interface to allow implementors of nsINetworkInterceptController to control the behaviour
* of intercepted channels without tying implementation details of the interception to * of intercepted channels without tying implementation details of the interception to
@@ -16,7 +26,7 @@ interface nsIURI;
* which do not implement nsIChannel. * which do not implement nsIChannel.
*/ */
[scriptable, uuid(2fc1170c-4f9d-4c9e-8e5d-2d351dbe03f2)] [scriptable, uuid(f2c07a6b-366d-4ef4-85ab-a77f4bcb1646)]
interface nsIInterceptedChannel : nsISupports interface nsIInterceptedChannel : nsISupports
{ {
/** /**
@@ -67,9 +77,10 @@ interface nsIInterceptedChannel : nsISupports
readonly attribute bool isNavigation; 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);
}; };
/** /**

View File

@@ -13,6 +13,7 @@
#include "nsHttpChannel.h" #include "nsHttpChannel.h"
#include "HttpChannelChild.h" #include "HttpChannelChild.h"
#include "nsHttpResponseHead.h" #include "nsHttpResponseHead.h"
#include "mozilla/dom/ChannelInfo.h"
namespace mozilla { namespace mozilla {
namespace net { namespace net {
@@ -233,13 +234,13 @@ InterceptedChannelChrome::Cancel()
} }
NS_IMETHODIMP NS_IMETHODIMP
InterceptedChannelChrome::SetSecurityInfo(nsISupports* aSecurityInfo) InterceptedChannelChrome::SetChannelInfo(dom::ChannelInfo* aChannelInfo)
{ {
if (!mChannel) { if (!mChannel) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
return mChannel->OverrideSecurityInfo(aSecurityInfo); return aChannelInfo->ResurrectInfoOnChannel(mChannel);
} }
InterceptedChannelContent::InterceptedChannelContent(HttpChannelChild* aChannel, InterceptedChannelContent::InterceptedChannelContent(HttpChannelChild* aChannel,
@@ -340,13 +341,13 @@ InterceptedChannelContent::Cancel()
} }
NS_IMETHODIMP NS_IMETHODIMP
InterceptedChannelContent::SetSecurityInfo(nsISupports* aSecurityInfo) InterceptedChannelContent::SetChannelInfo(dom::ChannelInfo* aChannelInfo)
{ {
if (!mChannel) { if (!mChannel) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
return mChannel->OverrideSecurityInfo(aSecurityInfo); return aChannelInfo->ResurrectInfoOnChannel(mChannel);
} }
} // namespace net } // namespace net

View File

@@ -82,7 +82,7 @@ public:
NS_IMETHOD SynthesizeStatus(uint16_t aStatus, const nsACString& aReason) override; NS_IMETHOD SynthesizeStatus(uint16_t aStatus, const nsACString& aReason) override;
NS_IMETHOD SynthesizeHeader(const nsACString& aName, const nsACString& aValue) override; NS_IMETHOD SynthesizeHeader(const nsACString& aName, const nsACString& aValue) override;
NS_IMETHOD Cancel() override; NS_IMETHOD Cancel() override;
NS_IMETHOD SetSecurityInfo(nsISupports* aSecurityInfo) override; NS_IMETHOD SetChannelInfo(mozilla::dom::ChannelInfo* aChannelInfo) override;
virtual void NotifyController() override; virtual void NotifyController() override;
}; };
@@ -109,7 +109,7 @@ public:
NS_IMETHOD SynthesizeStatus(uint16_t aStatus, const nsACString& aReason) override; NS_IMETHOD SynthesizeStatus(uint16_t aStatus, const nsACString& aReason) override;
NS_IMETHOD SynthesizeHeader(const nsACString& aName, const nsACString& aValue) override; NS_IMETHOD SynthesizeHeader(const nsACString& aName, const nsACString& aValue) override;
NS_IMETHOD Cancel() override; NS_IMETHOD Cancel() override;
NS_IMETHOD SetSecurityInfo(nsISupports* aSecurityInfo) override; NS_IMETHOD SetChannelInfo(mozilla::dom::ChannelInfo* aChannelInfo) override;
virtual void NotifyController() override; virtual void NotifyController() override;
}; };

View File

@@ -15,6 +15,7 @@
#include "nsITimer.h" #include "nsITimer.h"
#include "NullHttpTransaction.h" #include "NullHttpTransaction.h"
#include "mozilla/TimeStamp.h" #include "mozilla/TimeStamp.h"
#include "prio.h"
// a TLSFilterTransaction wraps another nsAHttpTransaction but // a TLSFilterTransaction wraps another nsAHttpTransaction but
// applies a encode/decode filter of TLS onto the ReadSegments // applies a encode/decode filter of TLS onto the ReadSegments

View File

@@ -11,6 +11,7 @@
#include "nsProxyInfo.h" #include "nsProxyInfo.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsStringFwd.h" #include "nsStringFwd.h"
#include "mozilla/Logging.h"
extern PRLogModuleInfo *gHttpLog; extern PRLogModuleInfo *gHttpLog;