tor-browser

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

nsViewSourceChannel.cpp (38582B)


      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim:set ts=4 sw=2 sts=2 et: */
      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/. */
      6 
      7 #include "nsViewSourceChannel.h"
      8 #include "mozilla/NullPrincipal.h"
      9 #include "nsContentSecurityManager.h"
     10 #include "nsContentUtils.h"
     11 #include "nsHttpChannel.h"
     12 #include "nsIExternalProtocolHandler.h"
     13 #include "nsIHttpHeaderVisitor.h"
     14 #include "nsIIOService.h"
     15 #include "nsIInputStreamChannel.h"
     16 #include "nsIReferrerInfo.h"
     17 #include "nsMimeTypes.h"
     18 #include "nsNetUtil.h"
     19 #include "nsServiceManagerUtils.h"
     20 
     21 NS_IMPL_ADDREF(nsViewSourceChannel)
     22 NS_IMPL_RELEASE(nsViewSourceChannel)
     23 /*
     24  This QI uses NS_INTERFACE_MAP_ENTRY_CONDITIONAL to check for
     25  non-nullness of mHttpChannel, mCachingChannel, and mUploadChannel.
     26 */
     27 NS_INTERFACE_MAP_BEGIN(nsViewSourceChannel)
     28  NS_INTERFACE_MAP_ENTRY(nsIViewSourceChannel)
     29  NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
     30  NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
     31  NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
     32  NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink)
     33  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannel, mHttpChannel)
     34  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIIdentChannel, mHttpChannel)
     35  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannelInternal,
     36                                     mHttpChannelInternal)
     37  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsICachingChannel, mCachingChannel)
     38  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsICacheInfoChannel, mCacheInfoChannel)
     39  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIUploadChannel, mUploadChannel)
     40  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIFormPOSTActionChannel, mPostChannel)
     41  NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIChildChannel, mChildChannel)
     42  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIRequest, nsIViewSourceChannel)
     43  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIChannel, nsIViewSourceChannel)
     44  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIViewSourceChannel)
     45 NS_INTERFACE_MAP_END
     46 
     47 static nsresult WillUseExternalProtocolHandler(nsIIOService* aIOService,
     48                                               const char* aScheme) {
     49  nsCOMPtr<nsIProtocolHandler> handler;
     50  nsresult rv =
     51      aIOService->GetProtocolHandler(aScheme, getter_AddRefs(handler));
     52  if (NS_FAILED(rv)) {
     53    return rv;
     54  }
     55 
     56  nsCOMPtr<nsIExternalProtocolHandler> externalHandler =
     57      do_QueryInterface(handler);
     58  // We should not allow view-source to open any external app.
     59  if (externalHandler) {
     60    NS_WARNING(nsPrintfCString("blocking view-source:%s:", aScheme).get());
     61    return NS_ERROR_MALFORMED_URI;
     62  }
     63 
     64  return NS_OK;
     65 }
     66 
     67 nsresult nsViewSourceChannel::Init(nsIURI* uri, nsILoadInfo* aLoadInfo) {
     68  mOriginalURI = uri;
     69 
     70  nsAutoCString path;
     71  nsresult rv = uri->GetPathQueryRef(path);
     72  if (NS_FAILED(rv)) return rv;
     73 
     74  nsCOMPtr<nsIIOService> pService(do_GetIOService(&rv));
     75  if (NS_FAILED(rv)) return rv;
     76 
     77  nsAutoCString scheme;
     78  rv = pService->ExtractScheme(path, scheme);
     79  if (NS_FAILED(rv)) return rv;
     80 
     81  // prevent viewing source of javascript URIs (see bug 204779)
     82  if (scheme.EqualsLiteral("javascript")) {
     83    NS_WARNING("blocking view-source:javascript:");
     84    return NS_ERROR_INVALID_ARG;
     85  }
     86 
     87  rv = WillUseExternalProtocolHandler(pService, scheme.get());
     88  if (NS_FAILED(rv)) {
     89    return rv;
     90  }
     91 
     92  nsCOMPtr<nsIURI> newChannelURI;
     93  rv = pService->NewURI(path, nullptr, nullptr, getter_AddRefs(newChannelURI));
     94  NS_ENSURE_SUCCESS(rv, rv);
     95 
     96  rv = pService->NewChannelFromURIWithLoadInfo(newChannelURI, aLoadInfo,
     97                                               getter_AddRefs(mChannel));
     98  NS_ENSURE_SUCCESS(rv, rv);
     99 
    100  mIsSrcdocChannel = false;
    101 
    102  mChannel->SetOriginalURI(mOriginalURI);
    103  UpdateChannelInterfaces();
    104 
    105  return NS_OK;
    106 }
    107 
    108 nsresult nsViewSourceChannel::InitSrcdoc(nsIURI* aURI, nsIURI* aBaseURI,
    109                                         const nsAString& aSrcdoc,
    110                                         nsILoadInfo* aLoadInfo) {
    111  nsresult rv;
    112 
    113  nsCOMPtr<nsIURI> inStreamURI;
    114  // Need to strip view-source: from the URI.  Hardcoded to
    115  // about:srcdoc as this is the only permissible URI for srcdoc
    116  // loads
    117  rv = NS_NewURI(getter_AddRefs(inStreamURI), u"about:srcdoc"_ns);
    118  NS_ENSURE_SUCCESS(rv, rv);
    119 
    120  rv = NS_NewInputStreamChannelInternal(getter_AddRefs(mChannel), inStreamURI,
    121                                        aSrcdoc, "text/html"_ns, aLoadInfo,
    122                                        true);
    123 
    124  NS_ENSURE_SUCCESS(rv, rv);
    125  mOriginalURI = aURI;
    126  mIsSrcdocChannel = true;
    127 
    128  mChannel->SetOriginalURI(mOriginalURI);
    129  UpdateChannelInterfaces();
    130 
    131  rv = UpdateLoadInfoResultPrincipalURI();
    132  NS_ENSURE_SUCCESS(rv, rv);
    133 
    134  nsCOMPtr<nsIInputStreamChannel> isc = do_QueryInterface(mChannel);
    135  MOZ_ASSERT(isc);
    136  isc->SetBaseURI(aBaseURI);
    137  return NS_OK;
    138 }
    139 
    140 void nsViewSourceChannel::UpdateChannelInterfaces() {
    141  mHttpChannel = do_QueryInterface(mChannel);
    142  mHttpChannelInternal = do_QueryInterface(mChannel);
    143  mCachingChannel = do_QueryInterface(mChannel);
    144  mCacheInfoChannel = do_QueryInterface(mChannel);
    145  mUploadChannel = do_QueryInterface(mChannel);
    146  mPostChannel = do_QueryInterface(mChannel);
    147  mChildChannel = do_QueryInterface(mChannel);
    148 }
    149 
    150 void nsViewSourceChannel::ReleaseListeners() {
    151  mListener = nullptr;
    152  mCallbacks = nullptr;
    153 }
    154 
    155 nsresult nsViewSourceChannel::UpdateLoadInfoResultPrincipalURI() {
    156  nsresult rv;
    157 
    158  MOZ_ASSERT(mChannel);
    159 
    160  nsCOMPtr<nsILoadInfo> channelLoadInfo = mChannel->LoadInfo();
    161  nsCOMPtr<nsIURI> channelResultPrincipalURI;
    162  rv = channelLoadInfo->GetResultPrincipalURI(
    163      getter_AddRefs(channelResultPrincipalURI));
    164  if (NS_FAILED(rv)) {
    165    return rv;
    166  }
    167 
    168  if (!channelResultPrincipalURI) {
    169    mChannel->GetOriginalURI(getter_AddRefs(channelResultPrincipalURI));
    170    return NS_OK;
    171  }
    172 
    173  if (!channelResultPrincipalURI) {
    174    return NS_ERROR_UNEXPECTED;
    175  }
    176 
    177  if (channelResultPrincipalURI->SchemeIs("view-source")) {
    178    // already view-source
    179    return NS_OK;
    180  }
    181 
    182  nsCOMPtr<nsIURI> updatedResultPrincipalURI;
    183  rv = BuildViewSourceURI(channelResultPrincipalURI,
    184                          getter_AddRefs(updatedResultPrincipalURI));
    185  if (NS_FAILED(rv)) {
    186    return rv;
    187  }
    188 
    189  rv = channelLoadInfo->SetResultPrincipalURI(updatedResultPrincipalURI);
    190  if (NS_FAILED(rv)) {
    191    return rv;
    192  }
    193 
    194  return NS_OK;
    195 }
    196 
    197 nsresult nsViewSourceChannel::BuildViewSourceURI(nsIURI* aURI,
    198                                                 nsIURI** aResult) {
    199  nsresult rv;
    200 
    201  // protect ourselves against broken channel implementations
    202  if (!aURI) {
    203    NS_ERROR("no URI to build view-source uri!");
    204    return NS_ERROR_UNEXPECTED;
    205  }
    206 
    207  nsAutoCString spec;
    208  rv = aURI->GetSpec(spec);
    209  if (NS_FAILED(rv)) {
    210    return rv;
    211  }
    212 
    213  return NS_NewURI(aResult, "view-source:"_ns + spec);
    214 }
    215 
    216 ////////////////////////////////////////////////////////////////////////////////
    217 // nsIRequest methods:
    218 
    219 NS_IMETHODIMP
    220 nsViewSourceChannel::GetName(nsACString& result) {
    221  nsCOMPtr<nsIURI> uri;
    222  GetURI(getter_AddRefs(uri));
    223  if (uri) {
    224    return uri->GetSpec(result);
    225  }
    226  return NS_ERROR_NOT_IMPLEMENTED;
    227 }
    228 
    229 NS_IMETHODIMP
    230 nsViewSourceChannel::GetTransferSize(uint64_t* aTransferSize) {
    231  return NS_ERROR_NOT_IMPLEMENTED;
    232 }
    233 
    234 NS_IMETHODIMP
    235 nsViewSourceChannel::GetRequestSize(uint64_t* aRequestSize) {
    236  return NS_ERROR_NOT_IMPLEMENTED;
    237 }
    238 
    239 NS_IMETHODIMP
    240 nsViewSourceChannel::GetDecodedBodySize(uint64_t* aDecodedBodySize) {
    241  return NS_ERROR_NOT_IMPLEMENTED;
    242 }
    243 
    244 NS_IMETHODIMP
    245 nsViewSourceChannel::GetEncodedBodySize(uint64_t* aEncodedBodySize) {
    246  return NS_ERROR_NOT_IMPLEMENTED;
    247 }
    248 
    249 NS_IMETHODIMP
    250 nsViewSourceChannel::IsPending(bool* result) {
    251  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    252 
    253  return mChannel->IsPending(result);
    254 }
    255 
    256 NS_IMETHODIMP
    257 nsViewSourceChannel::GetStatus(nsresult* status) {
    258  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    259 
    260  return mChannel->GetStatus(status);
    261 }
    262 
    263 NS_IMETHODIMP nsViewSourceChannel::SetCanceledReason(
    264    const nsACString& aReason) {
    265  return nsIViewSourceChannel::SetCanceledReasonImpl(aReason);
    266 }
    267 
    268 NS_IMETHODIMP nsViewSourceChannel::GetCanceledReason(nsACString& aReason) {
    269  return nsIViewSourceChannel::GetCanceledReasonImpl(aReason);
    270 }
    271 
    272 NS_IMETHODIMP nsViewSourceChannel::CancelWithReason(nsresult aStatus,
    273                                                    const nsACString& aReason) {
    274  return nsIViewSourceChannel::CancelWithReasonImpl(aStatus, aReason);
    275 }
    276 
    277 NS_IMETHODIMP
    278 nsViewSourceChannel::Cancel(nsresult status) {
    279  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    280 
    281  return mChannel->Cancel(status);
    282 }
    283 
    284 NS_IMETHODIMP
    285 nsViewSourceChannel::GetCanceled(bool* aCanceled) {
    286  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    287 
    288  return mChannel->GetCanceled(aCanceled);
    289 }
    290 
    291 NS_IMETHODIMP
    292 nsViewSourceChannel::Suspend(void) {
    293  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    294 
    295  return mChannel->Suspend();
    296 }
    297 
    298 NS_IMETHODIMP
    299 nsViewSourceChannel::Resume(void) {
    300  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    301 
    302  return mChannel->Resume();
    303 }
    304 
    305 ////////////////////////////////////////////////////////////////////////////////
    306 // nsIChannel methods:
    307 
    308 NS_IMETHODIMP
    309 nsViewSourceChannel::GetOriginalURI(nsIURI** aURI) {
    310  *aURI = do_AddRef(mOriginalURI).take();
    311  return NS_OK;
    312 }
    313 
    314 NS_IMETHODIMP
    315 nsViewSourceChannel::SetOriginalURI(nsIURI* aURI) {
    316  NS_ENSURE_ARG_POINTER(aURI);
    317  mOriginalURI = aURI;
    318  return NS_OK;
    319 }
    320 
    321 NS_IMETHODIMP
    322 nsViewSourceChannel::GetURI(nsIURI** aURI) {
    323  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    324 
    325  nsCOMPtr<nsIURI> uri;
    326  nsresult rv = mChannel->GetURI(getter_AddRefs(uri));
    327  if (NS_FAILED(rv)) {
    328    return rv;
    329  }
    330 
    331  return BuildViewSourceURI(uri, aURI);
    332 }
    333 
    334 NS_IMETHODIMP
    335 nsViewSourceChannel::Open(nsIInputStream** aStream) {
    336  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    337  return Open(aStream);
    338 }
    339 
    340 NS_IMETHODIMP
    341 nsViewSourceChannel::AsyncOpen(nsIStreamListener* aListener) {
    342  // We can't ensure GetInitialSecurityCheckDone here
    343 
    344  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    345 
    346  mListener = aListener;
    347 
    348  /*
    349   * We want to add ourselves to the loadgroup before opening
    350   * mChannel, since we want to make sure we're in the loadgroup
    351   * when mChannel finishes and fires OnStopRequest()
    352   */
    353 
    354  nsCOMPtr<nsILoadGroup> loadGroup;
    355  mChannel->GetLoadGroup(getter_AddRefs(loadGroup));
    356  if (loadGroup) {
    357    loadGroup->AddRequest(static_cast<nsIViewSourceChannel*>(this), nullptr);
    358  }
    359 
    360  nsresult rv = NS_OK;
    361  rv = mChannel->AsyncOpen(this);
    362 
    363  if (NS_FAILED(rv) && loadGroup) {
    364    loadGroup->RemoveRequest(static_cast<nsIViewSourceChannel*>(this), nullptr,
    365                             rv);
    366  }
    367 
    368  if (NS_SUCCEEDED(rv)) {
    369    // We do this here to make sure all notification callbacks changes have been
    370    // made first before we inject this view-source channel.
    371    mChannel->GetNotificationCallbacks(getter_AddRefs(mCallbacks));
    372    mChannel->SetNotificationCallbacks(this);
    373 
    374    MOZ_ASSERT(mCallbacks != this, "We have a cycle");
    375 
    376    mOpened = true;
    377  }
    378 
    379  if (NS_FAILED(rv)) {
    380    ReleaseListeners();
    381  }
    382 
    383  return rv;
    384 }
    385 
    386 /*
    387 * Both the view source channel and mChannel are added to the
    388 * loadgroup.  There should never be more than one request in the
    389 * loadgroup that has LOAD_DOCUMENT_URI set.  The one that has this
    390 * flag set is the request whose URI is used to refetch the document,
    391 * so it better be the viewsource channel.
    392 *
    393 * Therefore, we need to make sure that
    394 * 1) The load flags on mChannel _never_ include LOAD_DOCUMENT_URI
    395 * 2) The load flags on |this| include LOAD_DOCUMENT_URI when it was
    396 *    set via SetLoadFlags (mIsDocument keeps track of this flag).
    397 */
    398 
    399 NS_IMETHODIMP
    400 nsViewSourceChannel::GetLoadFlags(uint32_t* aLoadFlags) {
    401  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    402 
    403  nsresult rv = mChannel->GetLoadFlags(aLoadFlags);
    404  if (NS_FAILED(rv)) return rv;
    405 
    406  // This should actually be just LOAD_DOCUMENT_URI but the win32 compiler
    407  // fails to deal due to amiguous inheritance.  nsIChannel::LOAD_DOCUMENT_URI
    408  // also fails; the Win32 compiler thinks that's supposed to be a method.
    409  if (mIsDocument) *aLoadFlags |= ::nsIChannel::LOAD_DOCUMENT_URI;
    410 
    411  return rv;
    412 }
    413 
    414 NS_IMETHODIMP
    415 nsViewSourceChannel::SetLoadFlags(uint32_t aLoadFlags) {
    416  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    417 
    418  // "View source" always wants the currently cached content.
    419  // We also want to have _this_ channel, not mChannel to be the
    420  // 'document' channel in the loadgroup.
    421 
    422  // These should actually be just LOAD_FROM_CACHE and LOAD_DOCUMENT_URI but
    423  // the win32 compiler fails to deal due to amiguous inheritance.
    424  // nsIChannel::LOAD_DOCUMENT_URI/nsIRequest::LOAD_FROM_CACHE also fails; the
    425  // Win32 compiler thinks that's supposed to be a method.
    426  mIsDocument = (aLoadFlags & ::nsIChannel::LOAD_DOCUMENT_URI) != 0;
    427 
    428  nsresult rv =
    429      mChannel->SetLoadFlags((aLoadFlags | ::nsIRequest::LOAD_FROM_CACHE) &
    430                             ~::nsIChannel::LOAD_DOCUMENT_URI);
    431  if (NS_WARN_IF(NS_FAILED(rv))) {
    432    return rv;
    433  }
    434 
    435  if (mHttpChannel) {
    436    rv = mHttpChannel->SetIsMainDocumentChannel(
    437        aLoadFlags & ::nsIChannel::LOAD_DOCUMENT_URI);
    438    MOZ_ASSERT(NS_SUCCEEDED(rv));
    439  }
    440 
    441  return NS_OK;
    442 }
    443 
    444 NS_IMETHODIMP
    445 nsViewSourceChannel::GetTRRMode(nsIRequest::TRRMode* aTRRMode) {
    446  return nsIViewSourceChannel::GetTRRModeImpl(aTRRMode);
    447 }
    448 
    449 NS_IMETHODIMP
    450 nsViewSourceChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) {
    451  return nsIViewSourceChannel::SetTRRModeImpl(aTRRMode);
    452 }
    453 
    454 NS_IMETHODIMP
    455 nsViewSourceChannel::GetContentType(nsACString& aContentType) {
    456  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    457 
    458  aContentType.Truncate();
    459 
    460  if (mContentType.IsEmpty()) {
    461    // Get the current content type
    462    nsresult rv;
    463    nsAutoCString contentType;
    464    rv = mChannel->GetContentType(contentType);
    465    if (NS_FAILED(rv)) return rv;
    466 
    467    // If we don't know our type, just say so.  The unknown
    468    // content decoder will then kick in automatically, and it
    469    // will call our SetOriginalContentType method instead of our
    470    // SetContentType method to set the type it determines.
    471    if (!contentType.EqualsLiteral(UNKNOWN_CONTENT_TYPE) &&
    472        !contentType.IsEmpty()) {
    473      contentType = VIEWSOURCE_CONTENT_TYPE;
    474    }
    475 
    476    mContentType = contentType;
    477  }
    478 
    479  aContentType = mContentType;
    480  return NS_OK;
    481 }
    482 
    483 NS_IMETHODIMP
    484 nsViewSourceChannel::SetContentType(const nsACString& aContentType) {
    485  // Our GetContentType() currently returns VIEWSOURCE_CONTENT_TYPE
    486  //
    487  // However, during the parsing phase the parser calls our
    488  // channel's GetContentType(). Returning the string above trips up
    489  // the parser. In order to avoid messy changes and not to have the
    490  // parser depend on nsIViewSourceChannel Vidur proposed the
    491  // following solution:
    492  //
    493  // The ViewSourceChannel initially returns a content type of
    494  // VIEWSOURCE_CONTENT_TYPE.  Based on this type decisions to
    495  // create a viewer for doing a view source are made.  After the
    496  // viewer is created, nsLayoutDLF::CreateInstance() calls this
    497  // SetContentType() with the original content type.  When it's
    498  // time for the parser to find out the content type it will call
    499  // our channel's GetContentType() and it will get the original
    500  // content type, such as, text/html and everything is kosher from
    501  // then on.
    502 
    503  if (!mOpened) {
    504    // We do not take hints
    505    return NS_ERROR_NOT_AVAILABLE;
    506  }
    507 
    508  mContentType = aContentType;
    509  return NS_OK;
    510 }
    511 
    512 NS_IMETHODIMP
    513 nsViewSourceChannel::GetContentCharset(nsACString& aContentCharset) {
    514  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    515 
    516  return mChannel->GetContentCharset(aContentCharset);
    517 }
    518 
    519 NS_IMETHODIMP
    520 nsViewSourceChannel::SetContentCharset(const nsACString& aContentCharset) {
    521  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    522 
    523  return mChannel->SetContentCharset(aContentCharset);
    524 }
    525 
    526 // We don't forward these methods becacuse content-disposition isn't whitelisted
    527 // (see GetResponseHeader/VisitResponseHeaders).
    528 NS_IMETHODIMP
    529 nsViewSourceChannel::GetContentDisposition(uint32_t* aContentDisposition) {
    530  return NS_ERROR_NOT_AVAILABLE;
    531 }
    532 
    533 NS_IMETHODIMP
    534 nsViewSourceChannel::SetContentDisposition(uint32_t aContentDisposition) {
    535  return NS_ERROR_NOT_AVAILABLE;
    536 }
    537 
    538 NS_IMETHODIMP
    539 nsViewSourceChannel::GetContentDispositionFilename(
    540    nsAString& aContentDispositionFilename) {
    541  return NS_ERROR_NOT_AVAILABLE;
    542 }
    543 
    544 NS_IMETHODIMP
    545 nsViewSourceChannel::SetContentDispositionFilename(
    546    const nsAString& aContentDispositionFilename) {
    547  return NS_ERROR_NOT_AVAILABLE;
    548 }
    549 
    550 NS_IMETHODIMP
    551 nsViewSourceChannel::GetContentDispositionHeader(
    552    nsACString& aContentDispositionHeader) {
    553  return NS_ERROR_NOT_AVAILABLE;
    554 }
    555 
    556 NS_IMETHODIMP
    557 nsViewSourceChannel::GetContentLength(int64_t* aContentLength) {
    558  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    559 
    560  return mChannel->GetContentLength(aContentLength);
    561 }
    562 
    563 NS_IMETHODIMP
    564 nsViewSourceChannel::SetContentLength(int64_t aContentLength) {
    565  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    566 
    567  return mChannel->SetContentLength(aContentLength);
    568 }
    569 
    570 NS_IMETHODIMP
    571 nsViewSourceChannel::GetLoadGroup(nsILoadGroup** aLoadGroup) {
    572  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    573 
    574  return mChannel->GetLoadGroup(aLoadGroup);
    575 }
    576 
    577 NS_IMETHODIMP
    578 nsViewSourceChannel::SetLoadGroup(nsILoadGroup* aLoadGroup) {
    579  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    580 
    581  return mChannel->SetLoadGroup(aLoadGroup);
    582 }
    583 
    584 NS_IMETHODIMP
    585 nsViewSourceChannel::GetOwner(nsISupports** aOwner) {
    586  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    587 
    588  return mChannel->GetOwner(aOwner);
    589 }
    590 
    591 NS_IMETHODIMP
    592 nsViewSourceChannel::SetOwner(nsISupports* aOwner) {
    593  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    594 
    595  return mChannel->SetOwner(aOwner);
    596 }
    597 
    598 NS_IMETHODIMP
    599 nsViewSourceChannel::GetLoadInfo(nsILoadInfo** aLoadInfo) {
    600  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    601 
    602  return mChannel->GetLoadInfo(aLoadInfo);
    603 }
    604 
    605 NS_IMETHODIMP
    606 nsViewSourceChannel::SetLoadInfo(nsILoadInfo* aLoadInfo) {
    607  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    608  MOZ_RELEASE_ASSERT(aLoadInfo, "loadinfo can't be null");
    609  return mChannel->SetLoadInfo(aLoadInfo);
    610 }
    611 
    612 NS_IMETHODIMP
    613 nsViewSourceChannel::GetIsDocument(bool* aIsDocument) {
    614  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    615 
    616  return mChannel->GetIsDocument(aIsDocument);
    617 }
    618 
    619 NS_IMETHODIMP
    620 nsViewSourceChannel::GetNotificationCallbacks(
    621    nsIInterfaceRequestor** aNotificationCallbacks) {
    622  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    623 
    624  return mChannel->GetNotificationCallbacks(aNotificationCallbacks);
    625 }
    626 
    627 NS_IMETHODIMP
    628 nsViewSourceChannel::SetNotificationCallbacks(
    629    nsIInterfaceRequestor* aNotificationCallbacks) {
    630  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    631 
    632  return mChannel->SetNotificationCallbacks(aNotificationCallbacks);
    633 }
    634 
    635 NS_IMETHODIMP
    636 nsViewSourceChannel::GetSecurityInfo(nsITransportSecurityInfo** aSecurityInfo) {
    637  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    638 
    639  return mChannel->GetSecurityInfo(aSecurityInfo);
    640 }
    641 
    642 // nsIViewSourceChannel methods
    643 NS_IMETHODIMP
    644 nsViewSourceChannel::GetOriginalContentType(nsACString& aContentType) {
    645  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    646 
    647  return mChannel->GetContentType(aContentType);
    648 }
    649 
    650 NS_IMETHODIMP
    651 nsViewSourceChannel::SetOriginalContentType(const nsACString& aContentType) {
    652  NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
    653 
    654  // clear our cached content-type value
    655  mContentType.Truncate();
    656 
    657  return mChannel->SetContentType(aContentType);
    658 }
    659 
    660 NS_IMETHODIMP
    661 nsViewSourceChannel::GetIsSrcdocChannel(bool* aIsSrcdocChannel) {
    662  *aIsSrcdocChannel = mIsSrcdocChannel;
    663  return NS_OK;
    664 }
    665 
    666 NS_IMETHODIMP
    667 nsViewSourceChannel::GetBaseURI(nsIURI** aBaseURI) {
    668  if (mIsSrcdocChannel) {
    669    nsCOMPtr<nsIInputStreamChannel> isc = do_QueryInterface(mChannel);
    670    if (isc) {
    671      return isc->GetBaseURI(aBaseURI);
    672    }
    673  }
    674  *aBaseURI = do_AddRef(mBaseURI).take();
    675  return NS_OK;
    676 }
    677 
    678 NS_IMETHODIMP
    679 nsViewSourceChannel::SetBaseURI(nsIURI* aBaseURI) {
    680  mBaseURI = aBaseURI;
    681  return NS_OK;
    682 }
    683 
    684 nsIChannel* nsViewSourceChannel::GetInnerChannel() { return mChannel; }
    685 
    686 NS_IMETHODIMP
    687 nsViewSourceChannel::GetProtocolVersion(nsACString& aProtocolVersion) {
    688  return NS_ERROR_NOT_IMPLEMENTED;
    689 }
    690 
    691 // nsIRequestObserver methods
    692 NS_IMETHODIMP
    693 nsViewSourceChannel::OnStartRequest(nsIRequest* aRequest) {
    694  NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
    695  // The channel may have gotten redirected... Time to update our info
    696  mChannel = do_QueryInterface(aRequest);
    697  UpdateChannelInterfaces();
    698 
    699  nsresult rv = UpdateLoadInfoResultPrincipalURI();
    700  if (NS_FAILED(rv)) {
    701    Cancel(rv);
    702  }
    703 
    704  return mListener->OnStartRequest(static_cast<nsIViewSourceChannel*>(this));
    705 }
    706 
    707 NS_IMETHODIMP
    708 nsViewSourceChannel::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) {
    709  NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
    710  if (mChannel) {
    711    nsCOMPtr<nsILoadGroup> loadGroup;
    712    mChannel->GetLoadGroup(getter_AddRefs(loadGroup));
    713    if (loadGroup) {
    714      loadGroup->RemoveRequest(static_cast<nsIViewSourceChannel*>(this),
    715                               nullptr, aStatus);
    716    }
    717  }
    718 
    719  nsresult rv = mListener->OnStopRequest(
    720      static_cast<nsIViewSourceChannel*>(this), aStatus);
    721 
    722  ReleaseListeners();
    723 
    724  return rv;
    725 }
    726 
    727 // nsIStreamListener methods
    728 NS_IMETHODIMP
    729 nsViewSourceChannel::OnDataAvailable(nsIRequest* aRequest,
    730                                     nsIInputStream* aInputStream,
    731                                     uint64_t aSourceOffset, uint32_t aLength) {
    732  NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
    733  return mListener->OnDataAvailable(static_cast<nsIViewSourceChannel*>(this),
    734                                    aInputStream, aSourceOffset, aLength);
    735 }
    736 
    737 // nsIHttpChannel methods
    738 
    739 // We want to forward most of nsIHttpChannel over to mHttpChannel, but we want
    740 // to override GetRequestHeader and VisitHeaders. The reason is that we don't
    741 // want various headers like Link: and Refresh: applying to view-source.
    742 NS_IMETHODIMP
    743 nsViewSourceChannel::GetChannelId(uint64_t* aChannelId) {
    744  NS_ENSURE_ARG_POINTER(aChannelId);
    745  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    746                       : mHttpChannel->GetChannelId(aChannelId);
    747 }
    748 
    749 NS_IMETHODIMP
    750 nsViewSourceChannel::SetChannelId(uint64_t aChannelId) {
    751  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    752                       : mHttpChannel->SetChannelId(aChannelId);
    753 }
    754 
    755 NS_IMETHODIMP
    756 nsViewSourceChannel::GetTopLevelContentWindowId(uint64_t* aWindowId) {
    757  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    758                       : mHttpChannel->GetTopLevelContentWindowId(aWindowId);
    759 }
    760 
    761 NS_IMETHODIMP
    762 nsViewSourceChannel::SetTopLevelContentWindowId(uint64_t aWindowId) {
    763  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    764                       : mHttpChannel->SetTopLevelContentWindowId(aWindowId);
    765 }
    766 
    767 NS_IMETHODIMP
    768 nsViewSourceChannel::GetBrowserId(uint64_t* aId) {
    769  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    770                       : mHttpChannel->GetBrowserId(aId);
    771 }
    772 
    773 NS_IMETHODIMP
    774 nsViewSourceChannel::SetBrowserId(uint64_t aId) {
    775  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    776                       : mHttpChannel->SetBrowserId(aId);
    777 }
    778 
    779 NS_IMETHODIMP
    780 nsViewSourceChannel::GetRequestMethod(nsACString& aRequestMethod) {
    781  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    782                       : mHttpChannel->GetRequestMethod(aRequestMethod);
    783 }
    784 
    785 NS_IMETHODIMP
    786 nsViewSourceChannel::SetRequestMethod(const nsACString& aRequestMethod) {
    787  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    788                       : mHttpChannel->SetRequestMethod(aRequestMethod);
    789 }
    790 
    791 NS_IMETHODIMP
    792 nsViewSourceChannel::GetReferrerInfo(nsIReferrerInfo** aReferrerInfo) {
    793  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    794                       : mHttpChannel->GetReferrerInfo(aReferrerInfo);
    795 }
    796 
    797 NS_IMETHODIMP
    798 nsViewSourceChannel::SetReferrerInfo(nsIReferrerInfo* aReferrerInfo) {
    799  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    800                       : mHttpChannel->SetReferrerInfo(aReferrerInfo);
    801 }
    802 
    803 NS_IMETHODIMP nsViewSourceChannel::SetReferrerInfoWithoutClone(
    804    nsIReferrerInfo* aReferrerInfo) {
    805  return !mHttpChannel
    806             ? NS_ERROR_NULL_POINTER
    807             : mHttpChannel->SetReferrerInfoWithoutClone(aReferrerInfo);
    808 }
    809 
    810 NS_IMETHODIMP
    811 nsViewSourceChannel::GetRequestHeader(const nsACString& aHeader,
    812                                      nsACString& aValue) {
    813  aValue.Truncate();
    814  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    815                       : mHttpChannel->GetRequestHeader(aHeader, aValue);
    816 }
    817 
    818 NS_IMETHODIMP
    819 nsViewSourceChannel::SetRequestHeader(const nsACString& aHeader,
    820                                      const nsACString& aValue, bool aMerge) {
    821  return !mHttpChannel
    822             ? NS_ERROR_NULL_POINTER
    823             : mHttpChannel->SetRequestHeader(aHeader, aValue, aMerge);
    824 }
    825 
    826 NS_IMETHODIMP
    827 nsViewSourceChannel::SetNewReferrerInfo(
    828    const nsACString& aUrl, nsIReferrerInfo::ReferrerPolicyIDL aPolicy,
    829    bool aSendReferrer) {
    830  return !mHttpChannel
    831             ? NS_ERROR_NULL_POINTER
    832             : mHttpChannel->SetNewReferrerInfo(aUrl, aPolicy, aSendReferrer);
    833 }
    834 
    835 NS_IMETHODIMP
    836 nsViewSourceChannel::SetEmptyRequestHeader(const nsACString& aHeader) {
    837  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    838                       : mHttpChannel->SetEmptyRequestHeader(aHeader);
    839 }
    840 
    841 NS_IMETHODIMP
    842 nsViewSourceChannel::VisitRequestHeaders(nsIHttpHeaderVisitor* aVisitor) {
    843  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    844                       : mHttpChannel->VisitRequestHeaders(aVisitor);
    845 }
    846 
    847 NS_IMETHODIMP
    848 nsViewSourceChannel::VisitNonDefaultRequestHeaders(
    849    nsIHttpHeaderVisitor* aVisitor) {
    850  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    851                       : mHttpChannel->VisitNonDefaultRequestHeaders(aVisitor);
    852 }
    853 
    854 NS_IMETHODIMP
    855 nsViewSourceChannel::ShouldStripRequestBodyHeader(const nsACString& aMethod,
    856                                                  bool* aResult) {
    857  return !mHttpChannel
    858             ? NS_ERROR_NULL_POINTER
    859             : mHttpChannel->ShouldStripRequestBodyHeader(aMethod, aResult);
    860 }
    861 
    862 NS_IMETHODIMP
    863 nsViewSourceChannel::GetAllowSTS(bool* aAllowSTS) {
    864  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    865                       : mHttpChannel->GetAllowSTS(aAllowSTS);
    866 }
    867 
    868 NS_IMETHODIMP
    869 nsViewSourceChannel::SetAllowSTS(bool aAllowSTS) {
    870  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    871                       : mHttpChannel->SetAllowSTS(aAllowSTS);
    872 }
    873 
    874 NS_IMETHODIMP
    875 nsViewSourceChannel::GetRedirectionLimit(uint32_t* aRedirectionLimit) {
    876  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    877                       : mHttpChannel->GetRedirectionLimit(aRedirectionLimit);
    878 }
    879 
    880 NS_IMETHODIMP
    881 nsViewSourceChannel::SetRedirectionLimit(uint32_t aRedirectionLimit) {
    882  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    883                       : mHttpChannel->SetRedirectionLimit(aRedirectionLimit);
    884 }
    885 
    886 NS_IMETHODIMP
    887 nsViewSourceChannel::GetResponseStatus(uint32_t* aResponseStatus) {
    888  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    889                       : mHttpChannel->GetResponseStatus(aResponseStatus);
    890 }
    891 
    892 NS_IMETHODIMP
    893 nsViewSourceChannel::GetResponseStatusText(nsACString& aResponseStatusText) {
    894  return !mHttpChannel
    895             ? NS_ERROR_NULL_POINTER
    896             : mHttpChannel->GetResponseStatusText(aResponseStatusText);
    897 }
    898 
    899 NS_IMETHODIMP
    900 nsViewSourceChannel::GetRequestSucceeded(bool* aRequestSucceeded) {
    901  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    902                       : mHttpChannel->GetRequestSucceeded(aRequestSucceeded);
    903 }
    904 
    905 NS_IMETHODIMP
    906 nsViewSourceChannel::GetResponseHeader(const nsACString& aHeader,
    907                                       nsACString& aValue) {
    908  aValue.Truncate();
    909  if (!mHttpChannel) return NS_ERROR_NULL_POINTER;
    910 
    911  if (!aHeader.Equals("Content-Type"_ns, nsCaseInsensitiveCStringComparator) &&
    912      !aHeader.Equals("Content-Security-Policy"_ns,
    913                      nsCaseInsensitiveCStringComparator) &&
    914      !aHeader.Equals("Content-Security-Policy-Report-Only"_ns,
    915                      nsCaseInsensitiveCStringComparator) &&
    916      !aHeader.Equals("X-Frame-Options"_ns,
    917                      nsCaseInsensitiveCStringComparator)) {
    918    // We simulate the NS_ERROR_NOT_AVAILABLE error which is produced by
    919    // GetResponseHeader via nsHttpHeaderArray::GetHeader when the entry is
    920    // not present, such that it appears as though no headers except for the
    921    // whitelisted ones were set on this channel.
    922    return NS_ERROR_NOT_AVAILABLE;
    923  }
    924 
    925  return mHttpChannel->GetResponseHeader(aHeader, aValue);
    926 }
    927 
    928 NS_IMETHODIMP
    929 nsViewSourceChannel::SetResponseHeader(const nsACString& header,
    930                                       const nsACString& value, bool merge) {
    931  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    932                       : mHttpChannel->SetResponseHeader(header, value, merge);
    933 }
    934 
    935 NS_IMETHODIMP
    936 nsViewSourceChannel::VisitResponseHeaders(nsIHttpHeaderVisitor* aVisitor) {
    937  if (!mHttpChannel) return NS_ERROR_NULL_POINTER;
    938 
    939  constexpr auto contentTypeStr = "Content-Type"_ns;
    940  nsAutoCString contentType;
    941  nsresult rv = mHttpChannel->GetResponseHeader(contentTypeStr, contentType);
    942  if (NS_SUCCEEDED(rv)) {
    943    return aVisitor->VisitHeader(contentTypeStr, contentType);
    944  }
    945  return NS_OK;
    946 }
    947 
    948 NS_IMETHODIMP
    949 nsViewSourceChannel::GetOriginalResponseHeader(const nsACString& aHeader,
    950                                               nsIHttpHeaderVisitor* aVisitor) {
    951  nsAutoCString value;
    952  nsresult rv = GetResponseHeader(aHeader, value);
    953  if (NS_FAILED(rv)) {
    954    return rv;
    955  }
    956  return aVisitor->VisitHeader(aHeader, value);
    957 }
    958 
    959 NS_IMETHODIMP
    960 nsViewSourceChannel::VisitOriginalResponseHeaders(
    961    nsIHttpHeaderVisitor* aVisitor) {
    962  return VisitResponseHeaders(aVisitor);
    963 }
    964 
    965 NS_IMETHODIMP
    966 nsViewSourceChannel::IsNoStoreResponse(bool* _retval) {
    967  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    968                       : mHttpChannel->IsNoStoreResponse(_retval);
    969 }
    970 
    971 NS_IMETHODIMP
    972 nsViewSourceChannel::IsNoCacheResponse(bool* _retval) {
    973  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    974                       : mHttpChannel->IsNoCacheResponse(_retval);
    975 }
    976 
    977 NS_IMETHODIMP
    978 nsViewSourceChannel::RedirectTo(nsIURI* uri) {
    979  return !mHttpChannel ? NS_ERROR_NULL_POINTER : mHttpChannel->RedirectTo(uri);
    980 }
    981 
    982 NS_IMETHODIMP
    983 nsViewSourceChannel::UpgradeToSecure() {
    984  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    985                       : mHttpChannel->UpgradeToSecure();
    986 }
    987 
    988 NS_IMETHODIMP
    989 nsViewSourceChannel::GetRequestObserversCalled(bool* aCalled) {
    990  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    991                       : mHttpChannel->GetRequestObserversCalled(aCalled);
    992 }
    993 
    994 NS_IMETHODIMP
    995 nsViewSourceChannel::SetRequestObserversCalled(bool aCalled) {
    996  return !mHttpChannel ? NS_ERROR_NULL_POINTER
    997                       : mHttpChannel->SetRequestObserversCalled(aCalled);
    998 }
    999 
   1000 NS_IMETHODIMP
   1001 nsViewSourceChannel::GetRequestContextID(uint64_t* _retval) {
   1002  return !mHttpChannel ? NS_ERROR_NULL_POINTER
   1003                       : mHttpChannel->GetRequestContextID(_retval);
   1004 }
   1005 
   1006 NS_IMETHODIMP
   1007 nsViewSourceChannel::SetRequestContextID(uint64_t rcid) {
   1008  return !mHttpChannel ? NS_ERROR_NULL_POINTER
   1009                       : mHttpChannel->SetRequestContextID(rcid);
   1010 }
   1011 
   1012 NS_IMETHODIMP
   1013 nsViewSourceChannel::GetIsUserAgentHeaderOutdated(bool* aValue) {
   1014  return !mHttpChannel ? NS_ERROR_NULL_POINTER
   1015                       : mHttpChannel->GetIsUserAgentHeaderOutdated(aValue);
   1016 }
   1017 
   1018 NS_IMETHODIMP
   1019 nsViewSourceChannel::SetIsUserAgentHeaderOutdated(bool aValue) {
   1020  return !mHttpChannel ? NS_ERROR_NULL_POINTER
   1021                       : mHttpChannel->SetIsUserAgentHeaderOutdated(aValue);
   1022 }
   1023 
   1024 NS_IMETHODIMP
   1025 nsViewSourceChannel::GetIsMainDocumentChannel(bool* aValue) {
   1026  return !mHttpChannel ? NS_ERROR_NULL_POINTER
   1027                       : mHttpChannel->GetIsMainDocumentChannel(aValue);
   1028 }
   1029 
   1030 NS_IMETHODIMP
   1031 nsViewSourceChannel::SetIsMainDocumentChannel(bool aValue) {
   1032  return !mHttpChannel ? NS_ERROR_NULL_POINTER
   1033                       : mHttpChannel->SetIsMainDocumentChannel(aValue);
   1034 }
   1035 
   1036 NS_IMETHODIMP nsViewSourceChannel::SetClassicScriptHintCharset(
   1037    const nsAString& aClassicScriptHintCharset) {
   1038  return !mHttpChannel ? NS_ERROR_NULL_POINTER
   1039                       : mHttpChannel->SetClassicScriptHintCharset(
   1040                             aClassicScriptHintCharset);
   1041 }
   1042 
   1043 NS_IMETHODIMP nsViewSourceChannel::GetClassicScriptHintCharset(
   1044    nsAString& aClassicScriptHintCharset) {
   1045  return !mHttpChannel ? NS_ERROR_NULL_POINTER
   1046                       : mHttpChannel->GetClassicScriptHintCharset(
   1047                             aClassicScriptHintCharset);
   1048 }
   1049 
   1050 NS_IMETHODIMP nsViewSourceChannel::SetDocumentCharacterSet(
   1051    const nsAString& aDocumentCharacterSet) {
   1052  return !mHttpChannel
   1053             ? NS_ERROR_NULL_POINTER
   1054             : mHttpChannel->SetDocumentCharacterSet(aDocumentCharacterSet);
   1055 }
   1056 
   1057 NS_IMETHODIMP nsViewSourceChannel::GetDocumentCharacterSet(
   1058    nsAString& aDocumentCharacterSet) {
   1059  return !mHttpChannel
   1060             ? NS_ERROR_NULL_POINTER
   1061             : mHttpChannel->GetDocumentCharacterSet(aDocumentCharacterSet);
   1062 }
   1063 // Have to manually forward SetCorsPreflightParameters since it's [notxpcom]
   1064 void nsViewSourceChannel::SetCorsPreflightParameters(
   1065    const nsTArray<nsCString>& aUnsafeHeaders,
   1066    bool aShouldStripRequestBodyHeader, bool aShouldStripAuthHeader) {
   1067  mHttpChannelInternal->SetCorsPreflightParameters(
   1068      aUnsafeHeaders, aShouldStripRequestBodyHeader, aShouldStripAuthHeader);
   1069 }
   1070 
   1071 void nsViewSourceChannel::SetAltDataForChild(bool aIsForChild) {
   1072  mHttpChannelInternal->SetAltDataForChild(aIsForChild);
   1073 }
   1074 
   1075 void nsViewSourceChannel::DisableAltDataCache() {
   1076  mHttpChannelInternal->DisableAltDataCache();
   1077 }
   1078 
   1079 NS_IMETHODIMP
   1080 nsViewSourceChannel::LogBlockedCORSRequest(const nsAString& aMessage,
   1081                                           const nsACString& aCategory,
   1082                                           bool aIsWarning) {
   1083  if (!mHttpChannel) {
   1084    NS_WARNING(
   1085        "nsViewSourceChannel::LogBlockedCORSRequest mHttpChannel is null");
   1086    return NS_ERROR_UNEXPECTED;
   1087  }
   1088  return mHttpChannel->LogBlockedCORSRequest(aMessage, aCategory, aIsWarning);
   1089 }
   1090 
   1091 NS_IMETHODIMP
   1092 nsViewSourceChannel::LogMimeTypeMismatch(const nsACString& aMessageName,
   1093                                         bool aWarning, const nsAString& aURL,
   1094                                         const nsAString& aContentType) {
   1095  if (!mHttpChannel) {
   1096    NS_WARNING("nsViewSourceChannel::LogMimeTypeMismatch mHttpChannel is null");
   1097    return NS_ERROR_UNEXPECTED;
   1098  }
   1099  return mHttpChannel->LogMimeTypeMismatch(aMessageName, aWarning, aURL,
   1100                                           aContentType);
   1101 }
   1102 
   1103 // FIXME: Should this forward to mHttpChannel? This was previously handled by a
   1104 // default empty implementation.
   1105 void nsViewSourceChannel::SetSource(
   1106    mozilla::UniquePtr<mozilla::ProfileChunkedBuffer> aSource) {}
   1107 
   1108 const nsTArray<mozilla::net::PreferredAlternativeDataTypeParams>&
   1109 nsViewSourceChannel::PreferredAlternativeDataTypes() {
   1110  if (mCacheInfoChannel) {
   1111    return mCacheInfoChannel->PreferredAlternativeDataTypes();
   1112  }
   1113  return mEmptyArray;
   1114 }
   1115 
   1116 void nsViewSourceChannel::DoDiagnosticAssertWhenOnStopNotCalledOnDestroy() {
   1117  if (mHttpChannelInternal) {
   1118    mHttpChannelInternal->DoDiagnosticAssertWhenOnStopNotCalledOnDestroy();
   1119  }
   1120 }
   1121 
   1122 // FIXME: Should this forward to mHttpChannelInternal? This was previously
   1123 // handled by a default empty implementation.
   1124 void nsViewSourceChannel::SetConnectionInfo(
   1125    mozilla::net::nsHttpConnectionInfo* aInfo) {}
   1126 
   1127 // nsIChildChannel methods
   1128 
   1129 NS_IMETHODIMP
   1130 nsViewSourceChannel::ConnectParent(uint32_t aRegistarId) {
   1131  NS_ENSURE_TRUE(mChildChannel, NS_ERROR_NULL_POINTER);
   1132 
   1133  return mChildChannel->ConnectParent(aRegistarId);
   1134 }
   1135 
   1136 NS_IMETHODIMP
   1137 nsViewSourceChannel::CompleteRedirectSetup(nsIStreamListener* aListener) {
   1138  NS_ENSURE_TRUE(mChildChannel, NS_ERROR_NULL_POINTER);
   1139 
   1140  mListener = aListener;
   1141 
   1142  /*
   1143   * We want to add ourselves to the loadgroup before opening
   1144   * mChannel, since we want to make sure we're in the loadgroup
   1145   * when mChannel finishes and fires OnStopRequest()
   1146   */
   1147 
   1148  nsCOMPtr<nsILoadGroup> loadGroup;
   1149  mChannel->GetLoadGroup(getter_AddRefs(loadGroup));
   1150  if (loadGroup) {
   1151    loadGroup->AddRequest(static_cast<nsIViewSourceChannel*>(this), nullptr);
   1152  }
   1153 
   1154  nsresult rv = NS_OK;
   1155  rv = mChildChannel->CompleteRedirectSetup(this);
   1156 
   1157  if (NS_FAILED(rv) && loadGroup) {
   1158    loadGroup->RemoveRequest(static_cast<nsIViewSourceChannel*>(this), nullptr,
   1159                             rv);
   1160  }
   1161 
   1162  if (NS_SUCCEEDED(rv)) {
   1163    mOpened = true;
   1164  }
   1165 
   1166  return rv;
   1167 }
   1168 
   1169 // nsIChannelEventSink
   1170 
   1171 NS_IMETHODIMP
   1172 nsViewSourceChannel::AsyncOnChannelRedirect(
   1173    nsIChannel* oldChannel, nsIChannel* newChannel, uint32_t flags,
   1174    nsIAsyncVerifyRedirectCallback* callback) {
   1175  nsresult rv;
   1176 
   1177  // We want consumers of the new inner channel be able to recognize it's
   1178  // actually used for view-source.  Hence we modify its original URI here.
   1179  // This will not affect security checks because those have already been
   1180  // synchronously done before our event sink is called.  Note that result
   1181  // principal URI is still modified at the OnStartRequest notification.
   1182  nsCOMPtr<nsIURI> newChannelOrigURI;
   1183  rv = newChannel->GetOriginalURI(getter_AddRefs(newChannelOrigURI));
   1184  NS_ENSURE_SUCCESS(rv, rv);
   1185 
   1186  nsAutoCString scheme;
   1187  rv = newChannelOrigURI->GetScheme(scheme);
   1188  if (NS_FAILED(rv)) {
   1189    return rv;
   1190  }
   1191 
   1192  nsCOMPtr<nsIIOService> ioService(do_GetIOService(&rv));
   1193  if (NS_FAILED(rv)) {
   1194    return rv;
   1195  }
   1196 
   1197  rv = WillUseExternalProtocolHandler(ioService, scheme.get());
   1198  if (NS_FAILED(rv)) {
   1199    return rv;
   1200  }
   1201 
   1202  nsCOMPtr<nsIURI> newChannelUpdatedOrigURI;
   1203  rv = BuildViewSourceURI(newChannelOrigURI,
   1204                          getter_AddRefs(newChannelUpdatedOrigURI));
   1205  NS_ENSURE_SUCCESS(rv, rv);
   1206 
   1207  rv = newChannel->SetOriginalURI(newChannelUpdatedOrigURI);
   1208  NS_ENSURE_SUCCESS(rv, rv);
   1209 
   1210  nsCOMPtr<nsIChannelEventSink> sink(do_QueryInterface(mCallbacks));
   1211  if (sink) {
   1212    return sink->AsyncOnChannelRedirect(oldChannel, newChannel, flags,
   1213                                        callback);
   1214  }
   1215 
   1216  callback->OnRedirectVerifyCallback(NS_OK);
   1217  return NS_OK;
   1218 }
   1219 
   1220 NS_IMETHODIMP
   1221 nsViewSourceChannel::GetDecompressDictionary(
   1222    mozilla::net::DictionaryCacheEntry** aDictionary) {
   1223  *aDictionary = nullptr;
   1224  return NS_OK;
   1225 }
   1226 
   1227 NS_IMETHODIMP
   1228 nsViewSourceChannel::SetDecompressDictionary(
   1229    mozilla::net::DictionaryCacheEntry* aDictionary) {
   1230  return NS_OK;
   1231 }
   1232 
   1233 // nsIInterfaceRequestor
   1234 
   1235 NS_IMETHODIMP
   1236 nsViewSourceChannel::GetInterface(const nsIID& aIID, void** aResult) {
   1237  if (aIID.Equals(NS_GET_IID(nsIChannelEventSink))) {
   1238    nsCOMPtr<nsIChannelEventSink> self(this);
   1239    self.forget(aResult);
   1240    return NS_OK;
   1241  }
   1242 
   1243  if (mCallbacks) {
   1244    return mCallbacks->GetInterface(aIID, aResult);
   1245  }
   1246 
   1247  return NS_ERROR_NO_INTERFACE;
   1248 }