netwerk/protocol/http/HttpChannelParentListener.cpp

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set sw=2 ts=8 et tw=80 : */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 // HttpLog.h should generally be included first
     8 #include "HttpLog.h"
    10 #include "HttpChannelParentListener.h"
    11 #include "mozilla/net/HttpChannelParent.h"
    12 #include "mozilla/unused.h"
    13 #include "nsIRedirectChannelRegistrar.h"
    14 #include "nsIHttpEventSink.h"
    16 using mozilla::unused;
    18 namespace mozilla {
    19 namespace net {
    21 HttpChannelParentListener::HttpChannelParentListener(HttpChannelParent* aInitialChannel)
    22   : mNextListener(aInitialChannel)
    23   , mRedirectChannelId(0)
    24   , mSuspendedForDiversion(false)
    25 {
    26 }
    28 HttpChannelParentListener::~HttpChannelParentListener()
    29 {
    30 }
    32 //-----------------------------------------------------------------------------
    33 // HttpChannelParentListener::nsISupports
    34 //-----------------------------------------------------------------------------
    36 NS_IMPL_ISUPPORTS(HttpChannelParentListener,
    37                   nsIInterfaceRequestor,
    38                   nsIStreamListener,
    39                   nsIRequestObserver,
    40                   nsIChannelEventSink,
    41                   nsIRedirectResultListener)
    43 //-----------------------------------------------------------------------------
    44 // HttpChannelParentListener::nsIRequestObserver
    45 //-----------------------------------------------------------------------------
    47 NS_IMETHODIMP
    48 HttpChannelParentListener::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
    49 {
    50   MOZ_RELEASE_ASSERT(!mSuspendedForDiversion,
    51     "Cannot call OnStartRequest if suspended for diversion!");
    53   if (!mNextListener)
    54     return NS_ERROR_UNEXPECTED;
    56   LOG(("HttpChannelParentListener::OnStartRequest [this=%p]\n", this));
    57   return mNextListener->OnStartRequest(aRequest, aContext);
    58 }
    60 NS_IMETHODIMP
    61 HttpChannelParentListener::OnStopRequest(nsIRequest *aRequest,
    62                                           nsISupports *aContext,
    63                                           nsresult aStatusCode)
    64 {
    65   MOZ_RELEASE_ASSERT(!mSuspendedForDiversion,
    66     "Cannot call OnStopRequest if suspended for diversion!");
    68   if (!mNextListener)
    69     return NS_ERROR_UNEXPECTED;
    71   LOG(("HttpChannelParentListener::OnStopRequest: [this=%p status=%ul]\n",
    72        this, aStatusCode));
    73   nsresult rv = mNextListener->OnStopRequest(aRequest, aContext, aStatusCode);
    75   mNextListener = nullptr;
    76   return rv;
    77 }
    79 //-----------------------------------------------------------------------------
    80 // HttpChannelParentListener::nsIStreamListener
    81 //-----------------------------------------------------------------------------
    83 NS_IMETHODIMP
    84 HttpChannelParentListener::OnDataAvailable(nsIRequest *aRequest,
    85                                             nsISupports *aContext,
    86                                             nsIInputStream *aInputStream,
    87                                             uint64_t aOffset,
    88                                             uint32_t aCount)
    89 {
    90   MOZ_RELEASE_ASSERT(!mSuspendedForDiversion,
    91     "Cannot call OnDataAvailable if suspended for diversion!");
    93   if (!mNextListener)
    94     return NS_ERROR_UNEXPECTED;
    96   LOG(("HttpChannelParentListener::OnDataAvailable [this=%p]\n", this));
    97   return mNextListener->OnDataAvailable(aRequest, aContext, aInputStream, aOffset, aCount);
    98 }
   100 //-----------------------------------------------------------------------------
   101 // HttpChannelParentListener::nsIInterfaceRequestor
   102 //-----------------------------------------------------------------------------
   104 NS_IMETHODIMP
   105 HttpChannelParentListener::GetInterface(const nsIID& aIID, void **result)
   106 {
   107   if (aIID.Equals(NS_GET_IID(nsIChannelEventSink)) ||
   108       aIID.Equals(NS_GET_IID(nsIHttpEventSink))  ||
   109       aIID.Equals(NS_GET_IID(nsIRedirectResultListener)))
   110   {
   111     return QueryInterface(aIID, result);
   112   }
   114   nsCOMPtr<nsIInterfaceRequestor> ir;
   115   if (mNextListener &&
   116       NS_SUCCEEDED(CallQueryInterface(mNextListener.get(),
   117                                       getter_AddRefs(ir))))
   118   {
   119     return ir->GetInterface(aIID, result);
   120   }
   122   return NS_NOINTERFACE;
   123 }
   125 //-----------------------------------------------------------------------------
   126 // HttpChannelParentListener::nsIChannelEventSink
   127 //-----------------------------------------------------------------------------
   129 NS_IMETHODIMP
   130 HttpChannelParentListener::AsyncOnChannelRedirect(
   131                                     nsIChannel *oldChannel,
   132                                     nsIChannel *newChannel,
   133                                     uint32_t redirectFlags,
   134                                     nsIAsyncVerifyRedirectCallback* callback)
   135 {
   136   nsresult rv;
   138   // Register the new channel and obtain id for it
   139   nsCOMPtr<nsIRedirectChannelRegistrar> registrar =
   140       do_GetService("@mozilla.org/redirectchannelregistrar;1", &rv);
   141   NS_ENSURE_SUCCESS(rv, rv);
   143   rv = registrar->RegisterChannel(newChannel, &mRedirectChannelId);
   144   NS_ENSURE_SUCCESS(rv, rv);
   146   LOG(("Registered %p channel under id=%d", newChannel, mRedirectChannelId));
   148   nsCOMPtr<nsIParentRedirectingChannel> activeRedirectingChannel =
   149       do_QueryInterface(mNextListener);
   150   if (!activeRedirectingChannel) {
   151     NS_RUNTIMEABORT("Channel got a redirect response, but doesn't implement "
   152                     "nsIParentRedirectingChannel to handle it.");
   153   }
   155   return activeRedirectingChannel->StartRedirect(mRedirectChannelId,
   156                                                  newChannel,
   157                                                  redirectFlags,
   158                                                  callback);
   159 }
   161 //-----------------------------------------------------------------------------
   162 // HttpChannelParentListener::nsIRedirectResultListener
   163 //-----------------------------------------------------------------------------
   165 NS_IMETHODIMP
   166 HttpChannelParentListener::OnRedirectResult(bool succeeded)
   167 {
   168   nsresult rv;
   170   nsCOMPtr<nsIParentChannel> redirectChannel;
   171   if (mRedirectChannelId) {
   172     nsCOMPtr<nsIRedirectChannelRegistrar> registrar =
   173         do_GetService("@mozilla.org/redirectchannelregistrar;1", &rv);
   174     NS_ENSURE_SUCCESS(rv, rv);
   176     rv = registrar->GetParentChannel(mRedirectChannelId,
   177                                      getter_AddRefs(redirectChannel));
   178     if (NS_FAILED(rv) || !redirectChannel) {
   179       // Redirect might get canceled before we got AsyncOnChannelRedirect
   180       LOG(("Registered parent channel not found under id=%d", mRedirectChannelId));
   182       nsCOMPtr<nsIChannel> newChannel;
   183       rv = registrar->GetRegisteredChannel(mRedirectChannelId,
   184                                            getter_AddRefs(newChannel));
   185       MOZ_ASSERT(newChannel, "Already registered channel not found");
   187       if (NS_SUCCEEDED(rv))
   188         newChannel->Cancel(NS_BINDING_ABORTED);
   189     }
   191     // Release all previously registered channels, they are no longer need to be
   192     // kept in the registrar from this moment.
   193     registrar->DeregisterChannels(mRedirectChannelId);
   195     mRedirectChannelId = 0;
   196   }
   198   if (!redirectChannel) {
   199     succeeded = false;
   200   }
   202   nsCOMPtr<nsIParentRedirectingChannel> activeRedirectingChannel =
   203       do_QueryInterface(mNextListener);
   204   MOZ_ASSERT(activeRedirectingChannel,
   205     "Channel finished a redirect response, but doesn't implement "
   206     "nsIParentRedirectingChannel to complete it.");
   208   if (activeRedirectingChannel) {
   209     activeRedirectingChannel->CompleteRedirect(succeeded);
   210   } else {
   211     succeeded = false;
   212   }
   214   if (succeeded) {
   215     // Switch to redirect channel and delete the old one.
   216     nsCOMPtr<nsIParentChannel> parent;
   217     parent = do_QueryInterface(mNextListener);
   218     MOZ_ASSERT(parent);
   219     parent->Delete();
   220     mNextListener = do_QueryInterface(redirectChannel);
   221     MOZ_ASSERT(mNextListener);
   222     redirectChannel->SetParentListener(this);
   223   } else if (redirectChannel) {
   224     // Delete the redirect target channel: continue using old channel
   225     redirectChannel->Delete();
   226   }
   228   return NS_OK;
   229 }
   231 //-----------------------------------------------------------------------------
   233 nsresult
   234 HttpChannelParentListener::SuspendForDiversion()
   235 {
   236   if (NS_WARN_IF(mSuspendedForDiversion)) {
   237     MOZ_ASSERT(!mSuspendedForDiversion, "Cannot SuspendForDiversion twice!");
   238     return NS_ERROR_UNEXPECTED;
   239   }
   241   // While this is set, no OnStart/OnData/OnStop callbacks should be forwarded
   242   // to mNextListener.
   243   mSuspendedForDiversion = true;
   245   return NS_OK;
   246 }
   248 nsresult
   249 HttpChannelParentListener::ResumeForDiversion()
   250 {
   251   MOZ_RELEASE_ASSERT(mSuspendedForDiversion, "Must already be suspended!");
   253   // Allow OnStart/OnData/OnStop callbacks to be forwarded to mNextListener.
   254   mSuspendedForDiversion = false;
   256   return NS_OK;
   257 }
   259 nsresult
   260 HttpChannelParentListener::DivertTo(nsIStreamListener* aListener)
   261 {
   262   MOZ_ASSERT(aListener);
   263   MOZ_RELEASE_ASSERT(mSuspendedForDiversion, "Must already be suspended!");
   265   mNextListener = aListener;
   267   return ResumeForDiversion();
   268 }
   270 }} // mozilla::net

mercurial