author | Ehsan Akhgari <ehsan@mozilla.com> |
Tue, 02 Jun 2015 18:01:26 -0400 | |
changeset 247523 | 435358bf7c12a323aef04b0605753ec586e1bfe6 |
parent 247522 | 24d7d4dfab29e291aed2da8b904b981bc3ac9031 |
child 247524 | 095f8f54dcd2a26b9302677d61337f4341a857bb |
push id | 28870 |
push user | cbook@mozilla.com |
push date | Mon, 08 Jun 2015 09:58:36 +0000 |
treeherder | mozilla-central@4700d1cdf489 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jdm |
bugs | 1164397 |
milestone | 41.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/fetch/ChannelInfo.cpp +++ b/dom/fetch/ChannelInfo.cpp @@ -8,40 +8,58 @@ #include "nsCOMPtr.h" #include "nsIChannel.h" #include "nsIHttpChannel.h" #include "nsSerializationHelper.h" #include "mozilla/net/HttpBaseChannel.h" #include "mozilla/ipc/ChannelInfo.h" #include "nsIJARChannel.h" #include "nsJARChannel.h" +#include "nsNetUtil.h" using namespace mozilla; using namespace mozilla::dom; void ChannelInfo::InitFromChannel(nsIChannel* aChannel) { + MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(!mInited, "Cannot initialize the object twice"); nsCOMPtr<nsISupports> securityInfo; aChannel->GetSecurityInfo(getter_AddRefs(securityInfo)); if (securityInfo) { SetSecurityInfo(securityInfo); } + nsLoadFlags loadFlags = 0; + aChannel->GetLoadFlags(&loadFlags); + mRedirected = (loadFlags & nsIChannel::LOAD_REPLACE); + if (mRedirected) { + // Save the spec and not the nsIURI object itself, since those objects are + // not thread-safe, and releasing them somewhere other than the main thread + // is not possible. + nsCOMPtr<nsIURI> redirectedURI; + aChannel->GetURI(getter_AddRefs(redirectedURI)); + if (redirectedURI) { + redirectedURI->GetSpec(mRedirectedURISpec); + } + } + mInited = true; } void ChannelInfo::InitFromIPCChannelInfo(const ipc::IPCChannelInfo& aChannelInfo) { MOZ_ASSERT(!mInited, "Cannot initialize the object twice"); mSecurityInfo = aChannelInfo.securityInfo(); + mRedirectedURISpec = aChannelInfo.redirectedURI(); + mRedirected = aChannelInfo.redirected(); mInited = true; } void ChannelInfo::SetSecurityInfo(nsISupports* aSecurityInfo) { MOZ_ASSERT(mSecurityInfo.IsEmpty(), "security info should only be set once"); @@ -51,53 +69,83 @@ ChannelInfo::SetSecurityInfo(nsISupports return; } NS_SerializeToString(serializable, mSecurityInfo); } nsresult ChannelInfo::ResurrectInfoOnChannel(nsIChannel* aChannel) { + MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(mInited); + // These pointers may be null at this point. They must be checked before + // being dereferenced. + nsCOMPtr<nsIHttpChannel> httpChannel = + do_QueryInterface(aChannel); + nsCOMPtr<nsIJARChannel> jarChannel = + do_QueryInterface(aChannel); + 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 (httpChannel) { net::HttpBaseChannel* httpBaseChannel = static_cast<net::HttpBaseChannel*>(httpChannel.get()); rv = httpBaseChannel->OverrideSecurityInfo(infoObj); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } else { - nsCOMPtr<nsIJARChannel> jarChannel = - do_QueryInterface(aChannel); if (NS_WARN_IF(!jarChannel)) { return NS_ERROR_FAILURE; } static_cast<nsJARChannel*>(jarChannel.get())-> OverrideSecurityInfo(infoObj); } } + if (mRedirected) { + nsLoadFlags flags = 0; + aChannel->GetLoadFlags(&flags); + flags |= nsIChannel::LOAD_REPLACE; + aChannel->SetLoadFlags(flags); + + nsCOMPtr<nsIURI> redirectedURI; + nsresult rv = NS_NewURI(getter_AddRefs(redirectedURI), + mRedirectedURISpec); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + if (httpChannel) { + net::HttpBaseChannel* httpBaseChannel = + static_cast<net::HttpBaseChannel*>(httpChannel.get()); + httpBaseChannel->OverrideURI(redirectedURI); + } else { + if (NS_WARN_IF(!jarChannel)) { + return NS_ERROR_FAILURE; + } + static_cast<nsJARChannel*>(jarChannel.get())->OverrideURI(redirectedURI); + } + } + 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; + ipcInfo.redirectedURI() = mRedirectedURISpec; + ipcInfo.redirected() = mRedirected; return ipcInfo; }
--- a/dom/fetch/ChannelInfo.h +++ b/dom/fetch/ChannelInfo.h @@ -3,18 +3,20 @@ /* 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" +#include "nsCOMPtr.h" class nsIChannel; +class nsIURI; namespace mozilla { namespace ipc { class IPCChannelInfo; } // namespace ipc namespace dom { @@ -37,30 +39,35 @@ namespace dom { // initialized. There are assertions ensuring these invariants. class ChannelInfo final { public: typedef mozilla::ipc::IPCChannelInfo IPCChannelInfo; ChannelInfo() : mInited(false) + , mRedirected(false) { } ChannelInfo(const ChannelInfo& aRHS) : mSecurityInfo(aRHS.mSecurityInfo) + , mRedirectedURISpec(aRHS.mRedirectedURISpec) , mInited(aRHS.mInited) + , mRedirected(aRHS.mRedirected) { } ChannelInfo& operator=(const ChannelInfo& aRHS) { mSecurityInfo = aRHS.mSecurityInfo; + mRedirectedURISpec = aRHS.mRedirectedURISpec; mInited = aRHS.mInited; + mRedirected = aRHS.mRedirected; 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. @@ -73,15 +80,17 @@ public: IPCChannelInfo AsIPCChannelInfo() const; private: void SetSecurityInfo(nsISupports* aSecurityInfo); private: nsCString mSecurityInfo; + nsCString mRedirectedURISpec; bool mInited; + bool mRedirected; }; } // namespace dom } // namespace mozilla #endif // mozilla_dom_ChannelInfo_h
--- a/dom/fetch/ChannelInfo.ipdlh +++ b/dom/fetch/ChannelInfo.ipdlh @@ -3,12 +3,14 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ namespace mozilla { namespace ipc { struct IPCChannelInfo { nsCString securityInfo; + nsCString redirectedURI; + bool redirected; }; } // namespace ipc } // namespace mozilla