Bug 1395140 - Implement "http-on-stop-request" notification, r=mayhemer
authorAndrea Marchesini <amarchesini@mozilla.com>
Fri, 01 Sep 2017 11:55:37 +0200
changeset 378314 8d9d4d7a49149b9638c0caab9f25abfccefbf690
parent 378313 9f440b7db2d04d190aceeafdba67326bec8f21e5
child 378315 378e69fe5a92828602eec310b0206c6873ced5e6
push id50273
push userkwierso@gmail.com
push dateFri, 01 Sep 2017 23:34:30 +0000
treeherderautoland@ca3d00bb702d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmayhemer
bugs1395140
milestone57.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
Bug 1395140 - Implement "http-on-stop-request" notification, r=mayhemer
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpHandler.h
netwerk/protocol/http/nsIHttpProtocolHandler.idl
xpcom/ds/nsObserverService.cpp
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -3237,16 +3237,19 @@ HttpBaseChannel::DoNotifyListener()
                "We should not call OnStopRequest twice");
 
     nsCOMPtr<nsIStreamListener> listener = mListener;
     listener->OnStopRequest(this, mListenerContext, mStatus);
 
     mOnStopRequestCalled = true;
   }
 
+  // notify "http-on-stop-connect" observers
+  gHttpHandler->OnStopRequest(this);
+
   // This channel has finished its job, potentially release any tail-blocked
   // requests with this.
   RemoveAsNonTailRequest();
 
   // We have to make sure to drop the references to listeners and callbacks
   // no longer needed.
   ReleaseListeners();
 
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -1182,16 +1182,19 @@ HttpChannelChild::DoOnStopRequest(nsIReq
 
   // In theory mListener should not be null, but in practice sometimes it is.
   MOZ_ASSERT(mListener);
   if (mListener) {
     mListener->OnStopRequest(aRequest, aContext, mStatus);
   }
   mOnStopRequestCalled = true;
 
+  // notify "http-on-stop-connect" observers
+  gHttpHandler->OnStopRequest(this);
+
   ReleaseListeners();
 
   // If a preferred alt-data type was set, the parent would hold a reference to
   // the cache entry in case the child calls openAlternativeOutputStream().
   // (see nsHttpChannel::OnStopRequest)
   if (!mPreferredCachedAltDataType.IsEmpty()) {
     mAltDataCacheEntryAvailable = mCacheEntryAvailable;
   }
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -7573,16 +7573,19 @@ nsHttpChannel::OnStopRequest(nsIRequest 
         MOZ_ASSERT(mOnStartRequestCalled,
                    "OnStartRequest should be called before OnStopRequest");
         MOZ_ASSERT(!mOnStopRequestCalled,
                    "We should not call OnStopRequest twice");
         mListener->OnStopRequest(this, mListenerContext, status);
         mOnStopRequestCalled = true;
     }
 
+    // notify "http-on-stop-connect" observers
+    gHttpHandler->OnStopRequest(this);
+
     RemoveAsNonTailRequest();
 
     // If a preferred alt-data type was set, this signals the consumer is
     // interested in reading and/or writing the alt-data representation.
     // We need to hold a reference to the cache entry in case the listener calls
     // openAlternativeOutputStream() after CloseCacheEntry() clears mCacheEntry.
     if (!mPreferredCachedAltDataType.IsEmpty()) {
         mAltDataCacheEntry = mCacheEntry;
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -312,16 +312,22 @@ public:
     }
 
     // Called by the channel before writing a request
     void OnModifyRequest(nsIHttpChannel *chan)
     {
         NotifyObservers(chan, NS_HTTP_ON_MODIFY_REQUEST_TOPIC);
     }
 
+    // Called by the channel before writing a request
+    void OnStopRequest(nsIHttpChannel *chan)
+    {
+        NotifyObservers(chan, NS_HTTP_ON_STOP_REQUEST_TOPIC);
+    }
+
     // Called by the channel and cached in the loadGroup
     void OnUserAgentRequest(nsIHttpChannel *chan)
     {
       NotifyObservers(chan, NS_HTTP_ON_USERAGENT_REQUEST_TOPIC);
     }
 
     // Called by the channel before setting up the transaction
     void OnBeforeConnect(nsIHttpChannel *chan)
--- a/netwerk/protocol/http/nsIHttpProtocolHandler.idl
+++ b/netwerk/protocol/http/nsIHttpProtocolHandler.idl
@@ -127,10 +127,16 @@ interface nsIHttpProtocolHandler : nsIPr
  * Before an HTTP request corresponding to a channel with the LOAD_DOCUMENT_URI
  * flag is sent to the server, this observer topic is notified. The observer of
  * this topic can then choose to modify the user agent for this request before
  * the request is actually sent to the server. Additionally, the modified user
  * agent will be propagated to sub-resource requests from the same load group.
  */
 #define NS_HTTP_ON_USERAGENT_REQUEST_TOPIC "http-on-useragent-request"
 
+/**
+ * This topic is notified for every http channel right after it called
+ * OnStopRequest on its listener, regardless whether it was finished
+ * successfully, failed or has been canceled.
+ */
+#define NS_HTTP_ON_STOP_REQUEST_TOPIC "http-on-stop-request"
 
 %}
--- a/xpcom/ds/nsObserverService.cpp
+++ b/xpcom/ds/nsObserverService.cpp
@@ -207,20 +207,21 @@ nsObserverService::AddObserver(nsIObserv
   LOG(("nsObserverService::AddObserver(%p: %s)",
        (void*)aObserver, aTopic));
 
   NS_ENSURE_VALIDCALL
   if (NS_WARN_IF(!aObserver) || NS_WARN_IF(!aTopic)) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  // Specifically allow http-on-opening-request in the child process;
-  // see bug 1269765.
+  // Specifically allow http-on-opening-request and http-on-stop-request in the
+  // child process; see bug 1269765.
   if (mozilla::net::IsNeckoChild() && !strncmp(aTopic, "http-on-", 8) &&
-      strcmp(aTopic, "http-on-opening-request")) {
+      strcmp(aTopic, "http-on-opening-request") &&
+      strcmp(aTopic, "http-on-stop-request")) {
     nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
     nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
     error->Init(NS_LITERAL_STRING("http-on-* observers only work in the parent process"),
                 EmptyString(), EmptyString(), 0, 0,
                 nsIScriptError::warningFlag, "chrome javascript");
     console->LogMessage(error);
 
     return NS_ERROR_NOT_IMPLEMENTED;