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