author | Kershaw Chang <kechang@mozilla.com> |
Thu, 09 Mar 2017 02:55:00 -0500 | |
changeset 346836 | 379ac27cbef7fddf32b40ddfd0b11a78fb1aef9d |
parent 346835 | 50a0ca4800c14484161587adb16a19499f3c2e11 |
child 346837 | 4c2eaf534ed7ef20b6bf331807c0a15be591dd85 |
push id | 31479 |
push user | kwierso@gmail.com |
push date | Fri, 10 Mar 2017 00:33:39 +0000 |
treeherder | mozilla-central@35398cae65c1 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mayhemer |
bugs | 1326339 |
milestone | 55.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/netwerk/ipc/NeckoChannelParams.ipdlh +++ b/netwerk/ipc/NeckoChannelParams.ipdlh @@ -126,16 +126,17 @@ struct HttpChannelOpenArgs uint32_t initialRwin; bool blockAuthPrompt; bool suspendAfterSynthesizeResponse; bool allowStaleCacheContent; nsCString contentTypeHint; nsCString channelId; uint64_t contentWindowId; nsCString preferredAlternativeType; + uint64_t topLevelOuterContentWindowId; }; struct HttpChannelConnectArgs { uint32_t registrarId; bool shouldIntercept; };
--- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -195,16 +195,17 @@ HttpBaseChannel::HttpBaseChannel() , mFetchCacheMode(nsIHttpChannelInternal::FETCH_CACHE_MODE_DEFAULT) , mOnStartRequestCalled(false) , mOnStopRequestCalled(false) , mAfterOnStartRequestBegun(false) , mTransferSize(0) , mDecodedBodySize(0) , mEncodedBodySize(0) , mContentWindowId(0) + , mTopLevelOuterContentWindowId(0) , mRequireCORSPreflight(false) , mReportCollector(new ConsoleReportCollector()) , mForceMainDocumentChannel(false) , mIsTrackingResource(false) { LOG(("Creating HttpBaseChannel @%p\n", this)); // Subfields of unions cannot be targeted in an initializer list. @@ -3826,16 +3827,39 @@ HttpBaseChannel::EnsureRequestContextID( } // Set the load group connection scope on the transaction rootLoadGroup->GetRequestContextID(&mRequestContextID); return true; } void +HttpBaseChannel::EnsureTopLevelOuterContentWindowId() +{ + if (mTopLevelOuterContentWindowId) { + return; + } + + nsCOMPtr<nsILoadContext> loadContext; + GetCallback(loadContext); + if (!loadContext) { + return; + } + + nsCOMPtr<mozIDOMWindowProxy> topWindow; + loadContext->GetTopWindow(getter_AddRefs(topWindow)); + if (!topWindow) { + return; + } + + mTopLevelOuterContentWindowId = + nsPIDOMWindowOuter::From(topWindow)->WindowID(); +} + +void HttpBaseChannel::SetCorsPreflightParameters(const nsTArray<nsCString>& aUnsafeHeaders) { MOZ_RELEASE_ASSERT(!mRequestObserversCalled); mRequireCORSPreflight = true; mUnsafeHeaders = aUnsafeHeaders; }
--- a/netwerk/protocol/http/HttpBaseChannel.h +++ b/netwerk/protocol/http/HttpBaseChannel.h @@ -353,16 +353,21 @@ public: /* Necko internal use only... */ // the new mUploadStream. void EnsureUploadStreamIsCloneableComplete(nsresult aStatus); void SetIsTrackingResource() { mIsTrackingResource = true; } + void SetTopLevelOuterContentWindowId(uint64_t aTopLevelOuterContentWindowId) + { + mTopLevelOuterContentWindowId = aTopLevelOuterContentWindowId; + } + protected: // Handle notifying listener, removing from loadgroup if request failed. void DoNotifyListener(); virtual void DoNotifyListenerCleanup() = 0; // drop reference to listener, its callbacks, and the progress sink void ReleaseListeners(); @@ -582,16 +587,19 @@ protected: nsID mRequestContextID; bool EnsureRequestContextID(); // ID of the top-level document's inner window this channel is being // originated from. uint64_t mContentWindowId; + uint64_t mTopLevelOuterContentWindowId; + void EnsureTopLevelOuterContentWindowId(); + bool mRequireCORSPreflight; nsTArray<nsCString> mUnsafeHeaders; nsCOMPtr<nsIConsoleReportCollector> mReportCollector; // Holds the name of the preferred alt-data type. nsCString mPreferredCachedAltDataType; // Holds the name of the alternative data type the channel returned.
--- a/netwerk/protocol/http/HttpChannelChild.cpp +++ b/netwerk/protocol/http/HttpChannelChild.cpp @@ -2142,16 +2142,17 @@ HttpChannelChild::ContinueAsyncOpen() // This id identifies the inner window's top-level document, // which changes on every new load or navigation. uint64_t contentWindowId = 0; if (tabChild) { MOZ_ASSERT(tabChild->WebNavigation()); nsCOMPtr<nsIDocument> document = tabChild->GetDocument(); if (document) { contentWindowId = document->InnerWindowID(); + mTopLevelOuterContentWindowId = document->OuterWindowID(); } } SetTopLevelContentWindowId(contentWindowId); HttpChannelOpenArgs openArgs; // No access to HttpChannelOpenArgs members, but they each have a // function with the struct name that returns a ref. SerializeURI(mURI, openArgs.uri()); @@ -2240,16 +2241,17 @@ HttpChannelChild::ContinueAsyncOpen() mRequestContextID.ToProvidedString(rcid); openArgs.requestContextID().AssignASCII(rcid); char chid[NSID_LENGTH]; mChannelId.ToProvidedString(chid); openArgs.channelId().AssignASCII(chid); openArgs.contentWindowId() = contentWindowId; + openArgs.topLevelOuterContentWindowId() = mTopLevelOuterContentWindowId; if (tabChild && !tabChild->IPCOpen()) { return NS_ERROR_FAILURE; } ContentChild* cc = static_cast<ContentChild*>(gNeckoChild->Manager()); if (cc->IsShuttingDown()) { return NS_ERROR_FAILURE;
--- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -125,17 +125,18 @@ HttpChannelParent::Init(const HttpChanne a.entityID(), a.chooseApplicationCache(), a.appCacheClientID(), a.allowSpdy(), a.allowAltSvc(), a.beConservative(), a.loadInfo(), a.synthesizedResponseHead(), a.synthesizedSecurityInfoSerialization(), a.cacheKey(), a.requestContextID(), a.preflightArgs(), a.initialRwin(), a.blockAuthPrompt(), a.suspendAfterSynthesizeResponse(), a.allowStaleCacheContent(), a.contentTypeHint(), - a.channelId(), a.contentWindowId(), a.preferredAlternativeType()); + a.channelId(), a.contentWindowId(), a.preferredAlternativeType(), + a.topLevelOuterContentWindowId()); } case HttpChannelCreationArgs::THttpChannelConnectArgs: { const HttpChannelConnectArgs& cArgs = aArgs.get_HttpChannelConnectArgs(); return ConnectChannel(cArgs.registrarId(), cArgs.shouldIntercept()); } default: NS_NOTREACHED("unknown open type"); @@ -323,17 +324,18 @@ HttpChannelParent::DoAsyncOpen( const U const OptionalCorsPreflightArgs& aCorsPreflightArgs, const uint32_t& aInitialRwin, const bool& aBlockAuthPrompt, const bool& aSuspendAfterSynthesizeResponse, const bool& aAllowStaleCacheContent, const nsCString& aContentTypeHint, const nsCString& aChannelId, const uint64_t& aContentWindowId, - const nsCString& aPreferredAlternativeType) + const nsCString& aPreferredAlternativeType, + const uint64_t& aTopLevelOuterContentWindowId) { nsCOMPtr<nsIURI> uri = DeserializeURI(aURI); if (!uri) { // URIParams does MOZ_ASSERT if null, but we need to protect opt builds from // null deref here. return false; } nsCOMPtr<nsIURI> originalUri = DeserializeURI(aOriginalURI); @@ -374,16 +376,17 @@ HttpChannelParent::DoAsyncOpen( const U mChannel = do_QueryObject(channel, &rv); if (NS_FAILED(rv)) { return SendFailedAsyncOpen(rv); } // Set the channelId allocated in child to the parent instance mChannel->SetChannelId(aChannelId); mChannel->SetTopLevelContentWindowId(aContentWindowId); + mChannel->SetTopLevelOuterContentWindowId(aTopLevelOuterContentWindowId); mChannel->SetWarningReporter(this); mChannel->SetTimingEnabled(true); if (mPBOverride != kPBOverride_Unset) { mChannel->SetPrivate(mPBOverride == kPBOverride_Private ? true : false); } if (doResumeAt)
--- a/netwerk/protocol/http/HttpChannelParent.h +++ b/netwerk/protocol/http/HttpChannelParent.h @@ -143,17 +143,18 @@ protected: const OptionalCorsPreflightArgs& aCorsPreflightArgs, const uint32_t& aInitialRwin, const bool& aBlockAuthPrompt, const bool& aSuspendAfterSynthesizeResponse, const bool& aAllowStaleCacheContent, const nsCString& aContentTypeHint, const nsCString& aChannelId, const uint64_t& aContentWindowId, - const nsCString& aPreferredAlternativeType); + const nsCString& aPreferredAlternativeType, + const uint64_t& aTopLevelOuterContentWindowId); virtual mozilla::ipc::IPCResult RecvSetPriority(const int16_t& priority) override; virtual mozilla::ipc::IPCResult RecvSetClassOfService(const uint32_t& cos) override; virtual mozilla::ipc::IPCResult RecvSetCacheTokenCachedCharset(const nsCString& charset) override; virtual mozilla::ipc::IPCResult RecvSuspend() override; virtual mozilla::ipc::IPCResult RecvResume() override; virtual mozilla::ipc::IPCResult RecvCancel(const nsresult& status) override; virtual mozilla::ipc::IPCResult RecvRedirect2Verify(const nsresult& result,
--- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -987,20 +987,23 @@ nsHttpChannel::SetupTransaction() NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, NS_GET_IID(nsIHttpPushListener), getter_AddRefs(pushListener)); if (pushListener) { mCaps |= NS_HTTP_ONPUSH_LISTENER; } + EnsureTopLevelOuterContentWindowId(); + nsCOMPtr<nsIAsyncInputStream> responseStream; rv = mTransaction->Init(mCaps, mConnectionInfo, &mRequestHead, mUploadStream, mUploadStreamHasHeaders, NS_GetCurrentThread(), callbacks, this, + mTopLevelOuterContentWindowId, getter_AddRefs(responseStream)); if (NS_FAILED(rv)) { mTransaction = nullptr; return rv; } mTransaction->SetClassOfService(mClassOfService); SetupTransactionRequestContext();
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -82,16 +82,17 @@ nsHttpConnectionMgr::nsHttpConnectionMgr , mNumActiveConns(0) , mNumIdleConns(0) , mNumSpdyActiveConns(0) , mNumHalfOpenConns(0) , mTimeOfNextWakeUp(UINT64_MAX) , mPruningNoTraffic(false) , mTimeoutTickArmed(false) , mTimeoutTickNext(1) + , mCurrentTopLevelOuterContentWindowId(0) { LOG(("Creating nsHttpConnectionMgr @%p\n", this)); } nsHttpConnectionMgr::~nsHttpConnectionMgr() { LOG(("Destroying nsHttpConnectionMgr @%p\n", this)); if (mTimeoutTick) @@ -2423,16 +2424,54 @@ nsHttpConnectionMgr::ActivateTimeoutTick mTimeoutTick->SetTarget(mSocketThreadTarget); } MOZ_ASSERT(!mTimeoutTickArmed, "timer tick armed"); mTimeoutTickArmed = true; mTimeoutTick->Init(this, 1000, nsITimer::TYPE_REPEATING_SLACK); } +class UINT64Wrapper : public ARefBase +{ +public: + explicit UINT64Wrapper(uint64_t aUint64) : mUint64(aUint64) {} + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(UINT64Wrapper) + + uint64_t GetValue() + { + return mUint64; + } +private: + uint64_t mUint64; + virtual ~UINT64Wrapper() = default; +}; + +nsresult +nsHttpConnectionMgr::UpdateCurrentTopLevelOuterContentWindowId( + uint64_t aWindowId) +{ + RefPtr<UINT64Wrapper> windowIdWrapper = new UINT64Wrapper(aWindowId); + return PostEvent( + &nsHttpConnectionMgr::OnMsgUpdateCurrentTopLevelOuterContentWindowId, + 0, + windowIdWrapper); +} + +void +nsHttpConnectionMgr::OnMsgUpdateCurrentTopLevelOuterContentWindowId( + int32_t, ARefBase *param) +{ + MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); + mCurrentTopLevelOuterContentWindowId = + static_cast<UINT64Wrapper*>(param)->GetValue(); + LOG(("nsHttpConnectionMgr::OnMsgUpdateCurrentTopLevelOuterContentWindowId" + " id=%" PRIu64 "\n", + mCurrentTopLevelOuterContentWindowId)); +} + void nsHttpConnectionMgr::TimeoutTick() { MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); MOZ_ASSERT(mTimeoutTick, "no readtimeout tick"); LOG(("nsHttpConnectionMgr::TimeoutTick active=%d\n", mNumActiveConns)); // The next tick will be between 1 second and 1 hr
--- a/netwerk/protocol/http/nsHttpConnectionMgr.h +++ b/netwerk/protocol/http/nsHttpConnectionMgr.h @@ -187,16 +187,18 @@ public: void ResetIPFamilyPreference(nsHttpConnectionInfo *); uint16_t MaxRequestDelay() { return mMaxRequestDelay; } // public, so that the SPDY/http2 seesions can activate void ActivateTimeoutTick(); + nsresult UpdateCurrentTopLevelOuterContentWindowId(uint64_t aWindowId); + private: virtual ~nsHttpConnectionMgr(); class nsHalfOpenSocket; // nsConnectionEntry // // mCT maps connection info hash key to nsConnectionEntry object, which @@ -439,16 +441,17 @@ private: void OnMsgCompleteUpgrade (int32_t, ARefBase *); void OnMsgUpdateParam (int32_t, ARefBase *); void OnMsgDoShiftReloadConnectionCleanup (int32_t, ARefBase *); void OnMsgProcessFeedback (int32_t, ARefBase *); void OnMsgProcessAllSpdyPendingQ (int32_t, ARefBase *); void OnMsgUpdateRequestTokenBucket (int32_t, ARefBase *); void OnMsgVerifyTraffic (int32_t, ARefBase *); void OnMsgPruneNoTraffic (int32_t, ARefBase *); + void OnMsgUpdateCurrentTopLevelOuterContentWindowId (int32_t, ARefBase *); // Total number of active connections in all of the ConnectionEntry objects // that are accessed from mCT connection table. uint16_t mNumActiveConns; // Total number of idle connections in all of the ConnectionEntry objects // that are accessed from mCT connection table. uint16_t mNumIdleConns; // Total number of spdy connections which are a subset of the active conns @@ -483,14 +486,15 @@ private: // Read Timeout Tick handlers void TimeoutTick(); // For diagnostics void OnMsgPrintDiagnostics(int32_t, ARefBase *); nsCString mLogData; + uint64_t mCurrentTopLevelOuterContentWindowId; }; } // namespace net } // namespace mozilla #endif // !nsHttpConnectionMgr_h__
--- a/netwerk/protocol/http/nsHttpTransaction.cpp +++ b/netwerk/protocol/http/nsHttpTransaction.cpp @@ -130,16 +130,17 @@ nsHttpTransaction::nsHttpTransaction() , mContentDecoding(false) , mContentDecodingCheck(false) , mDeferredSendProgress(false) , mWaitingOnPipeOut(false) , mReportedStart(false) , mReportedResponseHeader(false) , mForTakeResponseHead(nullptr) , mResponseHeadTaken(false) + , mTopLevelOuterContentWindowId(0) , mSubmittedRatePacing(false) , mPassedRatePacing(false) , mSynchronousRatePaceRequest(false) , mClassOfService(0) , m0RTTInProgress(false) , mTransportStatus(NS_OK) { LOG(("Creating nsHttpTransaction @%p\n", this)); @@ -182,27 +183,30 @@ nsresult nsHttpTransaction::Init(uint32_t caps, nsHttpConnectionInfo *cinfo, nsHttpRequestHead *requestHead, nsIInputStream *requestBody, bool requestBodyHasHeaders, nsIEventTarget *target, nsIInterfaceRequestor *callbacks, nsITransportEventSink *eventsink, + uint64_t topLevelOuterContentWindowId, nsIAsyncInputStream **responseBody) { nsresult rv; LOG(("nsHttpTransaction::Init [this=%p caps=%x]\n", this, caps)); MOZ_ASSERT(cinfo); MOZ_ASSERT(requestHead); MOZ_ASSERT(target); MOZ_ASSERT(NS_IsMainThread()); + mTopLevelOuterContentWindowId = topLevelOuterContentWindowId; + mActivityDistributor = do_GetService(NS_HTTPACTIVITYDISTRIBUTOR_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; bool activityDistributorActive; rv = mActivityDistributor->GetIsActive(&activityDistributorActive); if (NS_SUCCEEDED(rv) && activityDistributorActive) { // there are some observers registered at activity distributor, gather // nsISupports for the channel that called Init()
--- a/netwerk/protocol/http/nsHttpTransaction.h +++ b/netwerk/protocol/http/nsHttpTransaction.h @@ -69,29 +69,33 @@ public: // @param reqBody // the request body (POST or PUT data stream) // @param reqBodyIncludesHeaders // fun stuff to support NPAPI plugins. // @param target // the dispatch target were notifications should be sent. // @param callbacks // the notification callbacks to be given to PSM. + // @param topLevelOuterContentWindowId + // indicate the top level outer content window in which + // this transaction is being loaded. // @param responseBody // the input stream that will contain the response data. async // wait on this input stream for data. on first notification, // headers should be available (check transaction status). // MOZ_MUST_USE nsresult Init(uint32_t caps, nsHttpConnectionInfo *connInfo, nsHttpRequestHead *reqHeaders, nsIInputStream *reqBody, bool reqBodyIncludesHeaders, nsIEventTarget *consumerTarget, nsIInterfaceRequestor *callbacks, nsITransportEventSink *eventsink, + uint64_t topLevelOuterContentWindowId, nsIAsyncInputStream **responseBody); // attributes nsHttpResponseHead *ResponseHead() { return mHaveAllHeaders ? mResponseHead : nullptr; } nsISupports *SecurityInfo() { return mSecurityInfo; } nsIEventTarget *ConsumerTarget() { return mConsumerTarget; } nsISupports *HttpChannel() { return mChannel; } @@ -161,16 +165,21 @@ public: mozilla::TimeStamp GetRequestStart(); mozilla::TimeStamp GetResponseStart(); mozilla::TimeStamp GetResponseEnd(); int64_t GetTransferSize() { return mTransferSize; } MOZ_MUST_USE bool Do0RTT() override; MOZ_MUST_USE nsresult Finish0RTT(bool aRestart, bool aAlpnChanged /* ignored */) override; + + uint64_t TopLevelOuterContentWindowId() + { + return mTopLevelOuterContentWindowId; + } private: friend class DeleteHttpTransaction; virtual ~nsHttpTransaction(); MOZ_MUST_USE nsresult Restart(); char *LocateHttpStart(char *buf, uint32_t len, bool aAllowPartialMatch); MOZ_MUST_USE nsresult ParseLine(nsACString &line); @@ -328,16 +337,18 @@ private: // protected by nsHttp::GetLock() nsHttpResponseHead *mForTakeResponseHead; bool mResponseHeadTaken; // The time when the transaction was submitted to the Connection Manager TimeStamp mPendingTime; + uint64_t mTopLevelOuterContentWindowId; + // For Rate Pacing via an EventTokenBucket public: // called by the connection manager to run this transaction through the // token bucket. If the token bucket admits the transaction immediately it // returns true. The function is called repeatedly until it returns true. bool TryToRunPacedRequest(); // ATokenBucketEvent pure virtual implementation. Called by the token bucket