1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,761 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* vim:set ts=4 sw=4 sts=4 et: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "nsViewSourceChannel.h" 1.11 +#include "nsIIOService.h" 1.12 +#include "nsMimeTypes.h" 1.13 +#include "nsNetUtil.h" 1.14 +#include "nsIHttpHeaderVisitor.h" 1.15 + 1.16 +NS_IMPL_ADDREF(nsViewSourceChannel) 1.17 +NS_IMPL_RELEASE(nsViewSourceChannel) 1.18 +/* 1.19 + This QI uses NS_INTERFACE_MAP_ENTRY_CONDITIONAL to check for 1.20 + non-nullness of mHttpChannel, mCachingChannel, and mUploadChannel. 1.21 +*/ 1.22 +NS_INTERFACE_MAP_BEGIN(nsViewSourceChannel) 1.23 + NS_INTERFACE_MAP_ENTRY(nsIViewSourceChannel) 1.24 + NS_INTERFACE_MAP_ENTRY(nsIStreamListener) 1.25 + NS_INTERFACE_MAP_ENTRY(nsIRequestObserver) 1.26 + NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannel, mHttpChannel) 1.27 + NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannelInternal, mHttpChannelInternal) 1.28 + NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsICachingChannel, mCachingChannel) 1.29 + NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIApplicationCacheChannel, mApplicationCacheChannel) 1.30 + NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIUploadChannel, mUploadChannel) 1.31 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIRequest, nsIViewSourceChannel) 1.32 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIChannel, nsIViewSourceChannel) 1.33 + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIViewSourceChannel) 1.34 +NS_INTERFACE_MAP_END 1.35 + 1.36 +nsresult 1.37 +nsViewSourceChannel::Init(nsIURI* uri) 1.38 +{ 1.39 + mOriginalURI = uri; 1.40 + 1.41 + nsAutoCString path; 1.42 + nsresult rv = uri->GetPath(path); 1.43 + if (NS_FAILED(rv)) 1.44 + return rv; 1.45 + 1.46 + nsCOMPtr<nsIIOService> pService(do_GetIOService(&rv)); 1.47 + if (NS_FAILED(rv)) return rv; 1.48 + 1.49 + nsAutoCString scheme; 1.50 + rv = pService->ExtractScheme(path, scheme); 1.51 + if (NS_FAILED(rv)) 1.52 + return rv; 1.53 + 1.54 + // prevent viewing source of javascript URIs (see bug 204779) 1.55 + if (scheme.LowerCaseEqualsLiteral("javascript")) { 1.56 + NS_WARNING("blocking view-source:javascript:"); 1.57 + return NS_ERROR_INVALID_ARG; 1.58 + } 1.59 + 1.60 + rv = pService->NewChannel(path, nullptr, nullptr, getter_AddRefs(mChannel)); 1.61 + if (NS_FAILED(rv)) 1.62 + return rv; 1.63 + 1.64 + mIsSrcdocChannel = false; 1.65 + 1.66 + mChannel->SetOriginalURI(mOriginalURI); 1.67 + mHttpChannel = do_QueryInterface(mChannel); 1.68 + mHttpChannelInternal = do_QueryInterface(mChannel); 1.69 + mCachingChannel = do_QueryInterface(mChannel); 1.70 + mApplicationCacheChannel = do_QueryInterface(mChannel); 1.71 + mUploadChannel = do_QueryInterface(mChannel); 1.72 + 1.73 + return NS_OK; 1.74 +} 1.75 + 1.76 +nsresult 1.77 +nsViewSourceChannel::InitSrcdoc(nsIURI* aURI, const nsAString &aSrcdoc, 1.78 + nsIURI* aBaseURI) 1.79 +{ 1.80 + 1.81 + nsresult rv; 1.82 + 1.83 + nsCOMPtr<nsIURI> inStreamURI; 1.84 + // Need to strip view-source: from the URI. Hardcoded to 1.85 + // about:srcdoc as this is the only permissible URI for srcdoc 1.86 + // loads 1.87 + rv = NS_NewURI(getter_AddRefs(inStreamURI), 1.88 + NS_LITERAL_STRING("about:srcdoc")); 1.89 + NS_ENSURE_SUCCESS(rv, rv); 1.90 + 1.91 + rv = NS_NewInputStreamChannel(getter_AddRefs(mChannel), inStreamURI, 1.92 + aSrcdoc, NS_LITERAL_CSTRING("text/html"), 1.93 + true); 1.94 + 1.95 + NS_ENSURE_SUCCESS(rv, rv); 1.96 + mOriginalURI = aURI; 1.97 + mIsSrcdocChannel = true; 1.98 + nsCOMPtr<nsIInputStreamChannel> isc = do_QueryInterface(mChannel); 1.99 + MOZ_ASSERT(isc); 1.100 + isc->SetBaseURI(aBaseURI); 1.101 + 1.102 + mChannel->SetOriginalURI(mOriginalURI); 1.103 + mHttpChannel = do_QueryInterface(mChannel); 1.104 + mHttpChannelInternal = do_QueryInterface(mChannel); 1.105 + mCachingChannel = do_QueryInterface(mChannel); 1.106 + mApplicationCacheChannel = do_QueryInterface(mChannel); 1.107 + mUploadChannel = do_QueryInterface(mChannel); 1.108 + return NS_OK; 1.109 +} 1.110 + 1.111 +//////////////////////////////////////////////////////////////////////////////// 1.112 +// nsIRequest methods: 1.113 + 1.114 +NS_IMETHODIMP 1.115 +nsViewSourceChannel::GetName(nsACString &result) 1.116 +{ 1.117 + return NS_ERROR_NOT_IMPLEMENTED; 1.118 +} 1.119 + 1.120 +NS_IMETHODIMP 1.121 +nsViewSourceChannel::GetProxyURI(nsIURI** proxyURI) 1.122 +{ 1.123 + return NS_ERROR_NOT_IMPLEMENTED; 1.124 +} 1.125 + 1.126 +NS_IMETHODIMP 1.127 +nsViewSourceChannel::IsPending(bool *result) 1.128 +{ 1.129 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.130 + 1.131 + return mChannel->IsPending(result); 1.132 +} 1.133 + 1.134 +NS_IMETHODIMP 1.135 +nsViewSourceChannel::GetStatus(nsresult *status) 1.136 +{ 1.137 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.138 + 1.139 + return mChannel->GetStatus(status); 1.140 +} 1.141 + 1.142 +NS_IMETHODIMP 1.143 +nsViewSourceChannel::Cancel(nsresult status) 1.144 +{ 1.145 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.146 + 1.147 + return mChannel->Cancel(status); 1.148 +} 1.149 + 1.150 +NS_IMETHODIMP 1.151 +nsViewSourceChannel::Suspend(void) 1.152 +{ 1.153 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.154 + 1.155 + return mChannel->Suspend(); 1.156 +} 1.157 + 1.158 +NS_IMETHODIMP 1.159 +nsViewSourceChannel::Resume(void) 1.160 +{ 1.161 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.162 + 1.163 + return mChannel->Resume(); 1.164 +} 1.165 + 1.166 +//////////////////////////////////////////////////////////////////////////////// 1.167 +// nsIChannel methods: 1.168 + 1.169 +NS_IMETHODIMP 1.170 +nsViewSourceChannel::GetOriginalURI(nsIURI* *aURI) 1.171 +{ 1.172 + NS_ASSERTION(aURI, "Null out param!"); 1.173 + *aURI = mOriginalURI; 1.174 + NS_ADDREF(*aURI); 1.175 + return NS_OK; 1.176 +} 1.177 + 1.178 +NS_IMETHODIMP 1.179 +nsViewSourceChannel::SetOriginalURI(nsIURI* aURI) 1.180 +{ 1.181 + NS_ENSURE_ARG_POINTER(aURI); 1.182 + mOriginalURI = aURI; 1.183 + return NS_OK; 1.184 +} 1.185 + 1.186 +NS_IMETHODIMP 1.187 +nsViewSourceChannel::GetURI(nsIURI* *aURI) 1.188 +{ 1.189 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.190 + 1.191 + nsCOMPtr<nsIURI> uri; 1.192 + nsresult rv = mChannel->GetURI(getter_AddRefs(uri)); 1.193 + if (NS_FAILED(rv)) 1.194 + return rv; 1.195 + 1.196 + // protect ourselves against broken channel implementations 1.197 + if (!uri) { 1.198 + NS_ERROR("inner channel returned NS_OK and a null URI"); 1.199 + return NS_ERROR_UNEXPECTED; 1.200 + } 1.201 + 1.202 + nsAutoCString spec; 1.203 + uri->GetSpec(spec); 1.204 + 1.205 + /* XXX Gross hack -- NS_NewURI goes into an infinite loop on 1.206 + non-flat specs. See bug 136980 */ 1.207 + return NS_NewURI(aURI, nsAutoCString(NS_LITERAL_CSTRING("view-source:")+spec), nullptr); 1.208 +} 1.209 + 1.210 +NS_IMETHODIMP 1.211 +nsViewSourceChannel::Open(nsIInputStream **_retval) 1.212 +{ 1.213 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.214 + 1.215 + nsresult rv = mChannel->Open(_retval); 1.216 + if (NS_SUCCEEDED(rv)) { 1.217 + mOpened = true; 1.218 + } 1.219 + 1.220 + return rv; 1.221 +} 1.222 + 1.223 +NS_IMETHODIMP 1.224 +nsViewSourceChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt) 1.225 +{ 1.226 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.227 + 1.228 + mListener = aListener; 1.229 + 1.230 + /* 1.231 + * We want to add ourselves to the loadgroup before opening 1.232 + * mChannel, since we want to make sure we're in the loadgroup 1.233 + * when mChannel finishes and fires OnStopRequest() 1.234 + */ 1.235 + 1.236 + nsCOMPtr<nsILoadGroup> loadGroup; 1.237 + mChannel->GetLoadGroup(getter_AddRefs(loadGroup)); 1.238 + if (loadGroup) 1.239 + loadGroup->AddRequest(static_cast<nsIViewSourceChannel*> 1.240 + (this), nullptr); 1.241 + 1.242 + nsresult rv = mChannel->AsyncOpen(this, ctxt); 1.243 + 1.244 + if (NS_FAILED(rv) && loadGroup) 1.245 + loadGroup->RemoveRequest(static_cast<nsIViewSourceChannel*> 1.246 + (this), 1.247 + nullptr, rv); 1.248 + 1.249 + if (NS_SUCCEEDED(rv)) { 1.250 + mOpened = true; 1.251 + } 1.252 + 1.253 + return rv; 1.254 +} 1.255 + 1.256 +/* 1.257 + * Both the view source channel and mChannel are added to the 1.258 + * loadgroup. There should never be more than one request in the 1.259 + * loadgroup that has LOAD_DOCUMENT_URI set. The one that has this 1.260 + * flag set is the request whose URI is used to refetch the document, 1.261 + * so it better be the viewsource channel. 1.262 + * 1.263 + * Therefore, we need to make sure that 1.264 + * 1) The load flags on mChannel _never_ include LOAD_DOCUMENT_URI 1.265 + * 2) The load flags on |this| include LOAD_DOCUMENT_URI when it was 1.266 + * set via SetLoadFlags (mIsDocument keeps track of this flag). 1.267 + */ 1.268 + 1.269 +NS_IMETHODIMP 1.270 +nsViewSourceChannel::GetLoadFlags(uint32_t *aLoadFlags) 1.271 +{ 1.272 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.273 + 1.274 + nsresult rv = mChannel->GetLoadFlags(aLoadFlags); 1.275 + if (NS_FAILED(rv)) 1.276 + return rv; 1.277 + 1.278 + // This should actually be just LOAD_DOCUMENT_URI but the win32 compiler 1.279 + // fails to deal due to amiguous inheritance. nsIChannel::LOAD_DOCUMENT_URI 1.280 + // also fails; the Win32 compiler thinks that's supposed to be a method. 1.281 + if (mIsDocument) 1.282 + *aLoadFlags |= ::nsIChannel::LOAD_DOCUMENT_URI; 1.283 + 1.284 + return rv; 1.285 +} 1.286 + 1.287 +NS_IMETHODIMP 1.288 +nsViewSourceChannel::SetLoadFlags(uint32_t aLoadFlags) 1.289 +{ 1.290 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.291 + 1.292 + // "View source" always wants the currently cached content. 1.293 + // We also want to have _this_ channel, not mChannel to be the 1.294 + // 'document' channel in the loadgroup. 1.295 + 1.296 + // These should actually be just LOAD_FROM_CACHE and LOAD_DOCUMENT_URI but 1.297 + // the win32 compiler fails to deal due to amiguous inheritance. 1.298 + // nsIChannel::LOAD_DOCUMENT_URI/nsIRequest::LOAD_FROM_CACHE also fails; the 1.299 + // Win32 compiler thinks that's supposed to be a method. 1.300 + mIsDocument = (aLoadFlags & ::nsIChannel::LOAD_DOCUMENT_URI) ? true : false; 1.301 + 1.302 + return mChannel->SetLoadFlags((aLoadFlags | 1.303 + ::nsIRequest::LOAD_FROM_CACHE) & 1.304 + ~::nsIChannel::LOAD_DOCUMENT_URI); 1.305 +} 1.306 + 1.307 +NS_IMETHODIMP 1.308 +nsViewSourceChannel::GetContentType(nsACString &aContentType) 1.309 +{ 1.310 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.311 + 1.312 + aContentType.Truncate(); 1.313 + 1.314 + if (mContentType.IsEmpty()) 1.315 + { 1.316 + // Get the current content type 1.317 + nsresult rv; 1.318 + nsAutoCString contentType; 1.319 + rv = mChannel->GetContentType(contentType); 1.320 + if (NS_FAILED(rv)) return rv; 1.321 + 1.322 + // If we don't know our type, just say so. The unknown 1.323 + // content decoder will then kick in automatically, and it 1.324 + // will call our SetOriginalContentType method instead of our 1.325 + // SetContentType method to set the type it determines. 1.326 + if (!contentType.Equals(UNKNOWN_CONTENT_TYPE)) { 1.327 + contentType = VIEWSOURCE_CONTENT_TYPE; 1.328 + } 1.329 + 1.330 + mContentType = contentType; 1.331 + } 1.332 + 1.333 + aContentType = mContentType; 1.334 + return NS_OK; 1.335 +} 1.336 + 1.337 +NS_IMETHODIMP 1.338 +nsViewSourceChannel::SetContentType(const nsACString &aContentType) 1.339 +{ 1.340 + // Our GetContentType() currently returns VIEWSOURCE_CONTENT_TYPE 1.341 + // 1.342 + // However, during the parsing phase the parser calls our 1.343 + // channel's GetContentType(). Returning the string above trips up 1.344 + // the parser. In order to avoid messy changes and not to have the 1.345 + // parser depend on nsIViewSourceChannel Vidur proposed the 1.346 + // following solution: 1.347 + // 1.348 + // The ViewSourceChannel initially returns a content type of 1.349 + // VIEWSOURCE_CONTENT_TYPE. Based on this type decisions to 1.350 + // create a viewer for doing a view source are made. After the 1.351 + // viewer is created, nsLayoutDLF::CreateInstance() calls this 1.352 + // SetContentType() with the original content type. When it's 1.353 + // time for the parser to find out the content type it will call 1.354 + // our channel's GetContentType() and it will get the original 1.355 + // content type, such as, text/html and everything is kosher from 1.356 + // then on. 1.357 + 1.358 + if (!mOpened) { 1.359 + // We do not take hints 1.360 + return NS_ERROR_NOT_AVAILABLE; 1.361 + } 1.362 + 1.363 + mContentType = aContentType; 1.364 + return NS_OK; 1.365 +} 1.366 + 1.367 +NS_IMETHODIMP 1.368 +nsViewSourceChannel::GetContentCharset(nsACString &aContentCharset) 1.369 +{ 1.370 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.371 + 1.372 + return mChannel->GetContentCharset(aContentCharset); 1.373 +} 1.374 + 1.375 +NS_IMETHODIMP 1.376 +nsViewSourceChannel::SetContentCharset(const nsACString &aContentCharset) 1.377 +{ 1.378 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.379 + 1.380 + return mChannel->SetContentCharset(aContentCharset); 1.381 +} 1.382 + 1.383 +// We don't forward these methods becacuse content-disposition isn't whitelisted 1.384 +// (see GetResponseHeader/VisitResponseHeaders). 1.385 +NS_IMETHODIMP 1.386 +nsViewSourceChannel::GetContentDisposition(uint32_t *aContentDisposition) 1.387 +{ 1.388 + return NS_ERROR_NOT_AVAILABLE; 1.389 +} 1.390 + 1.391 +NS_IMETHODIMP 1.392 +nsViewSourceChannel::SetContentDisposition(uint32_t aContentDisposition) 1.393 +{ 1.394 + return NS_ERROR_NOT_AVAILABLE; 1.395 +} 1.396 + 1.397 +NS_IMETHODIMP 1.398 +nsViewSourceChannel::GetContentDispositionFilename(nsAString &aContentDispositionFilename) 1.399 +{ 1.400 + return NS_ERROR_NOT_AVAILABLE; 1.401 +} 1.402 + 1.403 +NS_IMETHODIMP 1.404 +nsViewSourceChannel::SetContentDispositionFilename(const nsAString &aContentDispositionFilename) 1.405 +{ 1.406 + return NS_ERROR_NOT_AVAILABLE; 1.407 +} 1.408 + 1.409 +NS_IMETHODIMP 1.410 +nsViewSourceChannel::GetContentDispositionHeader(nsACString &aContentDispositionHeader) 1.411 +{ 1.412 + return NS_ERROR_NOT_AVAILABLE; 1.413 +} 1.414 + 1.415 +NS_IMETHODIMP 1.416 +nsViewSourceChannel::GetContentLength(int64_t *aContentLength) 1.417 +{ 1.418 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.419 + 1.420 + return mChannel->GetContentLength(aContentLength); 1.421 +} 1.422 + 1.423 +NS_IMETHODIMP 1.424 +nsViewSourceChannel::SetContentLength(int64_t aContentLength) 1.425 +{ 1.426 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.427 + 1.428 + return mChannel->SetContentLength(aContentLength); 1.429 +} 1.430 + 1.431 +NS_IMETHODIMP 1.432 +nsViewSourceChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup) 1.433 +{ 1.434 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.435 + 1.436 + return mChannel->GetLoadGroup(aLoadGroup); 1.437 +} 1.438 + 1.439 +NS_IMETHODIMP 1.440 +nsViewSourceChannel::SetLoadGroup(nsILoadGroup* aLoadGroup) 1.441 +{ 1.442 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.443 + 1.444 + return mChannel->SetLoadGroup(aLoadGroup); 1.445 +} 1.446 + 1.447 +NS_IMETHODIMP 1.448 +nsViewSourceChannel::GetOwner(nsISupports* *aOwner) 1.449 +{ 1.450 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.451 + 1.452 + return mChannel->GetOwner(aOwner); 1.453 +} 1.454 + 1.455 +NS_IMETHODIMP 1.456 +nsViewSourceChannel::SetOwner(nsISupports* aOwner) 1.457 +{ 1.458 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.459 + 1.460 + return mChannel->SetOwner(aOwner); 1.461 +} 1.462 + 1.463 +NS_IMETHODIMP 1.464 +nsViewSourceChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks) 1.465 +{ 1.466 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.467 + 1.468 + return mChannel->GetNotificationCallbacks(aNotificationCallbacks); 1.469 +} 1.470 + 1.471 +NS_IMETHODIMP 1.472 +nsViewSourceChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks) 1.473 +{ 1.474 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.475 + 1.476 + return mChannel->SetNotificationCallbacks(aNotificationCallbacks); 1.477 +} 1.478 + 1.479 +NS_IMETHODIMP 1.480 +nsViewSourceChannel::GetSecurityInfo(nsISupports * *aSecurityInfo) 1.481 +{ 1.482 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.483 + 1.484 + return mChannel->GetSecurityInfo(aSecurityInfo); 1.485 +} 1.486 + 1.487 +// nsIViewSourceChannel methods 1.488 +NS_IMETHODIMP 1.489 +nsViewSourceChannel::GetOriginalContentType(nsACString &aContentType) 1.490 +{ 1.491 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.492 + 1.493 + return mChannel->GetContentType(aContentType); 1.494 +} 1.495 + 1.496 +NS_IMETHODIMP 1.497 +nsViewSourceChannel::SetOriginalContentType(const nsACString &aContentType) 1.498 +{ 1.499 + NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE); 1.500 + 1.501 + // clear our cached content-type value 1.502 + mContentType.Truncate(); 1.503 + 1.504 + return mChannel->SetContentType(aContentType); 1.505 +} 1.506 + 1.507 +NS_IMETHODIMP 1.508 +nsViewSourceChannel::GetIsSrcdocChannel(bool* aIsSrcdocChannel) 1.509 +{ 1.510 + *aIsSrcdocChannel = mIsSrcdocChannel; 1.511 + return NS_OK; 1.512 +} 1.513 + 1.514 +NS_IMETHODIMP 1.515 +nsViewSourceChannel::GetBaseURI(nsIURI** aBaseURI) 1.516 +{ 1.517 + if (mIsSrcdocChannel) { 1.518 + nsCOMPtr<nsIInputStreamChannel> isc = do_QueryInterface(mChannel); 1.519 + if (isc) { 1.520 + return isc->GetBaseURI(aBaseURI); 1.521 + } 1.522 + } 1.523 + *aBaseURI = mBaseURI; 1.524 + NS_IF_ADDREF(*aBaseURI); 1.525 + return NS_OK; 1.526 +} 1.527 + 1.528 +NS_IMETHODIMP 1.529 +nsViewSourceChannel::SetBaseURI(nsIURI* aBaseURI) 1.530 +{ 1.531 + mBaseURI = aBaseURI; 1.532 + return NS_OK; 1.533 +} 1.534 + 1.535 +// nsIRequestObserver methods 1.536 +NS_IMETHODIMP 1.537 +nsViewSourceChannel::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext) 1.538 +{ 1.539 + NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE); 1.540 + // The channel may have gotten redirected... Time to update our info 1.541 + mChannel = do_QueryInterface(aRequest); 1.542 + mHttpChannel = do_QueryInterface(aRequest); 1.543 + mCachingChannel = do_QueryInterface(aRequest); 1.544 + mUploadChannel = do_QueryInterface(aRequest); 1.545 + 1.546 + return mListener->OnStartRequest(static_cast<nsIViewSourceChannel*> 1.547 + (this), 1.548 + aContext); 1.549 +} 1.550 + 1.551 + 1.552 +NS_IMETHODIMP 1.553 +nsViewSourceChannel::OnStopRequest(nsIRequest *aRequest, nsISupports* aContext, 1.554 + nsresult aStatus) 1.555 +{ 1.556 + NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE); 1.557 + if (mChannel) 1.558 + { 1.559 + nsCOMPtr<nsILoadGroup> loadGroup; 1.560 + mChannel->GetLoadGroup(getter_AddRefs(loadGroup)); 1.561 + if (loadGroup) 1.562 + { 1.563 + loadGroup->RemoveRequest(static_cast<nsIViewSourceChannel*> 1.564 + (this), 1.565 + nullptr, aStatus); 1.566 + } 1.567 + } 1.568 + return mListener->OnStopRequest(static_cast<nsIViewSourceChannel*> 1.569 + (this), 1.570 + aContext, aStatus); 1.571 +} 1.572 + 1.573 + 1.574 +// nsIStreamListener methods 1.575 +NS_IMETHODIMP 1.576 +nsViewSourceChannel::OnDataAvailable(nsIRequest *aRequest, nsISupports* aContext, 1.577 + nsIInputStream *aInputStream, 1.578 + uint64_t aSourceOffset, 1.579 + uint32_t aLength) 1.580 +{ 1.581 + NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE); 1.582 + return mListener->OnDataAvailable(static_cast<nsIViewSourceChannel*> 1.583 + (this), 1.584 + aContext, aInputStream, 1.585 + aSourceOffset, aLength); 1.586 +} 1.587 + 1.588 + 1.589 +// nsIHttpChannel methods 1.590 + 1.591 +// We want to forward most of nsIHttpChannel over to mHttpChannel, but we want 1.592 +// to override GetRequestHeader and VisitHeaders. The reason is that we don't 1.593 +// want various headers like Link: and Refresh: applying to view-source. 1.594 +NS_IMETHODIMP 1.595 +nsViewSourceChannel::GetRequestMethod(nsACString & aRequestMethod) 1.596 +{ 1.597 + return !mHttpChannel ? NS_ERROR_NULL_POINTER : 1.598 + mHttpChannel->GetRequestMethod(aRequestMethod); 1.599 +} 1.600 + 1.601 +NS_IMETHODIMP 1.602 +nsViewSourceChannel::SetRequestMethod(const nsACString & aRequestMethod) 1.603 +{ 1.604 + return !mHttpChannel ? NS_ERROR_NULL_POINTER : 1.605 + mHttpChannel->SetRequestMethod(aRequestMethod); 1.606 +} 1.607 + 1.608 +NS_IMETHODIMP 1.609 +nsViewSourceChannel::GetReferrer(nsIURI * *aReferrer) 1.610 +{ 1.611 + return !mHttpChannel ? NS_ERROR_NULL_POINTER : 1.612 + mHttpChannel->GetReferrer(aReferrer); 1.613 +} 1.614 + 1.615 +NS_IMETHODIMP 1.616 +nsViewSourceChannel::SetReferrer(nsIURI * aReferrer) 1.617 +{ 1.618 + return !mHttpChannel ? NS_ERROR_NULL_POINTER : 1.619 + mHttpChannel->SetReferrer(aReferrer); 1.620 +} 1.621 + 1.622 +NS_IMETHODIMP 1.623 +nsViewSourceChannel::GetRequestHeader(const nsACString & aHeader, 1.624 + nsACString & aValue) 1.625 +{ 1.626 + return !mHttpChannel ? NS_ERROR_NULL_POINTER : 1.627 + mHttpChannel->GetRequestHeader(aHeader, aValue); 1.628 +} 1.629 + 1.630 +NS_IMETHODIMP 1.631 +nsViewSourceChannel::SetRequestHeader(const nsACString & aHeader, 1.632 + const nsACString & aValue, 1.633 + bool aMerge) 1.634 +{ 1.635 + return !mHttpChannel ? NS_ERROR_NULL_POINTER : 1.636 + mHttpChannel->SetRequestHeader(aHeader, aValue, aMerge); 1.637 +} 1.638 + 1.639 +NS_IMETHODIMP 1.640 +nsViewSourceChannel::VisitRequestHeaders(nsIHttpHeaderVisitor *aVisitor) 1.641 +{ 1.642 + return !mHttpChannel ? NS_ERROR_NULL_POINTER : 1.643 + mHttpChannel->VisitRequestHeaders(aVisitor); 1.644 +} 1.645 + 1.646 +NS_IMETHODIMP 1.647 +nsViewSourceChannel::GetAllowPipelining(bool *aAllowPipelining) 1.648 +{ 1.649 + return !mHttpChannel ? NS_ERROR_NULL_POINTER : 1.650 + mHttpChannel->GetAllowPipelining(aAllowPipelining); 1.651 +} 1.652 + 1.653 +NS_IMETHODIMP 1.654 +nsViewSourceChannel::SetAllowPipelining(bool aAllowPipelining) 1.655 +{ 1.656 + return !mHttpChannel ? NS_ERROR_NULL_POINTER : 1.657 + mHttpChannel->SetAllowPipelining(aAllowPipelining); 1.658 +} 1.659 + 1.660 +NS_IMETHODIMP 1.661 +nsViewSourceChannel::GetRedirectionLimit(uint32_t *aRedirectionLimit) 1.662 +{ 1.663 + return !mHttpChannel ? NS_ERROR_NULL_POINTER : 1.664 + mHttpChannel->GetRedirectionLimit(aRedirectionLimit); 1.665 +} 1.666 + 1.667 +NS_IMETHODIMP 1.668 +nsViewSourceChannel::SetRedirectionLimit(uint32_t aRedirectionLimit) 1.669 +{ 1.670 + return !mHttpChannel ? NS_ERROR_NULL_POINTER : 1.671 + mHttpChannel->SetRedirectionLimit(aRedirectionLimit); 1.672 +} 1.673 + 1.674 +NS_IMETHODIMP 1.675 +nsViewSourceChannel::GetResponseStatus(uint32_t *aResponseStatus) 1.676 +{ 1.677 + return !mHttpChannel ? NS_ERROR_NULL_POINTER : 1.678 + mHttpChannel->GetResponseStatus(aResponseStatus); 1.679 +} 1.680 + 1.681 +NS_IMETHODIMP 1.682 +nsViewSourceChannel::GetResponseStatusText(nsACString & aResponseStatusText) 1.683 +{ 1.684 + return !mHttpChannel ? NS_ERROR_NULL_POINTER : 1.685 + mHttpChannel->GetResponseStatusText(aResponseStatusText); 1.686 +} 1.687 + 1.688 +NS_IMETHODIMP 1.689 +nsViewSourceChannel::GetRequestSucceeded(bool *aRequestSucceeded) 1.690 +{ 1.691 + return !mHttpChannel ? NS_ERROR_NULL_POINTER : 1.692 + mHttpChannel->GetRequestSucceeded(aRequestSucceeded); 1.693 +} 1.694 + 1.695 +NS_IMETHODIMP 1.696 +nsViewSourceChannel::GetResponseHeader(const nsACString & aHeader, 1.697 + nsACString & aValue) 1.698 +{ 1.699 + if (!mHttpChannel) 1.700 + return NS_ERROR_NULL_POINTER; 1.701 + 1.702 + if (!aHeader.Equals(NS_LITERAL_CSTRING("Content-Type"), 1.703 + nsCaseInsensitiveCStringComparator()) && 1.704 + !aHeader.Equals(NS_LITERAL_CSTRING("X-Content-Security-Policy"), 1.705 + nsCaseInsensitiveCStringComparator()) && 1.706 + !aHeader.Equals(NS_LITERAL_CSTRING("X-Content-Security-Policy-Report-Only"), 1.707 + nsCaseInsensitiveCStringComparator()) && 1.708 + !aHeader.Equals(NS_LITERAL_CSTRING("Content-Security-Policy"), 1.709 + nsCaseInsensitiveCStringComparator()) && 1.710 + !aHeader.Equals(NS_LITERAL_CSTRING("Content-Security-Policy-Report-Only"), 1.711 + nsCaseInsensitiveCStringComparator()) && 1.712 + !aHeader.Equals(NS_LITERAL_CSTRING("X-Frame-Options"), 1.713 + nsCaseInsensitiveCStringComparator())) { 1.714 + aValue.Truncate(); 1.715 + return NS_OK; 1.716 + } 1.717 + 1.718 + return mHttpChannel->GetResponseHeader(aHeader, aValue); 1.719 +} 1.720 + 1.721 +NS_IMETHODIMP 1.722 +nsViewSourceChannel::SetResponseHeader(const nsACString & header, 1.723 + const nsACString & value, bool merge) 1.724 +{ 1.725 + return !mHttpChannel ? NS_ERROR_NULL_POINTER : 1.726 + mHttpChannel->SetResponseHeader(header, value, merge); 1.727 +} 1.728 + 1.729 +NS_IMETHODIMP 1.730 +nsViewSourceChannel::VisitResponseHeaders(nsIHttpHeaderVisitor *aVisitor) 1.731 +{ 1.732 + if (!mHttpChannel) 1.733 + return NS_ERROR_NULL_POINTER; 1.734 + 1.735 + NS_NAMED_LITERAL_CSTRING(contentTypeStr, "Content-Type"); 1.736 + nsAutoCString contentType; 1.737 + nsresult rv = 1.738 + mHttpChannel->GetResponseHeader(contentTypeStr, contentType); 1.739 + if (NS_SUCCEEDED(rv)) 1.740 + aVisitor->VisitHeader(contentTypeStr, contentType); 1.741 + return NS_OK; 1.742 +} 1.743 + 1.744 +NS_IMETHODIMP 1.745 +nsViewSourceChannel::IsNoStoreResponse(bool *_retval) 1.746 +{ 1.747 + return !mHttpChannel ? NS_ERROR_NULL_POINTER : 1.748 + mHttpChannel->IsNoStoreResponse(_retval); 1.749 +} 1.750 + 1.751 +NS_IMETHODIMP 1.752 +nsViewSourceChannel::IsNoCacheResponse(bool *_retval) 1.753 +{ 1.754 + return !mHttpChannel ? NS_ERROR_NULL_POINTER : 1.755 + mHttpChannel->IsNoCacheResponse(_retval); 1.756 +} 1.757 + 1.758 +NS_IMETHODIMP 1.759 +nsViewSourceChannel::RedirectTo(nsIURI *uri) 1.760 +{ 1.761 + return !mHttpChannel ? NS_ERROR_NULL_POINTER : 1.762 + mHttpChannel->RedirectTo(uri); 1.763 +} 1.764 +