netwerk/protocol/viewsource/nsViewSourceChannel.cpp

Thu, 15 Jan 2015 15:55:04 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 15:55:04 +0100
branch
TOR_BUG_9701
changeset 9
a63d609f5ebe
permissions
-rw-r--r--

Back out 97036ab72558 which inappropriately compared turds to third parties.

michael@0 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
michael@0 2 /* vim:set ts=4 sw=4 sts=4 et: */
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 #include "nsViewSourceChannel.h"
michael@0 8 #include "nsIIOService.h"
michael@0 9 #include "nsMimeTypes.h"
michael@0 10 #include "nsNetUtil.h"
michael@0 11 #include "nsIHttpHeaderVisitor.h"
michael@0 12
michael@0 13 NS_IMPL_ADDREF(nsViewSourceChannel)
michael@0 14 NS_IMPL_RELEASE(nsViewSourceChannel)
michael@0 15 /*
michael@0 16 This QI uses NS_INTERFACE_MAP_ENTRY_CONDITIONAL to check for
michael@0 17 non-nullness of mHttpChannel, mCachingChannel, and mUploadChannel.
michael@0 18 */
michael@0 19 NS_INTERFACE_MAP_BEGIN(nsViewSourceChannel)
michael@0 20 NS_INTERFACE_MAP_ENTRY(nsIViewSourceChannel)
michael@0 21 NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
michael@0 22 NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
michael@0 23 NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannel, mHttpChannel)
michael@0 24 NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannelInternal, mHttpChannelInternal)
michael@0 25 NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsICachingChannel, mCachingChannel)
michael@0 26 NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIApplicationCacheChannel, mApplicationCacheChannel)
michael@0 27 NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIUploadChannel, mUploadChannel)
michael@0 28 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIRequest, nsIViewSourceChannel)
michael@0 29 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIChannel, nsIViewSourceChannel)
michael@0 30 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIViewSourceChannel)
michael@0 31 NS_INTERFACE_MAP_END
michael@0 32
michael@0 33 nsresult
michael@0 34 nsViewSourceChannel::Init(nsIURI* uri)
michael@0 35 {
michael@0 36 mOriginalURI = uri;
michael@0 37
michael@0 38 nsAutoCString path;
michael@0 39 nsresult rv = uri->GetPath(path);
michael@0 40 if (NS_FAILED(rv))
michael@0 41 return rv;
michael@0 42
michael@0 43 nsCOMPtr<nsIIOService> pService(do_GetIOService(&rv));
michael@0 44 if (NS_FAILED(rv)) return rv;
michael@0 45
michael@0 46 nsAutoCString scheme;
michael@0 47 rv = pService->ExtractScheme(path, scheme);
michael@0 48 if (NS_FAILED(rv))
michael@0 49 return rv;
michael@0 50
michael@0 51 // prevent viewing source of javascript URIs (see bug 204779)
michael@0 52 if (scheme.LowerCaseEqualsLiteral("javascript")) {
michael@0 53 NS_WARNING("blocking view-source:javascript:");
michael@0 54 return NS_ERROR_INVALID_ARG;
michael@0 55 }
michael@0 56
michael@0 57 rv = pService->NewChannel(path, nullptr, nullptr, getter_AddRefs(mChannel));
michael@0 58 if (NS_FAILED(rv))
michael@0 59 return rv;
michael@0 60
michael@0 61 mIsSrcdocChannel = false;
michael@0 62
michael@0 63 mChannel->SetOriginalURI(mOriginalURI);
michael@0 64 mHttpChannel = do_QueryInterface(mChannel);
michael@0 65 mHttpChannelInternal = do_QueryInterface(mChannel);
michael@0 66 mCachingChannel = do_QueryInterface(mChannel);
michael@0 67 mApplicationCacheChannel = do_QueryInterface(mChannel);
michael@0 68 mUploadChannel = do_QueryInterface(mChannel);
michael@0 69
michael@0 70 return NS_OK;
michael@0 71 }
michael@0 72
michael@0 73 nsresult
michael@0 74 nsViewSourceChannel::InitSrcdoc(nsIURI* aURI, const nsAString &aSrcdoc,
michael@0 75 nsIURI* aBaseURI)
michael@0 76 {
michael@0 77
michael@0 78 nsresult rv;
michael@0 79
michael@0 80 nsCOMPtr<nsIURI> inStreamURI;
michael@0 81 // Need to strip view-source: from the URI. Hardcoded to
michael@0 82 // about:srcdoc as this is the only permissible URI for srcdoc
michael@0 83 // loads
michael@0 84 rv = NS_NewURI(getter_AddRefs(inStreamURI),
michael@0 85 NS_LITERAL_STRING("about:srcdoc"));
michael@0 86 NS_ENSURE_SUCCESS(rv, rv);
michael@0 87
michael@0 88 rv = NS_NewInputStreamChannel(getter_AddRefs(mChannel), inStreamURI,
michael@0 89 aSrcdoc, NS_LITERAL_CSTRING("text/html"),
michael@0 90 true);
michael@0 91
michael@0 92 NS_ENSURE_SUCCESS(rv, rv);
michael@0 93 mOriginalURI = aURI;
michael@0 94 mIsSrcdocChannel = true;
michael@0 95 nsCOMPtr<nsIInputStreamChannel> isc = do_QueryInterface(mChannel);
michael@0 96 MOZ_ASSERT(isc);
michael@0 97 isc->SetBaseURI(aBaseURI);
michael@0 98
michael@0 99 mChannel->SetOriginalURI(mOriginalURI);
michael@0 100 mHttpChannel = do_QueryInterface(mChannel);
michael@0 101 mHttpChannelInternal = do_QueryInterface(mChannel);
michael@0 102 mCachingChannel = do_QueryInterface(mChannel);
michael@0 103 mApplicationCacheChannel = do_QueryInterface(mChannel);
michael@0 104 mUploadChannel = do_QueryInterface(mChannel);
michael@0 105 return NS_OK;
michael@0 106 }
michael@0 107
michael@0 108 ////////////////////////////////////////////////////////////////////////////////
michael@0 109 // nsIRequest methods:
michael@0 110
michael@0 111 NS_IMETHODIMP
michael@0 112 nsViewSourceChannel::GetName(nsACString &result)
michael@0 113 {
michael@0 114 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 115 }
michael@0 116
michael@0 117 NS_IMETHODIMP
michael@0 118 nsViewSourceChannel::GetProxyURI(nsIURI** proxyURI)
michael@0 119 {
michael@0 120 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 121 }
michael@0 122
michael@0 123 NS_IMETHODIMP
michael@0 124 nsViewSourceChannel::IsPending(bool *result)
michael@0 125 {
michael@0 126 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 127
michael@0 128 return mChannel->IsPending(result);
michael@0 129 }
michael@0 130
michael@0 131 NS_IMETHODIMP
michael@0 132 nsViewSourceChannel::GetStatus(nsresult *status)
michael@0 133 {
michael@0 134 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 135
michael@0 136 return mChannel->GetStatus(status);
michael@0 137 }
michael@0 138
michael@0 139 NS_IMETHODIMP
michael@0 140 nsViewSourceChannel::Cancel(nsresult status)
michael@0 141 {
michael@0 142 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 143
michael@0 144 return mChannel->Cancel(status);
michael@0 145 }
michael@0 146
michael@0 147 NS_IMETHODIMP
michael@0 148 nsViewSourceChannel::Suspend(void)
michael@0 149 {
michael@0 150 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 151
michael@0 152 return mChannel->Suspend();
michael@0 153 }
michael@0 154
michael@0 155 NS_IMETHODIMP
michael@0 156 nsViewSourceChannel::Resume(void)
michael@0 157 {
michael@0 158 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 159
michael@0 160 return mChannel->Resume();
michael@0 161 }
michael@0 162
michael@0 163 ////////////////////////////////////////////////////////////////////////////////
michael@0 164 // nsIChannel methods:
michael@0 165
michael@0 166 NS_IMETHODIMP
michael@0 167 nsViewSourceChannel::GetOriginalURI(nsIURI* *aURI)
michael@0 168 {
michael@0 169 NS_ASSERTION(aURI, "Null out param!");
michael@0 170 *aURI = mOriginalURI;
michael@0 171 NS_ADDREF(*aURI);
michael@0 172 return NS_OK;
michael@0 173 }
michael@0 174
michael@0 175 NS_IMETHODIMP
michael@0 176 nsViewSourceChannel::SetOriginalURI(nsIURI* aURI)
michael@0 177 {
michael@0 178 NS_ENSURE_ARG_POINTER(aURI);
michael@0 179 mOriginalURI = aURI;
michael@0 180 return NS_OK;
michael@0 181 }
michael@0 182
michael@0 183 NS_IMETHODIMP
michael@0 184 nsViewSourceChannel::GetURI(nsIURI* *aURI)
michael@0 185 {
michael@0 186 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 187
michael@0 188 nsCOMPtr<nsIURI> uri;
michael@0 189 nsresult rv = mChannel->GetURI(getter_AddRefs(uri));
michael@0 190 if (NS_FAILED(rv))
michael@0 191 return rv;
michael@0 192
michael@0 193 // protect ourselves against broken channel implementations
michael@0 194 if (!uri) {
michael@0 195 NS_ERROR("inner channel returned NS_OK and a null URI");
michael@0 196 return NS_ERROR_UNEXPECTED;
michael@0 197 }
michael@0 198
michael@0 199 nsAutoCString spec;
michael@0 200 uri->GetSpec(spec);
michael@0 201
michael@0 202 /* XXX Gross hack -- NS_NewURI goes into an infinite loop on
michael@0 203 non-flat specs. See bug 136980 */
michael@0 204 return NS_NewURI(aURI, nsAutoCString(NS_LITERAL_CSTRING("view-source:")+spec), nullptr);
michael@0 205 }
michael@0 206
michael@0 207 NS_IMETHODIMP
michael@0 208 nsViewSourceChannel::Open(nsIInputStream **_retval)
michael@0 209 {
michael@0 210 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 211
michael@0 212 nsresult rv = mChannel->Open(_retval);
michael@0 213 if (NS_SUCCEEDED(rv)) {
michael@0 214 mOpened = true;
michael@0 215 }
michael@0 216
michael@0 217 return rv;
michael@0 218 }
michael@0 219
michael@0 220 NS_IMETHODIMP
michael@0 221 nsViewSourceChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
michael@0 222 {
michael@0 223 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 224
michael@0 225 mListener = aListener;
michael@0 226
michael@0 227 /*
michael@0 228 * We want to add ourselves to the loadgroup before opening
michael@0 229 * mChannel, since we want to make sure we're in the loadgroup
michael@0 230 * when mChannel finishes and fires OnStopRequest()
michael@0 231 */
michael@0 232
michael@0 233 nsCOMPtr<nsILoadGroup> loadGroup;
michael@0 234 mChannel->GetLoadGroup(getter_AddRefs(loadGroup));
michael@0 235 if (loadGroup)
michael@0 236 loadGroup->AddRequest(static_cast<nsIViewSourceChannel*>
michael@0 237 (this), nullptr);
michael@0 238
michael@0 239 nsresult rv = mChannel->AsyncOpen(this, ctxt);
michael@0 240
michael@0 241 if (NS_FAILED(rv) && loadGroup)
michael@0 242 loadGroup->RemoveRequest(static_cast<nsIViewSourceChannel*>
michael@0 243 (this),
michael@0 244 nullptr, rv);
michael@0 245
michael@0 246 if (NS_SUCCEEDED(rv)) {
michael@0 247 mOpened = true;
michael@0 248 }
michael@0 249
michael@0 250 return rv;
michael@0 251 }
michael@0 252
michael@0 253 /*
michael@0 254 * Both the view source channel and mChannel are added to the
michael@0 255 * loadgroup. There should never be more than one request in the
michael@0 256 * loadgroup that has LOAD_DOCUMENT_URI set. The one that has this
michael@0 257 * flag set is the request whose URI is used to refetch the document,
michael@0 258 * so it better be the viewsource channel.
michael@0 259 *
michael@0 260 * Therefore, we need to make sure that
michael@0 261 * 1) The load flags on mChannel _never_ include LOAD_DOCUMENT_URI
michael@0 262 * 2) The load flags on |this| include LOAD_DOCUMENT_URI when it was
michael@0 263 * set via SetLoadFlags (mIsDocument keeps track of this flag).
michael@0 264 */
michael@0 265
michael@0 266 NS_IMETHODIMP
michael@0 267 nsViewSourceChannel::GetLoadFlags(uint32_t *aLoadFlags)
michael@0 268 {
michael@0 269 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 270
michael@0 271 nsresult rv = mChannel->GetLoadFlags(aLoadFlags);
michael@0 272 if (NS_FAILED(rv))
michael@0 273 return rv;
michael@0 274
michael@0 275 // This should actually be just LOAD_DOCUMENT_URI but the win32 compiler
michael@0 276 // fails to deal due to amiguous inheritance. nsIChannel::LOAD_DOCUMENT_URI
michael@0 277 // also fails; the Win32 compiler thinks that's supposed to be a method.
michael@0 278 if (mIsDocument)
michael@0 279 *aLoadFlags |= ::nsIChannel::LOAD_DOCUMENT_URI;
michael@0 280
michael@0 281 return rv;
michael@0 282 }
michael@0 283
michael@0 284 NS_IMETHODIMP
michael@0 285 nsViewSourceChannel::SetLoadFlags(uint32_t aLoadFlags)
michael@0 286 {
michael@0 287 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 288
michael@0 289 // "View source" always wants the currently cached content.
michael@0 290 // We also want to have _this_ channel, not mChannel to be the
michael@0 291 // 'document' channel in the loadgroup.
michael@0 292
michael@0 293 // These should actually be just LOAD_FROM_CACHE and LOAD_DOCUMENT_URI but
michael@0 294 // the win32 compiler fails to deal due to amiguous inheritance.
michael@0 295 // nsIChannel::LOAD_DOCUMENT_URI/nsIRequest::LOAD_FROM_CACHE also fails; the
michael@0 296 // Win32 compiler thinks that's supposed to be a method.
michael@0 297 mIsDocument = (aLoadFlags & ::nsIChannel::LOAD_DOCUMENT_URI) ? true : false;
michael@0 298
michael@0 299 return mChannel->SetLoadFlags((aLoadFlags |
michael@0 300 ::nsIRequest::LOAD_FROM_CACHE) &
michael@0 301 ~::nsIChannel::LOAD_DOCUMENT_URI);
michael@0 302 }
michael@0 303
michael@0 304 NS_IMETHODIMP
michael@0 305 nsViewSourceChannel::GetContentType(nsACString &aContentType)
michael@0 306 {
michael@0 307 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 308
michael@0 309 aContentType.Truncate();
michael@0 310
michael@0 311 if (mContentType.IsEmpty())
michael@0 312 {
michael@0 313 // Get the current content type
michael@0 314 nsresult rv;
michael@0 315 nsAutoCString contentType;
michael@0 316 rv = mChannel->GetContentType(contentType);
michael@0 317 if (NS_FAILED(rv)) return rv;
michael@0 318
michael@0 319 // If we don't know our type, just say so. The unknown
michael@0 320 // content decoder will then kick in automatically, and it
michael@0 321 // will call our SetOriginalContentType method instead of our
michael@0 322 // SetContentType method to set the type it determines.
michael@0 323 if (!contentType.Equals(UNKNOWN_CONTENT_TYPE)) {
michael@0 324 contentType = VIEWSOURCE_CONTENT_TYPE;
michael@0 325 }
michael@0 326
michael@0 327 mContentType = contentType;
michael@0 328 }
michael@0 329
michael@0 330 aContentType = mContentType;
michael@0 331 return NS_OK;
michael@0 332 }
michael@0 333
michael@0 334 NS_IMETHODIMP
michael@0 335 nsViewSourceChannel::SetContentType(const nsACString &aContentType)
michael@0 336 {
michael@0 337 // Our GetContentType() currently returns VIEWSOURCE_CONTENT_TYPE
michael@0 338 //
michael@0 339 // However, during the parsing phase the parser calls our
michael@0 340 // channel's GetContentType(). Returning the string above trips up
michael@0 341 // the parser. In order to avoid messy changes and not to have the
michael@0 342 // parser depend on nsIViewSourceChannel Vidur proposed the
michael@0 343 // following solution:
michael@0 344 //
michael@0 345 // The ViewSourceChannel initially returns a content type of
michael@0 346 // VIEWSOURCE_CONTENT_TYPE. Based on this type decisions to
michael@0 347 // create a viewer for doing a view source are made. After the
michael@0 348 // viewer is created, nsLayoutDLF::CreateInstance() calls this
michael@0 349 // SetContentType() with the original content type. When it's
michael@0 350 // time for the parser to find out the content type it will call
michael@0 351 // our channel's GetContentType() and it will get the original
michael@0 352 // content type, such as, text/html and everything is kosher from
michael@0 353 // then on.
michael@0 354
michael@0 355 if (!mOpened) {
michael@0 356 // We do not take hints
michael@0 357 return NS_ERROR_NOT_AVAILABLE;
michael@0 358 }
michael@0 359
michael@0 360 mContentType = aContentType;
michael@0 361 return NS_OK;
michael@0 362 }
michael@0 363
michael@0 364 NS_IMETHODIMP
michael@0 365 nsViewSourceChannel::GetContentCharset(nsACString &aContentCharset)
michael@0 366 {
michael@0 367 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 368
michael@0 369 return mChannel->GetContentCharset(aContentCharset);
michael@0 370 }
michael@0 371
michael@0 372 NS_IMETHODIMP
michael@0 373 nsViewSourceChannel::SetContentCharset(const nsACString &aContentCharset)
michael@0 374 {
michael@0 375 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 376
michael@0 377 return mChannel->SetContentCharset(aContentCharset);
michael@0 378 }
michael@0 379
michael@0 380 // We don't forward these methods becacuse content-disposition isn't whitelisted
michael@0 381 // (see GetResponseHeader/VisitResponseHeaders).
michael@0 382 NS_IMETHODIMP
michael@0 383 nsViewSourceChannel::GetContentDisposition(uint32_t *aContentDisposition)
michael@0 384 {
michael@0 385 return NS_ERROR_NOT_AVAILABLE;
michael@0 386 }
michael@0 387
michael@0 388 NS_IMETHODIMP
michael@0 389 nsViewSourceChannel::SetContentDisposition(uint32_t aContentDisposition)
michael@0 390 {
michael@0 391 return NS_ERROR_NOT_AVAILABLE;
michael@0 392 }
michael@0 393
michael@0 394 NS_IMETHODIMP
michael@0 395 nsViewSourceChannel::GetContentDispositionFilename(nsAString &aContentDispositionFilename)
michael@0 396 {
michael@0 397 return NS_ERROR_NOT_AVAILABLE;
michael@0 398 }
michael@0 399
michael@0 400 NS_IMETHODIMP
michael@0 401 nsViewSourceChannel::SetContentDispositionFilename(const nsAString &aContentDispositionFilename)
michael@0 402 {
michael@0 403 return NS_ERROR_NOT_AVAILABLE;
michael@0 404 }
michael@0 405
michael@0 406 NS_IMETHODIMP
michael@0 407 nsViewSourceChannel::GetContentDispositionHeader(nsACString &aContentDispositionHeader)
michael@0 408 {
michael@0 409 return NS_ERROR_NOT_AVAILABLE;
michael@0 410 }
michael@0 411
michael@0 412 NS_IMETHODIMP
michael@0 413 nsViewSourceChannel::GetContentLength(int64_t *aContentLength)
michael@0 414 {
michael@0 415 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 416
michael@0 417 return mChannel->GetContentLength(aContentLength);
michael@0 418 }
michael@0 419
michael@0 420 NS_IMETHODIMP
michael@0 421 nsViewSourceChannel::SetContentLength(int64_t aContentLength)
michael@0 422 {
michael@0 423 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 424
michael@0 425 return mChannel->SetContentLength(aContentLength);
michael@0 426 }
michael@0 427
michael@0 428 NS_IMETHODIMP
michael@0 429 nsViewSourceChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
michael@0 430 {
michael@0 431 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 432
michael@0 433 return mChannel->GetLoadGroup(aLoadGroup);
michael@0 434 }
michael@0 435
michael@0 436 NS_IMETHODIMP
michael@0 437 nsViewSourceChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
michael@0 438 {
michael@0 439 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 440
michael@0 441 return mChannel->SetLoadGroup(aLoadGroup);
michael@0 442 }
michael@0 443
michael@0 444 NS_IMETHODIMP
michael@0 445 nsViewSourceChannel::GetOwner(nsISupports* *aOwner)
michael@0 446 {
michael@0 447 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 448
michael@0 449 return mChannel->GetOwner(aOwner);
michael@0 450 }
michael@0 451
michael@0 452 NS_IMETHODIMP
michael@0 453 nsViewSourceChannel::SetOwner(nsISupports* aOwner)
michael@0 454 {
michael@0 455 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 456
michael@0 457 return mChannel->SetOwner(aOwner);
michael@0 458 }
michael@0 459
michael@0 460 NS_IMETHODIMP
michael@0 461 nsViewSourceChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
michael@0 462 {
michael@0 463 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 464
michael@0 465 return mChannel->GetNotificationCallbacks(aNotificationCallbacks);
michael@0 466 }
michael@0 467
michael@0 468 NS_IMETHODIMP
michael@0 469 nsViewSourceChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
michael@0 470 {
michael@0 471 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 472
michael@0 473 return mChannel->SetNotificationCallbacks(aNotificationCallbacks);
michael@0 474 }
michael@0 475
michael@0 476 NS_IMETHODIMP
michael@0 477 nsViewSourceChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
michael@0 478 {
michael@0 479 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 480
michael@0 481 return mChannel->GetSecurityInfo(aSecurityInfo);
michael@0 482 }
michael@0 483
michael@0 484 // nsIViewSourceChannel methods
michael@0 485 NS_IMETHODIMP
michael@0 486 nsViewSourceChannel::GetOriginalContentType(nsACString &aContentType)
michael@0 487 {
michael@0 488 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 489
michael@0 490 return mChannel->GetContentType(aContentType);
michael@0 491 }
michael@0 492
michael@0 493 NS_IMETHODIMP
michael@0 494 nsViewSourceChannel::SetOriginalContentType(const nsACString &aContentType)
michael@0 495 {
michael@0 496 NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
michael@0 497
michael@0 498 // clear our cached content-type value
michael@0 499 mContentType.Truncate();
michael@0 500
michael@0 501 return mChannel->SetContentType(aContentType);
michael@0 502 }
michael@0 503
michael@0 504 NS_IMETHODIMP
michael@0 505 nsViewSourceChannel::GetIsSrcdocChannel(bool* aIsSrcdocChannel)
michael@0 506 {
michael@0 507 *aIsSrcdocChannel = mIsSrcdocChannel;
michael@0 508 return NS_OK;
michael@0 509 }
michael@0 510
michael@0 511 NS_IMETHODIMP
michael@0 512 nsViewSourceChannel::GetBaseURI(nsIURI** aBaseURI)
michael@0 513 {
michael@0 514 if (mIsSrcdocChannel) {
michael@0 515 nsCOMPtr<nsIInputStreamChannel> isc = do_QueryInterface(mChannel);
michael@0 516 if (isc) {
michael@0 517 return isc->GetBaseURI(aBaseURI);
michael@0 518 }
michael@0 519 }
michael@0 520 *aBaseURI = mBaseURI;
michael@0 521 NS_IF_ADDREF(*aBaseURI);
michael@0 522 return NS_OK;
michael@0 523 }
michael@0 524
michael@0 525 NS_IMETHODIMP
michael@0 526 nsViewSourceChannel::SetBaseURI(nsIURI* aBaseURI)
michael@0 527 {
michael@0 528 mBaseURI = aBaseURI;
michael@0 529 return NS_OK;
michael@0 530 }
michael@0 531
michael@0 532 // nsIRequestObserver methods
michael@0 533 NS_IMETHODIMP
michael@0 534 nsViewSourceChannel::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
michael@0 535 {
michael@0 536 NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
michael@0 537 // The channel may have gotten redirected... Time to update our info
michael@0 538 mChannel = do_QueryInterface(aRequest);
michael@0 539 mHttpChannel = do_QueryInterface(aRequest);
michael@0 540 mCachingChannel = do_QueryInterface(aRequest);
michael@0 541 mUploadChannel = do_QueryInterface(aRequest);
michael@0 542
michael@0 543 return mListener->OnStartRequest(static_cast<nsIViewSourceChannel*>
michael@0 544 (this),
michael@0 545 aContext);
michael@0 546 }
michael@0 547
michael@0 548
michael@0 549 NS_IMETHODIMP
michael@0 550 nsViewSourceChannel::OnStopRequest(nsIRequest *aRequest, nsISupports* aContext,
michael@0 551 nsresult aStatus)
michael@0 552 {
michael@0 553 NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
michael@0 554 if (mChannel)
michael@0 555 {
michael@0 556 nsCOMPtr<nsILoadGroup> loadGroup;
michael@0 557 mChannel->GetLoadGroup(getter_AddRefs(loadGroup));
michael@0 558 if (loadGroup)
michael@0 559 {
michael@0 560 loadGroup->RemoveRequest(static_cast<nsIViewSourceChannel*>
michael@0 561 (this),
michael@0 562 nullptr, aStatus);
michael@0 563 }
michael@0 564 }
michael@0 565 return mListener->OnStopRequest(static_cast<nsIViewSourceChannel*>
michael@0 566 (this),
michael@0 567 aContext, aStatus);
michael@0 568 }
michael@0 569
michael@0 570
michael@0 571 // nsIStreamListener methods
michael@0 572 NS_IMETHODIMP
michael@0 573 nsViewSourceChannel::OnDataAvailable(nsIRequest *aRequest, nsISupports* aContext,
michael@0 574 nsIInputStream *aInputStream,
michael@0 575 uint64_t aSourceOffset,
michael@0 576 uint32_t aLength)
michael@0 577 {
michael@0 578 NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
michael@0 579 return mListener->OnDataAvailable(static_cast<nsIViewSourceChannel*>
michael@0 580 (this),
michael@0 581 aContext, aInputStream,
michael@0 582 aSourceOffset, aLength);
michael@0 583 }
michael@0 584
michael@0 585
michael@0 586 // nsIHttpChannel methods
michael@0 587
michael@0 588 // We want to forward most of nsIHttpChannel over to mHttpChannel, but we want
michael@0 589 // to override GetRequestHeader and VisitHeaders. The reason is that we don't
michael@0 590 // want various headers like Link: and Refresh: applying to view-source.
michael@0 591 NS_IMETHODIMP
michael@0 592 nsViewSourceChannel::GetRequestMethod(nsACString & aRequestMethod)
michael@0 593 {
michael@0 594 return !mHttpChannel ? NS_ERROR_NULL_POINTER :
michael@0 595 mHttpChannel->GetRequestMethod(aRequestMethod);
michael@0 596 }
michael@0 597
michael@0 598 NS_IMETHODIMP
michael@0 599 nsViewSourceChannel::SetRequestMethod(const nsACString & aRequestMethod)
michael@0 600 {
michael@0 601 return !mHttpChannel ? NS_ERROR_NULL_POINTER :
michael@0 602 mHttpChannel->SetRequestMethod(aRequestMethod);
michael@0 603 }
michael@0 604
michael@0 605 NS_IMETHODIMP
michael@0 606 nsViewSourceChannel::GetReferrer(nsIURI * *aReferrer)
michael@0 607 {
michael@0 608 return !mHttpChannel ? NS_ERROR_NULL_POINTER :
michael@0 609 mHttpChannel->GetReferrer(aReferrer);
michael@0 610 }
michael@0 611
michael@0 612 NS_IMETHODIMP
michael@0 613 nsViewSourceChannel::SetReferrer(nsIURI * aReferrer)
michael@0 614 {
michael@0 615 return !mHttpChannel ? NS_ERROR_NULL_POINTER :
michael@0 616 mHttpChannel->SetReferrer(aReferrer);
michael@0 617 }
michael@0 618
michael@0 619 NS_IMETHODIMP
michael@0 620 nsViewSourceChannel::GetRequestHeader(const nsACString & aHeader,
michael@0 621 nsACString & aValue)
michael@0 622 {
michael@0 623 return !mHttpChannel ? NS_ERROR_NULL_POINTER :
michael@0 624 mHttpChannel->GetRequestHeader(aHeader, aValue);
michael@0 625 }
michael@0 626
michael@0 627 NS_IMETHODIMP
michael@0 628 nsViewSourceChannel::SetRequestHeader(const nsACString & aHeader,
michael@0 629 const nsACString & aValue,
michael@0 630 bool aMerge)
michael@0 631 {
michael@0 632 return !mHttpChannel ? NS_ERROR_NULL_POINTER :
michael@0 633 mHttpChannel->SetRequestHeader(aHeader, aValue, aMerge);
michael@0 634 }
michael@0 635
michael@0 636 NS_IMETHODIMP
michael@0 637 nsViewSourceChannel::VisitRequestHeaders(nsIHttpHeaderVisitor *aVisitor)
michael@0 638 {
michael@0 639 return !mHttpChannel ? NS_ERROR_NULL_POINTER :
michael@0 640 mHttpChannel->VisitRequestHeaders(aVisitor);
michael@0 641 }
michael@0 642
michael@0 643 NS_IMETHODIMP
michael@0 644 nsViewSourceChannel::GetAllowPipelining(bool *aAllowPipelining)
michael@0 645 {
michael@0 646 return !mHttpChannel ? NS_ERROR_NULL_POINTER :
michael@0 647 mHttpChannel->GetAllowPipelining(aAllowPipelining);
michael@0 648 }
michael@0 649
michael@0 650 NS_IMETHODIMP
michael@0 651 nsViewSourceChannel::SetAllowPipelining(bool aAllowPipelining)
michael@0 652 {
michael@0 653 return !mHttpChannel ? NS_ERROR_NULL_POINTER :
michael@0 654 mHttpChannel->SetAllowPipelining(aAllowPipelining);
michael@0 655 }
michael@0 656
michael@0 657 NS_IMETHODIMP
michael@0 658 nsViewSourceChannel::GetRedirectionLimit(uint32_t *aRedirectionLimit)
michael@0 659 {
michael@0 660 return !mHttpChannel ? NS_ERROR_NULL_POINTER :
michael@0 661 mHttpChannel->GetRedirectionLimit(aRedirectionLimit);
michael@0 662 }
michael@0 663
michael@0 664 NS_IMETHODIMP
michael@0 665 nsViewSourceChannel::SetRedirectionLimit(uint32_t aRedirectionLimit)
michael@0 666 {
michael@0 667 return !mHttpChannel ? NS_ERROR_NULL_POINTER :
michael@0 668 mHttpChannel->SetRedirectionLimit(aRedirectionLimit);
michael@0 669 }
michael@0 670
michael@0 671 NS_IMETHODIMP
michael@0 672 nsViewSourceChannel::GetResponseStatus(uint32_t *aResponseStatus)
michael@0 673 {
michael@0 674 return !mHttpChannel ? NS_ERROR_NULL_POINTER :
michael@0 675 mHttpChannel->GetResponseStatus(aResponseStatus);
michael@0 676 }
michael@0 677
michael@0 678 NS_IMETHODIMP
michael@0 679 nsViewSourceChannel::GetResponseStatusText(nsACString & aResponseStatusText)
michael@0 680 {
michael@0 681 return !mHttpChannel ? NS_ERROR_NULL_POINTER :
michael@0 682 mHttpChannel->GetResponseStatusText(aResponseStatusText);
michael@0 683 }
michael@0 684
michael@0 685 NS_IMETHODIMP
michael@0 686 nsViewSourceChannel::GetRequestSucceeded(bool *aRequestSucceeded)
michael@0 687 {
michael@0 688 return !mHttpChannel ? NS_ERROR_NULL_POINTER :
michael@0 689 mHttpChannel->GetRequestSucceeded(aRequestSucceeded);
michael@0 690 }
michael@0 691
michael@0 692 NS_IMETHODIMP
michael@0 693 nsViewSourceChannel::GetResponseHeader(const nsACString & aHeader,
michael@0 694 nsACString & aValue)
michael@0 695 {
michael@0 696 if (!mHttpChannel)
michael@0 697 return NS_ERROR_NULL_POINTER;
michael@0 698
michael@0 699 if (!aHeader.Equals(NS_LITERAL_CSTRING("Content-Type"),
michael@0 700 nsCaseInsensitiveCStringComparator()) &&
michael@0 701 !aHeader.Equals(NS_LITERAL_CSTRING("X-Content-Security-Policy"),
michael@0 702 nsCaseInsensitiveCStringComparator()) &&
michael@0 703 !aHeader.Equals(NS_LITERAL_CSTRING("X-Content-Security-Policy-Report-Only"),
michael@0 704 nsCaseInsensitiveCStringComparator()) &&
michael@0 705 !aHeader.Equals(NS_LITERAL_CSTRING("Content-Security-Policy"),
michael@0 706 nsCaseInsensitiveCStringComparator()) &&
michael@0 707 !aHeader.Equals(NS_LITERAL_CSTRING("Content-Security-Policy-Report-Only"),
michael@0 708 nsCaseInsensitiveCStringComparator()) &&
michael@0 709 !aHeader.Equals(NS_LITERAL_CSTRING("X-Frame-Options"),
michael@0 710 nsCaseInsensitiveCStringComparator())) {
michael@0 711 aValue.Truncate();
michael@0 712 return NS_OK;
michael@0 713 }
michael@0 714
michael@0 715 return mHttpChannel->GetResponseHeader(aHeader, aValue);
michael@0 716 }
michael@0 717
michael@0 718 NS_IMETHODIMP
michael@0 719 nsViewSourceChannel::SetResponseHeader(const nsACString & header,
michael@0 720 const nsACString & value, bool merge)
michael@0 721 {
michael@0 722 return !mHttpChannel ? NS_ERROR_NULL_POINTER :
michael@0 723 mHttpChannel->SetResponseHeader(header, value, merge);
michael@0 724 }
michael@0 725
michael@0 726 NS_IMETHODIMP
michael@0 727 nsViewSourceChannel::VisitResponseHeaders(nsIHttpHeaderVisitor *aVisitor)
michael@0 728 {
michael@0 729 if (!mHttpChannel)
michael@0 730 return NS_ERROR_NULL_POINTER;
michael@0 731
michael@0 732 NS_NAMED_LITERAL_CSTRING(contentTypeStr, "Content-Type");
michael@0 733 nsAutoCString contentType;
michael@0 734 nsresult rv =
michael@0 735 mHttpChannel->GetResponseHeader(contentTypeStr, contentType);
michael@0 736 if (NS_SUCCEEDED(rv))
michael@0 737 aVisitor->VisitHeader(contentTypeStr, contentType);
michael@0 738 return NS_OK;
michael@0 739 }
michael@0 740
michael@0 741 NS_IMETHODIMP
michael@0 742 nsViewSourceChannel::IsNoStoreResponse(bool *_retval)
michael@0 743 {
michael@0 744 return !mHttpChannel ? NS_ERROR_NULL_POINTER :
michael@0 745 mHttpChannel->IsNoStoreResponse(_retval);
michael@0 746 }
michael@0 747
michael@0 748 NS_IMETHODIMP
michael@0 749 nsViewSourceChannel::IsNoCacheResponse(bool *_retval)
michael@0 750 {
michael@0 751 return !mHttpChannel ? NS_ERROR_NULL_POINTER :
michael@0 752 mHttpChannel->IsNoCacheResponse(_retval);
michael@0 753 }
michael@0 754
michael@0 755 NS_IMETHODIMP
michael@0 756 nsViewSourceChannel::RedirectTo(nsIURI *uri)
michael@0 757 {
michael@0 758 return !mHttpChannel ? NS_ERROR_NULL_POINTER :
michael@0 759 mHttpChannel->RedirectTo(uri);
michael@0 760 }
michael@0 761

mercurial