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.)

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

mercurial