Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* vim:set ts=4 sw=4 sts=4 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 "nsIIOService.h"
9 : #include "nsMimeTypes.h"
10 : #include "nsNetUtil.h"
11 : #include "nsContentUtils.h"
12 : #include "nsIHttpHeaderVisitor.h"
13 : #include "nsContentSecurityManager.h"
14 : #include "NullPrincipal.h"
15 : #include "nsServiceManagerUtils.h"
16 : #include "nsIInputStreamChannel.h"
17 : #include "mozilla/DebugOnly.h"
18 :
19 0 : NS_IMPL_ADDREF(nsViewSourceChannel)
20 0 : NS_IMPL_RELEASE(nsViewSourceChannel)
21 : /*
22 : This QI uses NS_INTERFACE_MAP_ENTRY_CONDITIONAL to check for
23 : non-nullness of mHttpChannel, mCachingChannel, and mUploadChannel.
24 : */
25 0 : NS_INTERFACE_MAP_BEGIN(nsViewSourceChannel)
26 0 : NS_INTERFACE_MAP_ENTRY(nsIViewSourceChannel)
27 0 : NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
28 0 : NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
29 0 : NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannel, mHttpChannel)
30 0 : NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIHttpChannelInternal, mHttpChannelInternal)
31 0 : NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsICachingChannel, mCachingChannel)
32 0 : NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsICacheInfoChannel, mCacheInfoChannel)
33 0 : NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIApplicationCacheChannel, mApplicationCacheChannel)
34 0 : NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIUploadChannel, mUploadChannel)
35 0 : NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIFormPOSTActionChannel, mPostChannel)
36 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIRequest, nsIViewSourceChannel)
37 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIChannel, nsIViewSourceChannel)
38 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIViewSourceChannel)
39 0 : NS_INTERFACE_MAP_END
40 :
41 : nsresult
42 0 : nsViewSourceChannel::Init(nsIURI* uri)
43 : {
44 0 : mOriginalURI = uri;
45 :
46 0 : nsAutoCString path;
47 0 : nsresult rv = uri->GetPath(path);
48 0 : if (NS_FAILED(rv))
49 0 : return rv;
50 :
51 0 : nsCOMPtr<nsIIOService> pService(do_GetIOService(&rv));
52 0 : if (NS_FAILED(rv)) return rv;
53 :
54 0 : nsAutoCString scheme;
55 0 : rv = pService->ExtractScheme(path, scheme);
56 0 : if (NS_FAILED(rv))
57 0 : return rv;
58 :
59 : // prevent viewing source of javascript URIs (see bug 204779)
60 0 : if (scheme.LowerCaseEqualsLiteral("javascript")) {
61 0 : NS_WARNING("blocking view-source:javascript:");
62 0 : return NS_ERROR_INVALID_ARG;
63 : }
64 :
65 : // This function is called from within nsViewSourceHandler::NewChannel2
66 : // and sets the right loadInfo right after returning from this function.
67 : // Until then we follow the principal of least privilege and use
68 : // nullPrincipal as the loadingPrincipal and the least permissive
69 : // securityflag.
70 0 : nsCOMPtr<nsIPrincipal> nullPrincipal = NullPrincipal::Create();
71 :
72 0 : rv = pService->NewChannel2(path,
73 : nullptr, // aOriginCharset
74 : nullptr, // aCharSet
75 : nullptr, // aLoadingNode
76 : nullPrincipal,
77 : nullptr, // aTriggeringPrincipal
78 : nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED,
79 : nsIContentPolicy::TYPE_OTHER,
80 0 : getter_AddRefs(mChannel));
81 0 : NS_ENSURE_SUCCESS(rv, rv);
82 :
83 0 : mIsSrcdocChannel = false;
84 :
85 0 : mChannel->SetOriginalURI(mOriginalURI);
86 0 : mHttpChannel = do_QueryInterface(mChannel);
87 0 : mHttpChannelInternal = do_QueryInterface(mChannel);
88 0 : mCachingChannel = do_QueryInterface(mChannel);
89 0 : mCacheInfoChannel = do_QueryInterface(mChannel);
90 0 : mApplicationCacheChannel = do_QueryInterface(mChannel);
91 0 : mUploadChannel = do_QueryInterface(mChannel);
92 0 : mPostChannel = do_QueryInterface(mChannel);
93 :
94 0 : return NS_OK;
95 : }
96 :
97 : nsresult
98 0 : nsViewSourceChannel::InitSrcdoc(nsIURI* aURI,
99 : nsIURI* aBaseURI,
100 : const nsAString &aSrcdoc,
101 : nsILoadInfo* aLoadInfo)
102 : {
103 : nsresult rv;
104 :
105 0 : nsCOMPtr<nsIURI> inStreamURI;
106 : // Need to strip view-source: from the URI. Hardcoded to
107 : // about:srcdoc as this is the only permissible URI for srcdoc
108 : // loads
109 0 : rv = NS_NewURI(getter_AddRefs(inStreamURI),
110 0 : NS_LITERAL_STRING("about:srcdoc"));
111 0 : NS_ENSURE_SUCCESS(rv, rv);
112 :
113 0 : rv = NS_NewInputStreamChannelInternal(getter_AddRefs(mChannel),
114 : inStreamURI,
115 : aSrcdoc,
116 0 : NS_LITERAL_CSTRING("text/html"),
117 : aLoadInfo,
118 0 : true);
119 :
120 0 : NS_ENSURE_SUCCESS(rv, rv);
121 0 : mOriginalURI = aURI;
122 0 : mIsSrcdocChannel = true;
123 :
124 0 : mChannel->SetOriginalURI(mOriginalURI);
125 0 : mHttpChannel = do_QueryInterface(mChannel);
126 0 : mHttpChannelInternal = do_QueryInterface(mChannel);
127 0 : mCachingChannel = do_QueryInterface(mChannel);
128 0 : mCacheInfoChannel = do_QueryInterface(mChannel);
129 0 : mApplicationCacheChannel = do_QueryInterface(mChannel);
130 0 : mUploadChannel = do_QueryInterface(mChannel);
131 :
132 0 : nsCOMPtr<nsIInputStreamChannel> isc = do_QueryInterface(mChannel);
133 0 : MOZ_ASSERT(isc);
134 0 : isc->SetBaseURI(aBaseURI);
135 0 : return NS_OK;
136 : }
137 :
138 : ////////////////////////////////////////////////////////////////////////////////
139 : // nsIRequest methods:
140 :
141 : NS_IMETHODIMP
142 0 : nsViewSourceChannel::GetName(nsACString &result)
143 : {
144 0 : return NS_ERROR_NOT_IMPLEMENTED;
145 : }
146 :
147 : NS_IMETHODIMP
148 0 : nsViewSourceChannel::GetTransferSize(uint64_t *aTransferSize)
149 : {
150 0 : return NS_ERROR_NOT_IMPLEMENTED;
151 : }
152 :
153 : NS_IMETHODIMP
154 0 : nsViewSourceChannel::GetDecodedBodySize(uint64_t *aDecodedBodySize)
155 : {
156 0 : return NS_ERROR_NOT_IMPLEMENTED;
157 : }
158 :
159 : NS_IMETHODIMP
160 0 : nsViewSourceChannel::GetEncodedBodySize(uint64_t *aEncodedBodySize)
161 : {
162 0 : return NS_ERROR_NOT_IMPLEMENTED;
163 : }
164 :
165 : NS_IMETHODIMP
166 0 : nsViewSourceChannel::IsPending(bool *result)
167 : {
168 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
169 :
170 0 : return mChannel->IsPending(result);
171 : }
172 :
173 : NS_IMETHODIMP
174 0 : nsViewSourceChannel::GetStatus(nsresult *status)
175 : {
176 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
177 :
178 0 : return mChannel->GetStatus(status);
179 : }
180 :
181 : NS_IMETHODIMP
182 0 : nsViewSourceChannel::Cancel(nsresult status)
183 : {
184 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
185 :
186 0 : return mChannel->Cancel(status);
187 : }
188 :
189 : NS_IMETHODIMP
190 0 : nsViewSourceChannel::Suspend(void)
191 : {
192 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
193 :
194 0 : return mChannel->Suspend();
195 : }
196 :
197 : NS_IMETHODIMP
198 0 : nsViewSourceChannel::Resume(void)
199 : {
200 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
201 :
202 0 : return mChannel->Resume();
203 : }
204 :
205 : ////////////////////////////////////////////////////////////////////////////////
206 : // nsIChannel methods:
207 :
208 : NS_IMETHODIMP
209 0 : nsViewSourceChannel::GetOriginalURI(nsIURI* *aURI)
210 : {
211 0 : NS_ASSERTION(aURI, "Null out param!");
212 0 : *aURI = mOriginalURI;
213 0 : NS_ADDREF(*aURI);
214 0 : return NS_OK;
215 : }
216 :
217 : NS_IMETHODIMP
218 0 : nsViewSourceChannel::SetOriginalURI(nsIURI* aURI)
219 : {
220 0 : NS_ENSURE_ARG_POINTER(aURI);
221 0 : mOriginalURI = aURI;
222 0 : return NS_OK;
223 : }
224 :
225 : NS_IMETHODIMP
226 0 : nsViewSourceChannel::GetURI(nsIURI* *aURI)
227 : {
228 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
229 :
230 0 : nsCOMPtr<nsIURI> uri;
231 0 : nsresult rv = mChannel->GetURI(getter_AddRefs(uri));
232 0 : if (NS_FAILED(rv))
233 0 : return rv;
234 :
235 : // protect ourselves against broken channel implementations
236 0 : if (!uri) {
237 0 : NS_ERROR("inner channel returned NS_OK and a null URI");
238 0 : return NS_ERROR_UNEXPECTED;
239 : }
240 :
241 0 : nsAutoCString spec;
242 0 : rv = uri->GetSpec(spec);
243 0 : if (NS_FAILED(rv)) {
244 0 : return rv;
245 : }
246 :
247 : /* XXX Gross hack -- NS_NewURI goes into an infinite loop on
248 : non-flat specs. See bug 136980 */
249 0 : return NS_NewURI(aURI, nsAutoCString(NS_LITERAL_CSTRING("view-source:")+spec), nullptr);
250 : }
251 :
252 : NS_IMETHODIMP
253 0 : nsViewSourceChannel::Open(nsIInputStream **_retval)
254 : {
255 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
256 :
257 0 : nsresult rv = NS_MaybeOpenChannelUsingOpen2(mChannel, _retval);
258 0 : if (NS_SUCCEEDED(rv)) {
259 0 : mOpened = true;
260 : }
261 0 : return rv;
262 : }
263 :
264 : NS_IMETHODIMP
265 0 : nsViewSourceChannel::Open2(nsIInputStream** aStream)
266 : {
267 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
268 0 : nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
269 0 : if(!loadInfo) {
270 0 : MOZ_ASSERT(loadInfo, "can not enforce security without loadInfo");
271 0 : return NS_ERROR_UNEXPECTED;
272 : }
273 : // setting the flag on the loadInfo indicates that the underlying
274 : // channel will be openend using Open2() and hence performs
275 : // the necessary security checks.
276 0 : loadInfo->SetEnforceSecurity(true);
277 0 : return Open(aStream);
278 : }
279 :
280 : NS_IMETHODIMP
281 0 : nsViewSourceChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
282 : {
283 : #ifdef DEBUG
284 : {
285 0 : nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
286 0 : MOZ_ASSERT(!loadInfo || loadInfo->GetSecurityMode() == 0 ||
287 : loadInfo->GetEnforceSecurity(),
288 : "security flags in loadInfo but asyncOpen2() not called");
289 : }
290 : #endif
291 :
292 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
293 :
294 0 : mListener = aListener;
295 :
296 : /*
297 : * We want to add ourselves to the loadgroup before opening
298 : * mChannel, since we want to make sure we're in the loadgroup
299 : * when mChannel finishes and fires OnStopRequest()
300 : */
301 :
302 0 : nsCOMPtr<nsILoadGroup> loadGroup;
303 0 : mChannel->GetLoadGroup(getter_AddRefs(loadGroup));
304 0 : if (loadGroup)
305 0 : loadGroup->AddRequest(static_cast<nsIViewSourceChannel*>
306 0 : (this), nullptr);
307 :
308 0 : nsresult rv = NS_OK;
309 0 : nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
310 0 : if (loadInfo && loadInfo->GetEnforceSecurity()) {
311 0 : rv = mChannel->AsyncOpen2(this);
312 : }
313 : else {
314 0 : rv = mChannel->AsyncOpen(this, ctxt);
315 : }
316 :
317 0 : if (NS_FAILED(rv) && loadGroup)
318 0 : loadGroup->RemoveRequest(static_cast<nsIViewSourceChannel*>
319 : (this),
320 0 : nullptr, rv);
321 :
322 0 : if (NS_SUCCEEDED(rv)) {
323 0 : mOpened = true;
324 : }
325 :
326 0 : return rv;
327 : }
328 :
329 : NS_IMETHODIMP
330 0 : nsViewSourceChannel::AsyncOpen2(nsIStreamListener *aListener)
331 : {
332 0 : nsCOMPtr<nsILoadInfo> loadInfo = mChannel->GetLoadInfo();
333 0 : if(!loadInfo) {
334 0 : MOZ_ASSERT(loadInfo, "can not enforce security without loadInfo");
335 0 : return NS_ERROR_UNEXPECTED;
336 : }
337 : // setting the flag on the loadInfo indicates that the underlying
338 : // channel will be openend using AsyncOpen2() and hence performs
339 : // the necessary security checks.
340 0 : loadInfo->SetEnforceSecurity(true);
341 0 : return AsyncOpen(aListener, nullptr);
342 : }
343 : /*
344 : * Both the view source channel and mChannel are added to the
345 : * loadgroup. There should never be more than one request in the
346 : * loadgroup that has LOAD_DOCUMENT_URI set. The one that has this
347 : * flag set is the request whose URI is used to refetch the document,
348 : * so it better be the viewsource channel.
349 : *
350 : * Therefore, we need to make sure that
351 : * 1) The load flags on mChannel _never_ include LOAD_DOCUMENT_URI
352 : * 2) The load flags on |this| include LOAD_DOCUMENT_URI when it was
353 : * set via SetLoadFlags (mIsDocument keeps track of this flag).
354 : */
355 :
356 : NS_IMETHODIMP
357 0 : nsViewSourceChannel::GetLoadFlags(uint32_t *aLoadFlags)
358 : {
359 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
360 :
361 0 : nsresult rv = mChannel->GetLoadFlags(aLoadFlags);
362 0 : if (NS_FAILED(rv))
363 0 : return rv;
364 :
365 : // This should actually be just LOAD_DOCUMENT_URI but the win32 compiler
366 : // fails to deal due to amiguous inheritance. nsIChannel::LOAD_DOCUMENT_URI
367 : // also fails; the Win32 compiler thinks that's supposed to be a method.
368 0 : if (mIsDocument)
369 0 : *aLoadFlags |= ::nsIChannel::LOAD_DOCUMENT_URI;
370 :
371 0 : return rv;
372 : }
373 :
374 : NS_IMETHODIMP
375 0 : nsViewSourceChannel::SetLoadFlags(uint32_t aLoadFlags)
376 : {
377 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
378 :
379 : // "View source" always wants the currently cached content.
380 : // We also want to have _this_ channel, not mChannel to be the
381 : // 'document' channel in the loadgroup.
382 :
383 : // These should actually be just LOAD_FROM_CACHE and LOAD_DOCUMENT_URI but
384 : // the win32 compiler fails to deal due to amiguous inheritance.
385 : // nsIChannel::LOAD_DOCUMENT_URI/nsIRequest::LOAD_FROM_CACHE also fails; the
386 : // Win32 compiler thinks that's supposed to be a method.
387 0 : mIsDocument = (aLoadFlags & ::nsIChannel::LOAD_DOCUMENT_URI) ? true : false;
388 :
389 0 : nsresult rv = mChannel->SetLoadFlags((aLoadFlags |
390 0 : ::nsIRequest::LOAD_FROM_CACHE) &
391 0 : ~::nsIChannel::LOAD_DOCUMENT_URI);
392 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
393 0 : return rv;
394 : }
395 :
396 0 : if (mHttpChannel) {
397 0 : rv = mHttpChannel->SetIsMainDocumentChannel(aLoadFlags & ::nsIChannel::LOAD_DOCUMENT_URI);
398 0 : MOZ_ASSERT(NS_SUCCEEDED(rv));
399 : }
400 :
401 0 : return NS_OK;
402 : }
403 :
404 : NS_IMETHODIMP
405 0 : nsViewSourceChannel::GetContentType(nsACString &aContentType)
406 : {
407 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
408 :
409 0 : aContentType.Truncate();
410 :
411 0 : if (mContentType.IsEmpty())
412 : {
413 : // Get the current content type
414 : nsresult rv;
415 0 : nsAutoCString contentType;
416 0 : rv = mChannel->GetContentType(contentType);
417 0 : if (NS_FAILED(rv)) return rv;
418 :
419 : // If we don't know our type, just say so. The unknown
420 : // content decoder will then kick in automatically, and it
421 : // will call our SetOriginalContentType method instead of our
422 : // SetContentType method to set the type it determines.
423 0 : if (!contentType.Equals(UNKNOWN_CONTENT_TYPE)) {
424 0 : contentType = VIEWSOURCE_CONTENT_TYPE;
425 : }
426 :
427 0 : mContentType = contentType;
428 : }
429 :
430 0 : aContentType = mContentType;
431 0 : return NS_OK;
432 : }
433 :
434 : NS_IMETHODIMP
435 0 : nsViewSourceChannel::SetContentType(const nsACString &aContentType)
436 : {
437 : // Our GetContentType() currently returns VIEWSOURCE_CONTENT_TYPE
438 : //
439 : // However, during the parsing phase the parser calls our
440 : // channel's GetContentType(). Returning the string above trips up
441 : // the parser. In order to avoid messy changes and not to have the
442 : // parser depend on nsIViewSourceChannel Vidur proposed the
443 : // following solution:
444 : //
445 : // The ViewSourceChannel initially returns a content type of
446 : // VIEWSOURCE_CONTENT_TYPE. Based on this type decisions to
447 : // create a viewer for doing a view source are made. After the
448 : // viewer is created, nsLayoutDLF::CreateInstance() calls this
449 : // SetContentType() with the original content type. When it's
450 : // time for the parser to find out the content type it will call
451 : // our channel's GetContentType() and it will get the original
452 : // content type, such as, text/html and everything is kosher from
453 : // then on.
454 :
455 0 : if (!mOpened) {
456 : // We do not take hints
457 0 : return NS_ERROR_NOT_AVAILABLE;
458 : }
459 :
460 0 : mContentType = aContentType;
461 0 : return NS_OK;
462 : }
463 :
464 : NS_IMETHODIMP
465 0 : nsViewSourceChannel::GetContentCharset(nsACString &aContentCharset)
466 : {
467 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
468 :
469 0 : return mChannel->GetContentCharset(aContentCharset);
470 : }
471 :
472 : NS_IMETHODIMP
473 0 : nsViewSourceChannel::SetContentCharset(const nsACString &aContentCharset)
474 : {
475 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
476 :
477 0 : return mChannel->SetContentCharset(aContentCharset);
478 : }
479 :
480 : // We don't forward these methods becacuse content-disposition isn't whitelisted
481 : // (see GetResponseHeader/VisitResponseHeaders).
482 : NS_IMETHODIMP
483 0 : nsViewSourceChannel::GetContentDisposition(uint32_t *aContentDisposition)
484 : {
485 0 : return NS_ERROR_NOT_AVAILABLE;
486 : }
487 :
488 : NS_IMETHODIMP
489 0 : nsViewSourceChannel::SetContentDisposition(uint32_t aContentDisposition)
490 : {
491 0 : return NS_ERROR_NOT_AVAILABLE;
492 : }
493 :
494 : NS_IMETHODIMP
495 0 : nsViewSourceChannel::GetContentDispositionFilename(nsAString &aContentDispositionFilename)
496 : {
497 0 : return NS_ERROR_NOT_AVAILABLE;
498 : }
499 :
500 : NS_IMETHODIMP
501 0 : nsViewSourceChannel::SetContentDispositionFilename(const nsAString &aContentDispositionFilename)
502 : {
503 0 : return NS_ERROR_NOT_AVAILABLE;
504 : }
505 :
506 : NS_IMETHODIMP
507 0 : nsViewSourceChannel::GetContentDispositionHeader(nsACString &aContentDispositionHeader)
508 : {
509 0 : return NS_ERROR_NOT_AVAILABLE;
510 : }
511 :
512 : NS_IMETHODIMP
513 0 : nsViewSourceChannel::GetContentLength(int64_t *aContentLength)
514 : {
515 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
516 :
517 0 : return mChannel->GetContentLength(aContentLength);
518 : }
519 :
520 : NS_IMETHODIMP
521 0 : nsViewSourceChannel::SetContentLength(int64_t aContentLength)
522 : {
523 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
524 :
525 0 : return mChannel->SetContentLength(aContentLength);
526 : }
527 :
528 : NS_IMETHODIMP
529 0 : nsViewSourceChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
530 : {
531 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
532 :
533 0 : return mChannel->GetLoadGroup(aLoadGroup);
534 : }
535 :
536 : NS_IMETHODIMP
537 0 : nsViewSourceChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
538 : {
539 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
540 :
541 0 : return mChannel->SetLoadGroup(aLoadGroup);
542 : }
543 :
544 : NS_IMETHODIMP
545 0 : nsViewSourceChannel::GetOwner(nsISupports* *aOwner)
546 : {
547 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
548 :
549 0 : return mChannel->GetOwner(aOwner);
550 : }
551 :
552 : NS_IMETHODIMP
553 0 : nsViewSourceChannel::SetOwner(nsISupports* aOwner)
554 : {
555 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
556 :
557 0 : return mChannel->SetOwner(aOwner);
558 : }
559 :
560 : NS_IMETHODIMP
561 0 : nsViewSourceChannel::GetLoadInfo(nsILoadInfo* *aLoadInfo)
562 : {
563 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
564 :
565 0 : return mChannel->GetLoadInfo(aLoadInfo);
566 : }
567 :
568 : NS_IMETHODIMP
569 0 : nsViewSourceChannel::SetLoadInfo(nsILoadInfo* aLoadInfo)
570 : {
571 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
572 :
573 0 : return mChannel->SetLoadInfo(aLoadInfo);
574 : }
575 :
576 : NS_IMETHODIMP
577 0 : nsViewSourceChannel::GetIsDocument(bool *aIsDocument)
578 : {
579 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
580 :
581 0 : return mChannel->GetIsDocument(aIsDocument);
582 : }
583 :
584 : NS_IMETHODIMP
585 0 : nsViewSourceChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
586 : {
587 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
588 :
589 0 : return mChannel->GetNotificationCallbacks(aNotificationCallbacks);
590 : }
591 :
592 : NS_IMETHODIMP
593 0 : nsViewSourceChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
594 : {
595 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
596 :
597 0 : return mChannel->SetNotificationCallbacks(aNotificationCallbacks);
598 : }
599 :
600 : NS_IMETHODIMP
601 0 : nsViewSourceChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
602 : {
603 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
604 :
605 0 : return mChannel->GetSecurityInfo(aSecurityInfo);
606 : }
607 :
608 : // nsIViewSourceChannel methods
609 : NS_IMETHODIMP
610 0 : nsViewSourceChannel::GetOriginalContentType(nsACString &aContentType)
611 : {
612 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
613 :
614 0 : return mChannel->GetContentType(aContentType);
615 : }
616 :
617 : NS_IMETHODIMP
618 0 : nsViewSourceChannel::SetOriginalContentType(const nsACString &aContentType)
619 : {
620 0 : NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
621 :
622 : // clear our cached content-type value
623 0 : mContentType.Truncate();
624 :
625 0 : return mChannel->SetContentType(aContentType);
626 : }
627 :
628 : NS_IMETHODIMP
629 0 : nsViewSourceChannel::GetIsSrcdocChannel(bool* aIsSrcdocChannel)
630 : {
631 0 : *aIsSrcdocChannel = mIsSrcdocChannel;
632 0 : return NS_OK;
633 : }
634 :
635 : NS_IMETHODIMP
636 0 : nsViewSourceChannel::GetBaseURI(nsIURI** aBaseURI)
637 : {
638 0 : if (mIsSrcdocChannel) {
639 0 : nsCOMPtr<nsIInputStreamChannel> isc = do_QueryInterface(mChannel);
640 0 : if (isc) {
641 0 : return isc->GetBaseURI(aBaseURI);
642 : }
643 : }
644 0 : *aBaseURI = mBaseURI;
645 0 : NS_IF_ADDREF(*aBaseURI);
646 0 : return NS_OK;
647 : }
648 :
649 : NS_IMETHODIMP
650 0 : nsViewSourceChannel::SetBaseURI(nsIURI* aBaseURI)
651 : {
652 0 : mBaseURI = aBaseURI;
653 0 : return NS_OK;
654 : }
655 :
656 : NS_IMETHODIMP
657 0 : nsViewSourceChannel::GetProtocolVersion(nsACString& aProtocolVersion)
658 : {
659 0 : return NS_ERROR_NOT_IMPLEMENTED;
660 : }
661 :
662 : // nsIRequestObserver methods
663 : NS_IMETHODIMP
664 0 : nsViewSourceChannel::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
665 : {
666 0 : NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
667 : // The channel may have gotten redirected... Time to update our info
668 0 : mChannel = do_QueryInterface(aRequest);
669 0 : mHttpChannel = do_QueryInterface(aRequest);
670 0 : mCachingChannel = do_QueryInterface(aRequest);
671 0 : mCacheInfoChannel = do_QueryInterface(mChannel);
672 0 : mUploadChannel = do_QueryInterface(aRequest);
673 :
674 0 : return mListener->OnStartRequest(static_cast<nsIViewSourceChannel*>
675 : (this),
676 0 : aContext);
677 : }
678 :
679 :
680 : NS_IMETHODIMP
681 0 : nsViewSourceChannel::OnStopRequest(nsIRequest *aRequest, nsISupports* aContext,
682 : nsresult aStatus)
683 : {
684 0 : NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
685 0 : if (mChannel)
686 : {
687 0 : nsCOMPtr<nsILoadGroup> loadGroup;
688 0 : mChannel->GetLoadGroup(getter_AddRefs(loadGroup));
689 0 : if (loadGroup)
690 : {
691 0 : loadGroup->RemoveRequest(static_cast<nsIViewSourceChannel*>
692 : (this),
693 0 : nullptr, aStatus);
694 : }
695 : }
696 0 : return mListener->OnStopRequest(static_cast<nsIViewSourceChannel*>
697 : (this),
698 0 : aContext, aStatus);
699 : }
700 :
701 :
702 : // nsIStreamListener methods
703 : NS_IMETHODIMP
704 0 : nsViewSourceChannel::OnDataAvailable(nsIRequest *aRequest, nsISupports* aContext,
705 : nsIInputStream *aInputStream,
706 : uint64_t aSourceOffset,
707 : uint32_t aLength)
708 : {
709 0 : NS_ENSURE_TRUE(mListener, NS_ERROR_FAILURE);
710 0 : return mListener->OnDataAvailable(static_cast<nsIViewSourceChannel*>
711 : (this),
712 : aContext, aInputStream,
713 0 : aSourceOffset, aLength);
714 : }
715 :
716 :
717 : // nsIHttpChannel methods
718 :
719 : // We want to forward most of nsIHttpChannel over to mHttpChannel, but we want
720 : // to override GetRequestHeader and VisitHeaders. The reason is that we don't
721 : // want various headers like Link: and Refresh: applying to view-source.
722 : NS_IMETHODIMP
723 0 : nsViewSourceChannel::GetChannelId(uint64_t *aChannelId)
724 : {
725 0 : NS_ENSURE_ARG_POINTER(aChannelId);
726 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
727 0 : mHttpChannel->GetChannelId(aChannelId);
728 : }
729 :
730 : NS_IMETHODIMP
731 0 : nsViewSourceChannel::SetChannelId(uint64_t aChannelId)
732 : {
733 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
734 0 : mHttpChannel->SetChannelId(aChannelId);
735 : }
736 :
737 : NS_IMETHODIMP
738 0 : nsViewSourceChannel::GetTopLevelContentWindowId(uint64_t *aWindowId)
739 : {
740 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
741 0 : mHttpChannel->GetTopLevelContentWindowId(aWindowId);
742 : }
743 :
744 : NS_IMETHODIMP
745 0 : nsViewSourceChannel::SetTopLevelContentWindowId(uint64_t aWindowId)
746 : {
747 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
748 0 : mHttpChannel->SetTopLevelContentWindowId(aWindowId);
749 : }
750 :
751 : NS_IMETHODIMP
752 0 : nsViewSourceChannel::GetTopLevelOuterContentWindowId(uint64_t *aWindowId)
753 : {
754 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
755 0 : mHttpChannel->GetTopLevelOuterContentWindowId(aWindowId);
756 : }
757 :
758 : NS_IMETHODIMP
759 0 : nsViewSourceChannel::SetTopLevelOuterContentWindowId(uint64_t aWindowId)
760 : {
761 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
762 0 : mHttpChannel->SetTopLevelOuterContentWindowId(aWindowId);
763 : }
764 :
765 : NS_IMETHODIMP
766 0 : nsViewSourceChannel::GetIsTrackingResource(bool* aIsTrackingResource)
767 : {
768 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
769 0 : mHttpChannel->GetIsTrackingResource(aIsTrackingResource);
770 : }
771 :
772 : NS_IMETHODIMP
773 0 : nsViewSourceChannel::GetRequestMethod(nsACString & aRequestMethod)
774 : {
775 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
776 0 : mHttpChannel->GetRequestMethod(aRequestMethod);
777 : }
778 :
779 : NS_IMETHODIMP
780 0 : nsViewSourceChannel::SetRequestMethod(const nsACString & aRequestMethod)
781 : {
782 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
783 0 : mHttpChannel->SetRequestMethod(aRequestMethod);
784 : }
785 :
786 : NS_IMETHODIMP
787 0 : nsViewSourceChannel::GetReferrer(nsIURI * *aReferrer)
788 : {
789 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
790 0 : mHttpChannel->GetReferrer(aReferrer);
791 : }
792 :
793 : NS_IMETHODIMP
794 0 : nsViewSourceChannel::SetReferrer(nsIURI * aReferrer)
795 : {
796 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
797 0 : mHttpChannel->SetReferrer(aReferrer);
798 : }
799 :
800 : NS_IMETHODIMP
801 0 : nsViewSourceChannel::GetReferrerPolicy(uint32_t *aReferrerPolicy)
802 : {
803 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
804 0 : mHttpChannel->GetReferrerPolicy(aReferrerPolicy);
805 : }
806 :
807 : NS_IMETHODIMP
808 0 : nsViewSourceChannel::SetReferrerWithPolicy(nsIURI * aReferrer,
809 : uint32_t aReferrerPolicy)
810 : {
811 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
812 0 : mHttpChannel->SetReferrerWithPolicy(aReferrer, aReferrerPolicy);
813 : }
814 :
815 : NS_IMETHODIMP
816 0 : nsViewSourceChannel::GetRequestHeader(const nsACString & aHeader,
817 : nsACString & aValue)
818 : {
819 0 : aValue.Truncate();
820 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
821 0 : mHttpChannel->GetRequestHeader(aHeader, aValue);
822 : }
823 :
824 : NS_IMETHODIMP
825 0 : nsViewSourceChannel::SetRequestHeader(const nsACString & aHeader,
826 : const nsACString & aValue,
827 : bool aMerge)
828 : {
829 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
830 0 : mHttpChannel->SetRequestHeader(aHeader, aValue, aMerge);
831 : }
832 :
833 : NS_IMETHODIMP
834 0 : nsViewSourceChannel::SetEmptyRequestHeader(const nsACString & aHeader)
835 : {
836 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
837 0 : mHttpChannel->SetEmptyRequestHeader(aHeader);
838 : }
839 :
840 : NS_IMETHODIMP
841 0 : nsViewSourceChannel::VisitRequestHeaders(nsIHttpHeaderVisitor *aVisitor)
842 : {
843 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
844 0 : mHttpChannel->VisitRequestHeaders(aVisitor);
845 : }
846 :
847 : NS_IMETHODIMP
848 0 : nsViewSourceChannel::VisitNonDefaultRequestHeaders(nsIHttpHeaderVisitor *aVisitor)
849 : {
850 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
851 0 : mHttpChannel->VisitNonDefaultRequestHeaders(aVisitor);
852 : }
853 :
854 : NS_IMETHODIMP
855 0 : nsViewSourceChannel::GetAllowPipelining(bool *aAllowPipelining)
856 : {
857 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
858 0 : mHttpChannel->GetAllowPipelining(aAllowPipelining);
859 : }
860 :
861 : NS_IMETHODIMP
862 0 : nsViewSourceChannel::SetAllowPipelining(bool aAllowPipelining)
863 : {
864 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
865 0 : mHttpChannel->SetAllowPipelining(aAllowPipelining);
866 : }
867 :
868 : NS_IMETHODIMP
869 0 : nsViewSourceChannel::GetAllowSTS(bool *aAllowSTS)
870 : {
871 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
872 0 : mHttpChannel->GetAllowSTS(aAllowSTS);
873 : }
874 :
875 : NS_IMETHODIMP
876 0 : nsViewSourceChannel::SetAllowSTS(bool aAllowSTS)
877 : {
878 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
879 0 : mHttpChannel->SetAllowSTS(aAllowSTS);
880 : }
881 :
882 : NS_IMETHODIMP
883 0 : nsViewSourceChannel::GetRedirectionLimit(uint32_t *aRedirectionLimit)
884 : {
885 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
886 0 : mHttpChannel->GetRedirectionLimit(aRedirectionLimit);
887 : }
888 :
889 : NS_IMETHODIMP
890 0 : nsViewSourceChannel::SetRedirectionLimit(uint32_t aRedirectionLimit)
891 : {
892 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
893 0 : mHttpChannel->SetRedirectionLimit(aRedirectionLimit);
894 : }
895 :
896 : NS_IMETHODIMP
897 0 : nsViewSourceChannel::GetResponseStatus(uint32_t *aResponseStatus)
898 : {
899 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
900 0 : mHttpChannel->GetResponseStatus(aResponseStatus);
901 : }
902 :
903 : NS_IMETHODIMP
904 0 : nsViewSourceChannel::GetResponseStatusText(nsACString & aResponseStatusText)
905 : {
906 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
907 0 : mHttpChannel->GetResponseStatusText(aResponseStatusText);
908 : }
909 :
910 : NS_IMETHODIMP
911 0 : nsViewSourceChannel::GetRequestSucceeded(bool *aRequestSucceeded)
912 : {
913 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
914 0 : mHttpChannel->GetRequestSucceeded(aRequestSucceeded);
915 : }
916 :
917 : NS_IMETHODIMP
918 0 : nsViewSourceChannel::GetResponseHeader(const nsACString & aHeader,
919 : nsACString & aValue)
920 : {
921 0 : aValue.Truncate();
922 0 : if (!mHttpChannel)
923 0 : return NS_ERROR_NULL_POINTER;
924 :
925 0 : if (!aHeader.Equals(NS_LITERAL_CSTRING("Content-Type"),
926 0 : nsCaseInsensitiveCStringComparator()) &&
927 0 : !aHeader.Equals(NS_LITERAL_CSTRING("Content-Security-Policy"),
928 0 : nsCaseInsensitiveCStringComparator()) &&
929 0 : !aHeader.Equals(NS_LITERAL_CSTRING("Content-Security-Policy-Report-Only"),
930 0 : nsCaseInsensitiveCStringComparator()) &&
931 0 : !aHeader.Equals(NS_LITERAL_CSTRING("X-Frame-Options"),
932 0 : nsCaseInsensitiveCStringComparator())) {
933 : // We simulate the NS_ERROR_NOT_AVAILABLE error which is produced by
934 : // GetResponseHeader via nsHttpHeaderArray::GetHeader when the entry is
935 : // not present, such that it appears as though no headers except for the
936 : // whitelisted ones were set on this channel.
937 0 : return NS_ERROR_NOT_AVAILABLE;
938 : }
939 :
940 0 : return mHttpChannel->GetResponseHeader(aHeader, aValue);
941 : }
942 :
943 : NS_IMETHODIMP
944 0 : nsViewSourceChannel::SetResponseHeader(const nsACString & header,
945 : const nsACString & value, bool merge)
946 : {
947 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
948 0 : mHttpChannel->SetResponseHeader(header, value, merge);
949 : }
950 :
951 : NS_IMETHODIMP
952 0 : nsViewSourceChannel::VisitResponseHeaders(nsIHttpHeaderVisitor *aVisitor)
953 : {
954 0 : if (!mHttpChannel)
955 0 : return NS_ERROR_NULL_POINTER;
956 :
957 0 : NS_NAMED_LITERAL_CSTRING(contentTypeStr, "Content-Type");
958 0 : nsAutoCString contentType;
959 : nsresult rv =
960 0 : mHttpChannel->GetResponseHeader(contentTypeStr, contentType);
961 0 : if (NS_SUCCEEDED(rv)) {
962 0 : return aVisitor->VisitHeader(contentTypeStr, contentType);
963 : }
964 0 : return NS_OK;
965 : }
966 :
967 : NS_IMETHODIMP
968 0 : nsViewSourceChannel::GetOriginalResponseHeader(const nsACString & aHeader,
969 : nsIHttpHeaderVisitor *aVisitor)
970 : {
971 0 : nsAutoCString value;
972 0 : nsresult rv = GetResponseHeader(aHeader, value);
973 0 : if (NS_FAILED(rv)) {
974 0 : return rv;
975 : }
976 0 : return aVisitor->VisitHeader(aHeader, value);
977 : }
978 :
979 : NS_IMETHODIMP
980 0 : nsViewSourceChannel::VisitOriginalResponseHeaders(nsIHttpHeaderVisitor *aVisitor)
981 : {
982 0 : return VisitResponseHeaders(aVisitor);
983 : }
984 :
985 : NS_IMETHODIMP
986 0 : nsViewSourceChannel::IsNoStoreResponse(bool *_retval)
987 : {
988 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
989 0 : mHttpChannel->IsNoStoreResponse(_retval);
990 : }
991 :
992 : NS_IMETHODIMP
993 0 : nsViewSourceChannel::IsNoCacheResponse(bool *_retval)
994 : {
995 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
996 0 : mHttpChannel->IsNoCacheResponse(_retval);
997 : }
998 :
999 : NS_IMETHODIMP
1000 0 : nsViewSourceChannel::IsPrivateResponse(bool *_retval)
1001 : {
1002 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
1003 0 : mHttpChannel->IsPrivateResponse(_retval);
1004 : }
1005 :
1006 : NS_IMETHODIMP
1007 0 : nsViewSourceChannel::RedirectTo(nsIURI *uri)
1008 : {
1009 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
1010 0 : mHttpChannel->RedirectTo(uri);
1011 : }
1012 :
1013 : NS_IMETHODIMP
1014 0 : nsViewSourceChannel::GetRequestContextID(uint64_t *_retval)
1015 : {
1016 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
1017 0 : mHttpChannel->GetRequestContextID(_retval);
1018 : }
1019 :
1020 : NS_IMETHODIMP
1021 0 : nsViewSourceChannel::SetRequestContextID(uint64_t rcid)
1022 : {
1023 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
1024 0 : mHttpChannel->SetRequestContextID(rcid);
1025 : }
1026 :
1027 : NS_IMETHODIMP
1028 0 : nsViewSourceChannel::GetIsMainDocumentChannel(bool* aValue)
1029 : {
1030 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
1031 0 : mHttpChannel->GetIsMainDocumentChannel(aValue);
1032 : }
1033 :
1034 : NS_IMETHODIMP
1035 0 : nsViewSourceChannel::SetIsMainDocumentChannel(bool aValue)
1036 : {
1037 0 : return !mHttpChannel ? NS_ERROR_NULL_POINTER :
1038 0 : mHttpChannel->SetIsMainDocumentChannel(aValue);
1039 : }
1040 :
1041 : // Have to manually forward SetCorsPreflightParameters since it's [notxpcom]
1042 : void
1043 0 : nsViewSourceChannel::SetCorsPreflightParameters(const nsTArray<nsCString>& aUnsafeHeaders)
1044 : {
1045 0 : mHttpChannelInternal->SetCorsPreflightParameters(aUnsafeHeaders);
1046 0 : }
|