Bug 932046 - crash in mozilla::net::HttpChannelChild::OnRedirectVerifyCallback(unsigned int), r=jduell
authorHonza Bambas <honzab.moz@firemni.cz>
Thu, 05 Dec 2013 13:09:11 +0100
changeset 174589 3d1b55d822b2eb6884927172638391fa8d957b54
parent 174588 f6b0c6073f4f8fe114f23f6a197d6af3de0490bf
child 174590 efaee7511571ee5a43daf68caa749d5c181f51e1
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjduell
bugs932046
milestone28.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 932046 - crash in mozilla::net::HttpChannelChild::OnRedirectVerifyCallback(unsigned int), r=jduell
netwerk/protocol/http/HttpBaseChannel.cpp
netwerk/protocol/http/HttpBaseChannel.h
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/nsIHttpChannelInternal.idl
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -1519,16 +1519,24 @@ HttpBaseChannel::GetLoadUnblocked(bool *
 
 NS_IMETHODIMP
 HttpBaseChannel::SetLoadUnblocked(bool aLoadUnblocked)
 {
   mLoadUnblocked = aLoadUnblocked;
   return NS_OK;
 }
 
+NS_IMETHODIMP
+HttpBaseChannel::GetApiRedirectToURI(nsIURI ** aResult)
+{
+  NS_ENSURE_ARG_POINTER(aResult);
+  NS_IF_ADDREF(*aResult = mAPIRedirectToURI);
+  return NS_OK;
+}
+
 //-----------------------------------------------------------------------------
 // HttpBaseChannel::nsISupportsPriority
 //-----------------------------------------------------------------------------
 
 NS_IMETHODIMP
 HttpBaseChannel::GetPriority(int32_t *value)
 {
   *value = mPriority;
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -148,16 +148,17 @@ public:
   NS_IMETHOD GetRemoteAddress(nsACString& addr);
   NS_IMETHOD GetRemotePort(int32_t* port);
   NS_IMETHOD GetAllowSpdy(bool *aAllowSpdy);
   NS_IMETHOD SetAllowSpdy(bool aAllowSpdy);
   NS_IMETHOD GetLoadAsBlocking(bool *aLoadAsBlocking);
   NS_IMETHOD SetLoadAsBlocking(bool aLoadAsBlocking);
   NS_IMETHOD GetLoadUnblocked(bool *aLoadUnblocked);
   NS_IMETHOD SetLoadUnblocked(bool aLoadUnblocked);
+  NS_IMETHOD GetApiRedirectToURI(nsIURI * *aApiRedirectToURI);
   NS_IMETHOD AddSecurityMessage(const nsAString &aMessageTag, const nsAString &aMessageCategory);
   NS_IMETHOD TakeAllSecurityMessages(nsCOMArray<nsISecurityConsoleMessage> &aMessages);
 
   inline void CleanRedirectCacheChainIfNecessary()
   {
       mRedirectedCachekeys = nullptr;
   }
   NS_IMETHOD HTTPUpgrade(const nsACString & aProtocolName,
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -880,34 +880,40 @@ HttpChannelChild::OnRedirectVerifyCallba
 
   nsCOMPtr<nsIHttpChannelChild> newHttpChannelChild =
       do_QueryInterface(mRedirectChannelChild);
   if (newHttpChannelChild && NS_SUCCEEDED(result)) {
     newHttpChannelChild->AddCookiesToRequest();
     newHttpChannelChild->GetClientSetRequestHeaders(&headerTuples);
   }
 
+  /* If the redirect was canceled, bypass OMR and send an empty API
+   * redirect URI */
+  SerializeURI(nullptr, redirectURI);
+
   if (NS_SUCCEEDED(result)) {
-    // we know this is an HttpChannelChild
-    HttpChannelChild* base =
-      static_cast<HttpChannelChild*>(mRedirectChannelChild.get());
     // Note: this is where we would notify "http-on-modify-response" observers.
     // We have deliberately disabled this for child processes (see bug 806753)
     //
     // After we verify redirect, nsHttpChannel may hit the network: must give
     // "http-on-modify-request" observers the chance to cancel before that.
     //base->CallOnModifyRequestObservers();
 
-    /* If there was an API redirect of this redirect, we need to send it
-     * down here, since it can't get sent via SendAsyncOpen. */
-    SerializeURI(base->mAPIRedirectToURI, redirectURI);
-  } else {
-    /* If the redirect was canceled, bypass OMR and send an empty API
-     * redirect URI */
-    SerializeURI(nullptr, redirectURI);
+    nsCOMPtr<nsIHttpChannelInternal> newHttpChannelInternal =
+      do_QueryInterface(mRedirectChannelChild);
+    if (newHttpChannelInternal) {
+      nsCOMPtr<nsIURI> apiRedirectURI;
+      nsresult rv = newHttpChannelInternal->GetApiRedirectToURI(
+        getter_AddRefs(apiRedirectURI));
+      if (NS_SUCCEEDED(rv) && apiRedirectURI) {
+        /* If there was an API redirect of this channel, we need to send it
+         * up here, since it can't be sent via SendAsyncOpen. */
+        SerializeURI(apiRedirectURI, redirectURI);
+      }
+    }
   }
 
   if (mIPCOpen)
     SendRedirect2Verify(result, *headerTuples, redirectURI);
 
   return NS_OK;
 }
 
--- a/netwerk/protocol/http/nsIHttpChannelInternal.idl
+++ b/netwerk/protocol/http/nsIHttpChannelInternal.idl
@@ -32,17 +32,17 @@ interface nsIHttpUpgradeListener : nsISu
                               in nsIAsyncOutputStream aSocketOut);
 };
 
 /**
  * Dumping ground for http.  This interface will never be frozen.  If you are
  * using any feature exposed by this interface, be aware that this interface
  * will change and you will be broken.  You have been warned.
  */
-[scriptable, uuid(5b4b2632-cee4-11e2-8e84-c7506188709b)]
+[scriptable, uuid(b733194f-6751-4876-a444-bca4ba3f2fcb)]
 interface nsIHttpChannelInternal : nsISupports
 {
     /**
      * An http channel can own a reference to the document URI
      */
     attribute nsIURI documentURI;
 
     /**
@@ -176,9 +176,14 @@ interface nsIHttpChannelInternal : nsISu
 
     /**
      * If set, this channel will load in parallel with the rest of the load
      * group even if a blocking subset of the group would normally be given
      * exclusivity. Default false.
      */
     attribute boolean loadUnblocked;
 
+    /**
+     * Get value of the URI passed to nsIHttpChannel.redirectTo() if any.
+     * May return null when redirectTo() has not been called.
+     */
+    readonly attribute nsIURI apiRedirectToURI;
 };