tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsRequestObserverProxy.cpp (6194B)


      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #include "mozilla/DebugOnly.h"
      7 
      8 #include "nscore.h"
      9 #include "nsRequestObserverProxy.h"
     10 #include "nsIRequest.h"
     11 #include "mozilla/Logging.h"
     12 #include "mozilla/IntegerPrintfMacros.h"
     13 
     14 namespace mozilla {
     15 namespace net {
     16 
     17 static LazyLogModule gRequestObserverProxyLog("nsRequestObserverProxy");
     18 
     19 #undef LOG
     20 #define LOG(args) MOZ_LOG(gRequestObserverProxyLog, LogLevel::Debug, args)
     21 
     22 //-----------------------------------------------------------------------------
     23 // nsARequestObserverEvent internal class...
     24 //-----------------------------------------------------------------------------
     25 
     26 nsARequestObserverEvent::nsARequestObserverEvent(nsIRequest* request)
     27    : Runnable("net::nsARequestObserverEvent"), mRequest(request) {
     28  MOZ_ASSERT(mRequest, "null pointer");
     29 }
     30 
     31 //-----------------------------------------------------------------------------
     32 // nsOnStartRequestEvent internal class...
     33 //-----------------------------------------------------------------------------
     34 
     35 class nsOnStartRequestEvent : public nsARequestObserverEvent {
     36  RefPtr<nsRequestObserverProxy> mProxy;
     37 
     38 public:
     39  nsOnStartRequestEvent(nsRequestObserverProxy* proxy, nsIRequest* request)
     40      : nsARequestObserverEvent(request), mProxy(proxy) {
     41    MOZ_ASSERT(mProxy, "null pointer");
     42  }
     43 
     44  NS_IMETHOD Run() override {
     45    LOG(("nsOnStartRequestEvent::HandleEvent [req=%p]\n", mRequest.get()));
     46 
     47    if (!mProxy->mObserver) {
     48      MOZ_ASSERT_UNREACHABLE(
     49          "already handled onStopRequest event "
     50          "(observer is null)");
     51      return NS_OK;
     52    }
     53 
     54    LOG(("handle startevent=%p\n", this));
     55    nsresult rv = mProxy->mObserver->OnStartRequest(mRequest);
     56    if (NS_FAILED(rv)) {
     57      LOG(("OnStartRequest failed [rv=%" PRIx32 "] canceling request!\n",
     58           static_cast<uint32_t>(rv)));
     59      rv = mRequest->Cancel(rv);
     60      NS_ASSERTION(NS_SUCCEEDED(rv), "Cancel failed for request!");
     61    }
     62 
     63    return NS_OK;
     64  }
     65 
     66 private:
     67  virtual ~nsOnStartRequestEvent() = default;
     68 };
     69 
     70 //-----------------------------------------------------------------------------
     71 // nsOnStopRequestEvent internal class...
     72 //-----------------------------------------------------------------------------
     73 
     74 class nsOnStopRequestEvent : public nsARequestObserverEvent {
     75  RefPtr<nsRequestObserverProxy> mProxy;
     76 
     77 public:
     78  nsOnStopRequestEvent(nsRequestObserverProxy* proxy, nsIRequest* request)
     79      : nsARequestObserverEvent(request), mProxy(proxy) {
     80    MOZ_ASSERT(mProxy, "null pointer");
     81  }
     82 
     83  NS_IMETHOD Run() override {
     84    LOG(("nsOnStopRequestEvent::HandleEvent [req=%p]\n", mRequest.get()));
     85 
     86    nsMainThreadPtrHandle<nsIRequestObserver> observer = mProxy->mObserver;
     87    if (!observer) {
     88      MOZ_ASSERT_UNREACHABLE(
     89          "already handled onStopRequest event "
     90          "(observer is null)");
     91      return NS_OK;
     92    }
     93    // Do not allow any more events to be handled after OnStopRequest
     94    mProxy->mObserver = nullptr;
     95 
     96    nsresult status = NS_OK;
     97    DebugOnly<nsresult> rv = mRequest->GetStatus(&status);
     98    NS_ASSERTION(NS_SUCCEEDED(rv), "GetStatus failed for request!");
     99 
    100    LOG(("handle stopevent=%p\n", this));
    101    (void)observer->OnStopRequest(mRequest, status);
    102 
    103    return NS_OK;
    104  }
    105 
    106 private:
    107  virtual ~nsOnStopRequestEvent() = default;
    108 };
    109 
    110 //-----------------------------------------------------------------------------
    111 // nsRequestObserverProxy::nsISupports implementation...
    112 //-----------------------------------------------------------------------------
    113 
    114 NS_IMPL_ISUPPORTS(nsRequestObserverProxy, nsIRequestObserver,
    115                  nsIRequestObserverProxy)
    116 
    117 //-----------------------------------------------------------------------------
    118 // nsRequestObserverProxy::nsIRequestObserver implementation...
    119 //-----------------------------------------------------------------------------
    120 
    121 NS_IMETHODIMP
    122 nsRequestObserverProxy::OnStartRequest(nsIRequest* request) {
    123  LOG(("nsRequestObserverProxy::OnStartRequest [this=%p req=%p]\n", this,
    124       request));
    125 
    126  RefPtr<nsOnStartRequestEvent> ev = new nsOnStartRequestEvent(this, request);
    127 
    128  LOG(("post startevent=%p\n", ev.get()));
    129  return FireEvent(ev);
    130 }
    131 
    132 NS_IMETHODIMP
    133 nsRequestObserverProxy::OnStopRequest(nsIRequest* request, nsresult status) {
    134  LOG(("nsRequestObserverProxy: OnStopRequest [this=%p req=%p status=%" PRIx32
    135       "]\n",
    136       this, request, static_cast<uint32_t>(status)));
    137 
    138  // The status argument is ignored because, by the time the OnStopRequestEvent
    139  // is actually processed, the status of the request may have changed :-(
    140  // To make sure that an accurate status code is always used, GetStatus() is
    141  // called when the OnStopRequestEvent is actually processed (see above).
    142 
    143  RefPtr<nsOnStopRequestEvent> ev = new nsOnStopRequestEvent(this, request);
    144 
    145  LOG(("post stopevent=%p\n", ev.get()));
    146  return FireEvent(ev);
    147 }
    148 
    149 //-----------------------------------------------------------------------------
    150 // nsRequestObserverProxy::nsIRequestObserverProxy implementation...
    151 //-----------------------------------------------------------------------------
    152 
    153 NS_IMETHODIMP
    154 nsRequestObserverProxy::Init(nsIRequestObserver* observer,
    155                             nsISupports* context) {
    156  NS_ENSURE_ARG_POINTER(observer);
    157  mObserver = new nsMainThreadPtrHolder<nsIRequestObserver>(
    158      "nsRequestObserverProxy::mObserver", observer);
    159  mContext = new nsMainThreadPtrHolder<nsISupports>(
    160      "nsRequestObserverProxy::mContext", context);
    161 
    162  return NS_OK;
    163 }
    164 
    165 //-----------------------------------------------------------------------------
    166 // nsRequestObserverProxy implementation...
    167 //-----------------------------------------------------------------------------
    168 
    169 nsresult nsRequestObserverProxy::FireEvent(nsARequestObserverEvent* event) {
    170  nsCOMPtr<nsIEventTarget> mainThread(GetMainThreadSerialEventTarget());
    171  return mainThread->Dispatch(event, NS_DISPATCH_NORMAL);
    172 }
    173 
    174 }  // namespace net
    175 }  // namespace mozilla