Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* vim:set ts=4 sw=4 sts=4 et cin: */
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 : // HttpLog.h should generally be included first
8 : #include "HttpLog.h"
9 :
10 : #include "nsNetUtil.h"
11 :
12 : #include "mozilla/Encoding.h"
13 : #include "mozilla/LoadContext.h"
14 : #include "mozilla/LoadInfo.h"
15 : #include "mozilla/BasePrincipal.h"
16 : #include "mozilla/Telemetry.h"
17 : #include "nsCategoryCache.h"
18 : #include "nsContentUtils.h"
19 : #include "nsHashKeys.h"
20 : #include "nsHttp.h"
21 : #include "nsIAsyncStreamCopier.h"
22 : #include "nsIAuthPrompt.h"
23 : #include "nsIAuthPrompt2.h"
24 : #include "nsIAuthPromptAdapterFactory.h"
25 : #include "nsIBufferedStreams.h"
26 : #include "nsIChannelEventSink.h"
27 : #include "nsIContentSniffer.h"
28 : #include "nsIDocument.h"
29 : #include "nsIDownloader.h"
30 : #include "nsIFileProtocolHandler.h"
31 : #include "nsIFileStreams.h"
32 : #include "nsIFileURL.h"
33 : #include "nsIIDNService.h"
34 : #include "nsIInputStreamChannel.h"
35 : #include "nsIInputStreamPump.h"
36 : #include "nsIInterfaceRequestorUtils.h"
37 : #include "nsILoadContext.h"
38 : #include "nsIMIMEHeaderParam.h"
39 : #include "nsIMutable.h"
40 : #include "nsINode.h"
41 : #include "nsIObjectLoadingContent.h"
42 : #include "nsIOfflineCacheUpdate.h"
43 : #include "nsIPersistentProperties2.h"
44 : #include "nsIPrivateBrowsingChannel.h"
45 : #include "nsIPropertyBag2.h"
46 : #include "nsIProtocolProxyService.h"
47 : #include "nsIRedirectChannelRegistrar.h"
48 : #include "nsIRequestObserverProxy.h"
49 : #include "nsIScriptSecurityManager.h"
50 : #include "nsISimpleStreamListener.h"
51 : #include "nsISocketProvider.h"
52 : #include "nsISocketProviderService.h"
53 : #include "nsIStandardURL.h"
54 : #include "nsIStreamLoader.h"
55 : #include "nsIIncrementalStreamLoader.h"
56 : #include "nsIStreamTransportService.h"
57 : #include "nsStringStream.h"
58 : #include "nsISyncStreamListener.h"
59 : #include "nsITransport.h"
60 : #include "nsIUnicharStreamLoader.h"
61 : #include "nsIURIWithPrincipal.h"
62 : #include "nsIURLParser.h"
63 : #include "nsIUUIDGenerator.h"
64 : #include "nsIViewSourceChannel.h"
65 : #include "nsInterfaceRequestorAgg.h"
66 : #include "plstr.h"
67 : #include "nsINestedURI.h"
68 : #include "mozilla/dom/nsCSPUtils.h"
69 : #include "mozilla/net/HttpBaseChannel.h"
70 : #include "nsIScriptError.h"
71 : #include "nsISiteSecurityService.h"
72 : #include "nsHttpHandler.h"
73 : #include "nsNSSComponent.h"
74 : #include "nsIRedirectHistoryEntry.h"
75 :
76 : #include <limits>
77 :
78 : using namespace mozilla;
79 : using namespace mozilla::net;
80 :
81 : #define DEFAULT_USER_CONTROL_RP 3
82 :
83 : static uint32_t sUserControlRp = DEFAULT_USER_CONTROL_RP;
84 :
85 : already_AddRefed<nsIIOService>
86 7090 : do_GetIOService(nsresult *error /* = 0 */)
87 : {
88 14180 : nsCOMPtr<nsIIOService> io = mozilla::services::GetIOService();
89 7090 : if (error)
90 6909 : *error = io ? NS_OK : NS_ERROR_FAILURE;
91 14180 : return io.forget();
92 : }
93 :
94 : nsresult
95 265 : NS_NewLocalFileInputStream(nsIInputStream **result,
96 : nsIFile *file,
97 : int32_t ioFlags /* = -1 */,
98 : int32_t perm /* = -1 */,
99 : int32_t behaviorFlags /* = 0 */)
100 : {
101 : nsresult rv;
102 : nsCOMPtr<nsIFileInputStream> in =
103 530 : do_CreateInstance(NS_LOCALFILEINPUTSTREAM_CONTRACTID, &rv);
104 265 : if (NS_SUCCEEDED(rv)) {
105 265 : rv = in->Init(file, ioFlags, perm, behaviorFlags);
106 265 : if (NS_SUCCEEDED(rv))
107 264 : in.forget(result);
108 : }
109 530 : return rv;
110 : }
111 :
112 : nsresult
113 6 : NS_NewLocalFileOutputStream(nsIOutputStream **result,
114 : nsIFile *file,
115 : int32_t ioFlags /* = -1 */,
116 : int32_t perm /* = -1 */,
117 : int32_t behaviorFlags /* = 0 */)
118 : {
119 : nsresult rv;
120 : nsCOMPtr<nsIFileOutputStream> out =
121 12 : do_CreateInstance(NS_LOCALFILEOUTPUTSTREAM_CONTRACTID, &rv);
122 6 : if (NS_SUCCEEDED(rv)) {
123 6 : rv = out->Init(file, ioFlags, perm, behaviorFlags);
124 6 : if (NS_SUCCEEDED(rv))
125 6 : out.forget(result);
126 : }
127 12 : return rv;
128 : }
129 :
130 : nsresult
131 6610 : net_EnsureIOService(nsIIOService **ios, nsCOMPtr<nsIIOService> &grip)
132 : {
133 6610 : nsresult rv = NS_OK;
134 6610 : if (!*ios) {
135 5271 : grip = do_GetIOService(&rv);
136 5271 : *ios = grip;
137 : }
138 6610 : return rv;
139 : }
140 :
141 : nsresult
142 1092 : NS_NewFileURI(nsIURI **result,
143 : nsIFile *spec,
144 : nsIIOService *ioService /* = nullptr */) // pass in nsIIOService to optimize callers
145 : {
146 : nsresult rv;
147 2184 : nsCOMPtr<nsIIOService> grip;
148 1092 : rv = net_EnsureIOService(&ioService, grip);
149 1092 : if (ioService)
150 1092 : rv = ioService->NewFileURI(spec, result);
151 2184 : return rv;
152 : }
153 :
154 : nsresult
155 1165 : NS_NewChannelInternal(nsIChannel **outChannel,
156 : nsIURI *aUri,
157 : nsILoadInfo *aLoadInfo,
158 : nsILoadGroup *aLoadGroup /* = nullptr */,
159 : nsIInterfaceRequestor *aCallbacks /* = nullptr */,
160 : nsLoadFlags aLoadFlags /* = nsIRequest::LOAD_NORMAL */,
161 : nsIIOService *aIoService /* = nullptr */)
162 : {
163 : // NS_NewChannelInternal is mostly called for channel redirects. We should allow
164 : // the creation of a channel even if the original channel did not have a loadinfo
165 : // attached.
166 1165 : NS_ENSURE_ARG_POINTER(outChannel);
167 :
168 2330 : nsCOMPtr<nsIIOService> grip;
169 1165 : nsresult rv = net_EnsureIOService(&aIoService, grip);
170 1165 : NS_ENSURE_SUCCESS(rv, rv);
171 :
172 2330 : nsCOMPtr<nsIChannel> channel;
173 2330 : rv = aIoService->NewChannelFromURIWithLoadInfo(
174 : aUri,
175 : aLoadInfo,
176 2330 : getter_AddRefs(channel));
177 1165 : NS_ENSURE_SUCCESS(rv, rv);
178 :
179 1165 : if (aLoadGroup) {
180 0 : rv = channel->SetLoadGroup(aLoadGroup);
181 0 : NS_ENSURE_SUCCESS(rv, rv);
182 : }
183 :
184 1165 : if (aCallbacks) {
185 6 : rv = channel->SetNotificationCallbacks(aCallbacks);
186 6 : NS_ENSURE_SUCCESS(rv, rv);
187 : }
188 :
189 : #ifdef DEBUG
190 1165 : nsLoadFlags channelLoadFlags = 0;
191 1165 : channel->GetLoadFlags(&channelLoadFlags);
192 : // Will be removed when we remove LOAD_REPLACE altogether
193 : // This check is trying to catch protocol handlers that still
194 : // try to set the LOAD_REPLACE flag.
195 1165 : MOZ_DIAGNOSTIC_ASSERT(!(channelLoadFlags & nsIChannel::LOAD_REPLACE));
196 : #endif
197 :
198 1165 : if (aLoadFlags != nsIRequest::LOAD_NORMAL) {
199 7 : rv = channel->SetLoadFlags(aLoadFlags);
200 7 : NS_ENSURE_SUCCESS(rv, rv);
201 : }
202 :
203 1165 : channel.forget(outChannel);
204 1165 : return NS_OK;
205 : }
206 :
207 : nsresult
208 1123 : NS_NewChannel(nsIChannel **outChannel,
209 : nsIURI *aUri,
210 : nsIPrincipal *aLoadingPrincipal,
211 : nsSecurityFlags aSecurityFlags,
212 : nsContentPolicyType aContentPolicyType,
213 : nsILoadGroup *aLoadGroup /* = nullptr */,
214 : nsIInterfaceRequestor *aCallbacks /* = nullptr */,
215 : nsLoadFlags aLoadFlags /* = nsIRequest::LOAD_NORMAL */,
216 : nsIIOService *aIoService /* = nullptr */)
217 : {
218 : return NS_NewChannelInternal(outChannel,
219 : aUri,
220 : nullptr, // aLoadingNode,
221 : aLoadingPrincipal,
222 : nullptr, // aTriggeringPrincipal
223 : aSecurityFlags,
224 : aContentPolicyType,
225 : aLoadGroup,
226 : aCallbacks,
227 : aLoadFlags,
228 1123 : aIoService);
229 : }
230 :
231 : nsresult
232 1177 : NS_NewChannelInternal(nsIChannel **outChannel,
233 : nsIURI *aUri,
234 : nsINode *aLoadingNode,
235 : nsIPrincipal *aLoadingPrincipal,
236 : nsIPrincipal *aTriggeringPrincipal,
237 : nsSecurityFlags aSecurityFlags,
238 : nsContentPolicyType aContentPolicyType,
239 : nsILoadGroup *aLoadGroup /* = nullptr */,
240 : nsIInterfaceRequestor *aCallbacks /* = nullptr */,
241 : nsLoadFlags aLoadFlags /* = nsIRequest::LOAD_NORMAL */,
242 : nsIIOService *aIoService /* = nullptr */)
243 : {
244 1177 : NS_ENSURE_ARG_POINTER(outChannel);
245 :
246 2354 : nsCOMPtr<nsIIOService> grip;
247 1177 : nsresult rv = net_EnsureIOService(&aIoService, grip);
248 1177 : NS_ENSURE_SUCCESS(rv, rv);
249 :
250 2354 : nsCOMPtr<nsIChannel> channel;
251 2408 : rv = aIoService->NewChannelFromURI2(
252 : aUri,
253 : aLoadingNode ?
254 54 : aLoadingNode->AsDOMNode() : nullptr,
255 : aLoadingPrincipal,
256 : aTriggeringPrincipal,
257 : aSecurityFlags,
258 : aContentPolicyType,
259 2354 : getter_AddRefs(channel));
260 1177 : if (NS_FAILED(rv)) {
261 0 : return rv;
262 : }
263 :
264 1177 : if (aLoadGroup) {
265 25 : rv = channel->SetLoadGroup(aLoadGroup);
266 25 : NS_ENSURE_SUCCESS(rv, rv);
267 : }
268 :
269 1177 : if (aCallbacks) {
270 46 : rv = channel->SetNotificationCallbacks(aCallbacks);
271 46 : NS_ENSURE_SUCCESS(rv, rv);
272 : }
273 :
274 : #ifdef DEBUG
275 1177 : nsLoadFlags channelLoadFlags = 0;
276 1177 : channel->GetLoadFlags(&channelLoadFlags);
277 : // Will be removed when we remove LOAD_REPLACE altogether
278 : // This check is trying to catch protocol handlers that still
279 : // try to set the LOAD_REPLACE flag.
280 1177 : MOZ_DIAGNOSTIC_ASSERT(!(channelLoadFlags & nsIChannel::LOAD_REPLACE));
281 : #endif
282 :
283 1177 : if (aLoadFlags != nsIRequest::LOAD_NORMAL) {
284 66 : rv = channel->SetLoadFlags(aLoadFlags);
285 66 : NS_ENSURE_SUCCESS(rv, rv);
286 : }
287 :
288 1177 : channel.forget(outChannel);
289 1177 : return NS_OK;
290 : }
291 :
292 : nsresult /*NS_NewChannelWithNodeAndTriggeringPrincipal */
293 50 : NS_NewChannelWithTriggeringPrincipal(nsIChannel **outChannel,
294 : nsIURI *aUri,
295 : nsINode *aLoadingNode,
296 : nsIPrincipal *aTriggeringPrincipal,
297 : nsSecurityFlags aSecurityFlags,
298 : nsContentPolicyType aContentPolicyType,
299 : nsILoadGroup *aLoadGroup /* = nullptr */,
300 : nsIInterfaceRequestor *aCallbacks /* = nullptr */,
301 : nsLoadFlags aLoadFlags /* = nsIRequest::LOAD_NORMAL */,
302 : nsIIOService *aIoService /* = nullptr */)
303 : {
304 50 : MOZ_ASSERT(aLoadingNode);
305 50 : NS_ASSERTION(aTriggeringPrincipal, "Can not create channel without a triggering Principal!");
306 50 : return NS_NewChannelInternal(outChannel,
307 : aUri,
308 : aLoadingNode,
309 : aLoadingNode->NodePrincipal(),
310 : aTriggeringPrincipal,
311 : aSecurityFlags,
312 : aContentPolicyType,
313 : aLoadGroup,
314 : aCallbacks,
315 : aLoadFlags,
316 50 : aIoService);
317 : }
318 :
319 : // See NS_NewChannelInternal for usage and argument description
320 : nsresult /*NS_NewChannelWithPrincipalAndTriggeringPrincipal */
321 0 : NS_NewChannelWithTriggeringPrincipal(nsIChannel **outChannel,
322 : nsIURI *aUri,
323 : nsIPrincipal *aLoadingPrincipal,
324 : nsIPrincipal *aTriggeringPrincipal,
325 : nsSecurityFlags aSecurityFlags,
326 : nsContentPolicyType aContentPolicyType,
327 : nsILoadGroup *aLoadGroup /* = nullptr */,
328 : nsIInterfaceRequestor *aCallbacks /* = nullptr */,
329 : nsLoadFlags aLoadFlags /* = nsIRequest::LOAD_NORMAL */,
330 : nsIIOService *aIoService /* = nullptr */)
331 : {
332 0 : NS_ASSERTION(aLoadingPrincipal, "Can not create channel without a loading Principal!");
333 : return NS_NewChannelInternal(outChannel,
334 : aUri,
335 : nullptr, // aLoadingNode
336 : aLoadingPrincipal,
337 : aTriggeringPrincipal,
338 : aSecurityFlags,
339 : aContentPolicyType,
340 : aLoadGroup,
341 : aCallbacks,
342 : aLoadFlags,
343 0 : aIoService);
344 : }
345 :
346 : nsresult /* NS_NewChannelNode */
347 4 : NS_NewChannel(nsIChannel **outChannel,
348 : nsIURI *aUri,
349 : nsINode *aLoadingNode,
350 : nsSecurityFlags aSecurityFlags,
351 : nsContentPolicyType aContentPolicyType,
352 : nsILoadGroup *aLoadGroup /* = nullptr */,
353 : nsIInterfaceRequestor *aCallbacks /* = nullptr */,
354 : nsLoadFlags aLoadFlags /* = nsIRequest::LOAD_NORMAL */,
355 : nsIIOService *aIoService /* = nullptr */)
356 : {
357 4 : NS_ASSERTION(aLoadingNode, "Can not create channel without a loading Node!");
358 4 : return NS_NewChannelInternal(outChannel,
359 : aUri,
360 : aLoadingNode,
361 : aLoadingNode->NodePrincipal(),
362 : nullptr, // aTriggeringPrincipal
363 : aSecurityFlags,
364 : aContentPolicyType,
365 : aLoadGroup,
366 : aCallbacks,
367 : aLoadFlags,
368 4 : aIoService);
369 : }
370 :
371 : nsresult
372 3 : NS_GetIsDocumentChannel(nsIChannel * aChannel, bool *aIsDocument)
373 : {
374 : // Check if this channel is going to be used to create a document. If it has
375 : // LOAD_DOCUMENT_URI set it is trivially creating a document. If
376 : // LOAD_HTML_OBJECT_DATA is set it may or may not be used to create a
377 : // document, depending on its MIME type.
378 :
379 3 : if (!aChannel || !aIsDocument) {
380 0 : return NS_ERROR_NULL_POINTER;
381 : }
382 3 : *aIsDocument = false;
383 : nsLoadFlags loadFlags;
384 3 : nsresult rv = aChannel->GetLoadFlags(&loadFlags);
385 3 : if (NS_FAILED(rv)) {
386 0 : return rv;
387 : }
388 3 : if (loadFlags & nsIChannel::LOAD_DOCUMENT_URI) {
389 1 : *aIsDocument = true;
390 1 : return NS_OK;
391 : }
392 2 : if (!(loadFlags & nsIRequest::LOAD_HTML_OBJECT_DATA)) {
393 2 : *aIsDocument = false;
394 2 : return NS_OK;
395 : }
396 0 : nsAutoCString mimeType;
397 0 : rv = aChannel->GetContentType(mimeType);
398 0 : if (NS_FAILED(rv)) {
399 0 : return rv;
400 : }
401 0 : if (nsContentUtils::HtmlObjectContentTypeForMIMEType(mimeType, false, nullptr) ==
402 : nsIObjectLoadingContent::TYPE_DOCUMENT) {
403 0 : *aIsDocument = true;
404 0 : return NS_OK;
405 : }
406 0 : *aIsDocument = false;
407 0 : return NS_OK;
408 : }
409 :
410 : nsresult
411 0 : NS_MakeAbsoluteURI(nsACString &result,
412 : const nsACString &spec,
413 : nsIURI *baseURI)
414 : {
415 : nsresult rv;
416 0 : if (!baseURI) {
417 0 : NS_WARNING("It doesn't make sense to not supply a base URI");
418 0 : result = spec;
419 0 : rv = NS_OK;
420 : }
421 0 : else if (spec.IsEmpty())
422 0 : rv = baseURI->GetSpec(result);
423 : else
424 0 : rv = baseURI->Resolve(spec, result);
425 0 : return rv;
426 : }
427 :
428 : nsresult
429 0 : NS_MakeAbsoluteURI(char **result,
430 : const char *spec,
431 : nsIURI *baseURI)
432 : {
433 : nsresult rv;
434 0 : nsAutoCString resultBuf;
435 0 : rv = NS_MakeAbsoluteURI(resultBuf, nsDependentCString(spec), baseURI);
436 0 : if (NS_SUCCEEDED(rv)) {
437 0 : *result = ToNewCString(resultBuf);
438 0 : if (!*result)
439 0 : rv = NS_ERROR_OUT_OF_MEMORY;
440 : }
441 0 : return rv;
442 : }
443 :
444 : nsresult
445 0 : NS_MakeAbsoluteURI(nsAString &result,
446 : const nsAString &spec,
447 : nsIURI *baseURI)
448 : {
449 : nsresult rv;
450 0 : if (!baseURI) {
451 0 : NS_WARNING("It doesn't make sense to not supply a base URI");
452 0 : result = spec;
453 0 : rv = NS_OK;
454 : }
455 : else {
456 0 : nsAutoCString resultBuf;
457 0 : if (spec.IsEmpty())
458 0 : rv = baseURI->GetSpec(resultBuf);
459 : else
460 0 : rv = baseURI->Resolve(NS_ConvertUTF16toUTF8(spec), resultBuf);
461 0 : if (NS_SUCCEEDED(rv))
462 0 : CopyUTF8toUTF16(resultBuf, result);
463 : }
464 0 : return rv;
465 : }
466 :
467 : int32_t
468 7 : NS_GetDefaultPort(const char *scheme,
469 : nsIIOService *ioService /* = nullptr */)
470 : {
471 : nsresult rv;
472 :
473 : // Getting the default port through the protocol handler has a lot of XPCOM
474 : // overhead involved. We optimize the protocols that matter for Web pages
475 : // (HTTP and HTTPS) by hardcoding their default ports here.
476 7 : if (strncmp(scheme, "http", 4) == 0) {
477 7 : if (scheme[4] == 's' && scheme[5] == '\0') {
478 0 : return 443;
479 : }
480 7 : if (scheme[4] == '\0') {
481 7 : return 80;
482 : }
483 : }
484 :
485 0 : nsCOMPtr<nsIIOService> grip;
486 0 : net_EnsureIOService(&ioService, grip);
487 0 : if (!ioService)
488 0 : return -1;
489 :
490 0 : nsCOMPtr<nsIProtocolHandler> handler;
491 0 : rv = ioService->GetProtocolHandler(scheme, getter_AddRefs(handler));
492 0 : if (NS_FAILED(rv))
493 0 : return -1;
494 : int32_t port;
495 0 : rv = handler->GetDefaultPort(&port);
496 0 : return NS_SUCCEEDED(rv) ? port : -1;
497 : }
498 :
499 : /**
500 : * This function is a helper function to apply the ToAscii conversion
501 : * to a string
502 : */
503 : bool
504 0 : NS_StringToACE(const nsACString &idn, nsACString &result)
505 : {
506 0 : nsCOMPtr<nsIIDNService> idnSrv = do_GetService(NS_IDNSERVICE_CONTRACTID);
507 0 : if (!idnSrv)
508 0 : return false;
509 0 : nsresult rv = idnSrv->ConvertUTF8toACE(idn, result);
510 0 : if (NS_FAILED(rv))
511 0 : return false;
512 :
513 0 : return true;
514 : }
515 :
516 : int32_t
517 8 : NS_GetRealPort(nsIURI *aURI)
518 : {
519 : int32_t port;
520 8 : nsresult rv = aURI->GetPort(&port);
521 8 : if (NS_FAILED(rv))
522 0 : return -1;
523 :
524 8 : if (port != -1)
525 8 : return port; // explicitly specified
526 :
527 : // Otherwise, we have to get the default port from the protocol handler
528 :
529 : // Need the scheme first
530 0 : nsAutoCString scheme;
531 0 : rv = aURI->GetScheme(scheme);
532 0 : if (NS_FAILED(rv))
533 0 : return -1;
534 :
535 0 : return NS_GetDefaultPort(scheme.get());
536 : }
537 :
538 : nsresult /* NS_NewInputStreamChannelWithLoadInfo */
539 6 : NS_NewInputStreamChannelInternal(nsIChannel **outChannel,
540 : nsIURI *aUri,
541 : nsIInputStream *aStream,
542 : const nsACString &aContentType,
543 : const nsACString &aContentCharset,
544 : nsILoadInfo *aLoadInfo)
545 : {
546 : nsresult rv;
547 : nsCOMPtr<nsIInputStreamChannel> isc =
548 12 : do_CreateInstance(NS_INPUTSTREAMCHANNEL_CONTRACTID, &rv);
549 6 : NS_ENSURE_SUCCESS(rv, rv);
550 6 : rv = isc->SetURI(aUri);
551 6 : NS_ENSURE_SUCCESS(rv, rv);
552 6 : rv = isc->SetContentStream(aStream);
553 6 : NS_ENSURE_SUCCESS(rv, rv);
554 :
555 12 : nsCOMPtr<nsIChannel> channel = do_QueryInterface(isc, &rv);
556 6 : NS_ENSURE_SUCCESS(rv, rv);
557 :
558 6 : if (!aContentType.IsEmpty()) {
559 6 : rv = channel->SetContentType(aContentType);
560 6 : NS_ENSURE_SUCCESS(rv, rv);
561 : }
562 :
563 6 : if (!aContentCharset.IsEmpty()) {
564 4 : rv = channel->SetContentCharset(aContentCharset);
565 4 : NS_ENSURE_SUCCESS(rv, rv);
566 : }
567 :
568 6 : channel->SetLoadInfo(aLoadInfo);
569 :
570 : // If we're sandboxed, make sure to clear any owner the channel
571 : // might already have.
572 6 : if (aLoadInfo && aLoadInfo->GetLoadingSandboxed()) {
573 0 : channel->SetOwner(nullptr);
574 : }
575 :
576 6 : channel.forget(outChannel);
577 6 : return NS_OK;
578 : }
579 :
580 : nsresult
581 2 : NS_NewInputStreamChannelInternal(nsIChannel **outChannel,
582 : nsIURI *aUri,
583 : nsIInputStream *aStream,
584 : const nsACString &aContentType,
585 : const nsACString &aContentCharset,
586 : nsINode *aLoadingNode,
587 : nsIPrincipal *aLoadingPrincipal,
588 : nsIPrincipal *aTriggeringPrincipal,
589 : nsSecurityFlags aSecurityFlags,
590 : nsContentPolicyType aContentPolicyType)
591 : {
592 : nsCOMPtr<nsILoadInfo> loadInfo =
593 : new mozilla::LoadInfo(aLoadingPrincipal,
594 : aTriggeringPrincipal,
595 : aLoadingNode,
596 : aSecurityFlags,
597 4 : aContentPolicyType);
598 2 : if (!loadInfo) {
599 0 : return NS_ERROR_UNEXPECTED;
600 : }
601 2 : return NS_NewInputStreamChannelInternal(outChannel,
602 : aUri,
603 : aStream,
604 : aContentType,
605 : aContentCharset,
606 2 : loadInfo);
607 : }
608 :
609 : nsresult /* NS_NewInputStreamChannelPrincipal */
610 2 : NS_NewInputStreamChannel(nsIChannel **outChannel,
611 : nsIURI *aUri,
612 : nsIInputStream *aStream,
613 : nsIPrincipal *aLoadingPrincipal,
614 : nsSecurityFlags aSecurityFlags,
615 : nsContentPolicyType aContentPolicyType,
616 : const nsACString &aContentType /* = EmptyCString() */,
617 : const nsACString &aContentCharset /* = EmptyCString() */)
618 : {
619 : return NS_NewInputStreamChannelInternal(outChannel,
620 : aUri,
621 : aStream,
622 : aContentType,
623 : aContentCharset,
624 : nullptr, // aLoadingNode
625 : aLoadingPrincipal,
626 : nullptr, // aTriggeringPrincipal
627 : aSecurityFlags,
628 2 : aContentPolicyType);
629 : }
630 :
631 : nsresult
632 0 : NS_NewInputStreamChannelInternal(nsIChannel **outChannel,
633 : nsIURI *aUri,
634 : const nsAString &aData,
635 : const nsACString &aContentType,
636 : nsILoadInfo *aLoadInfo,
637 : bool aIsSrcdocChannel /* = false */)
638 : {
639 : nsresult rv;
640 0 : nsCOMPtr<nsIStringInputStream> stream;
641 0 : stream = do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID, &rv);
642 0 : NS_ENSURE_SUCCESS(rv, rv);
643 :
644 : uint32_t len;
645 0 : char* utf8Bytes = ToNewUTF8String(aData, &len);
646 0 : rv = stream->AdoptData(utf8Bytes, len);
647 :
648 0 : nsCOMPtr<nsIChannel> channel;
649 0 : rv = NS_NewInputStreamChannelInternal(getter_AddRefs(channel),
650 : aUri,
651 : stream,
652 : aContentType,
653 0 : NS_LITERAL_CSTRING("UTF-8"),
654 0 : aLoadInfo);
655 :
656 0 : NS_ENSURE_SUCCESS(rv, rv);
657 :
658 0 : if (aIsSrcdocChannel) {
659 0 : nsCOMPtr<nsIInputStreamChannel> inStrmChan = do_QueryInterface(channel);
660 0 : NS_ENSURE_TRUE(inStrmChan, NS_ERROR_FAILURE);
661 0 : inStrmChan->SetSrcdocData(aData);
662 : }
663 0 : channel.forget(outChannel);
664 0 : return NS_OK;
665 : }
666 :
667 : nsresult
668 0 : NS_NewInputStreamChannelInternal(nsIChannel **outChannel,
669 : nsIURI *aUri,
670 : const nsAString &aData,
671 : const nsACString &aContentType,
672 : nsINode *aLoadingNode,
673 : nsIPrincipal *aLoadingPrincipal,
674 : nsIPrincipal *aTriggeringPrincipal,
675 : nsSecurityFlags aSecurityFlags,
676 : nsContentPolicyType aContentPolicyType,
677 : bool aIsSrcdocChannel /* = false */)
678 : {
679 : nsCOMPtr<nsILoadInfo> loadInfo =
680 : new mozilla::LoadInfo(aLoadingPrincipal, aTriggeringPrincipal,
681 0 : aLoadingNode, aSecurityFlags, aContentPolicyType);
682 0 : return NS_NewInputStreamChannelInternal(outChannel, aUri, aData, aContentType,
683 0 : loadInfo, aIsSrcdocChannel);
684 : }
685 :
686 : nsresult
687 0 : NS_NewInputStreamChannel(nsIChannel **outChannel,
688 : nsIURI *aUri,
689 : const nsAString &aData,
690 : const nsACString &aContentType,
691 : nsIPrincipal *aLoadingPrincipal,
692 : nsSecurityFlags aSecurityFlags,
693 : nsContentPolicyType aContentPolicyType,
694 : bool aIsSrcdocChannel /* = false */)
695 : {
696 0 : return NS_NewInputStreamChannelInternal(outChannel,
697 : aUri,
698 : aData,
699 : aContentType,
700 : nullptr, // aLoadingNode
701 : aLoadingPrincipal,
702 : nullptr, // aTriggeringPrincipal
703 : aSecurityFlags,
704 : aContentPolicyType,
705 0 : aIsSrcdocChannel);
706 : }
707 :
708 : nsresult
709 1 : NS_NewInputStreamPump(nsIInputStreamPump **result,
710 : nsIInputStream *stream,
711 : int64_t streamPos /* = int64_t(-1) */,
712 : int64_t streamLen /* = int64_t(-1) */,
713 : uint32_t segsize /* = 0 */,
714 : uint32_t segcount /* = 0 */,
715 : bool closeWhenDone /* = false */,
716 : nsIEventTarget *mainThreadTarget /* = nullptr */)
717 : {
718 : nsresult rv;
719 : nsCOMPtr<nsIInputStreamPump> pump =
720 2 : do_CreateInstance(NS_INPUTSTREAMPUMP_CONTRACTID, &rv);
721 1 : if (NS_SUCCEEDED(rv)) {
722 2 : rv = pump->Init(stream, streamPos, streamLen,
723 1 : segsize, segcount, closeWhenDone, mainThreadTarget);
724 1 : if (NS_SUCCEEDED(rv)) {
725 1 : *result = nullptr;
726 1 : pump.swap(*result);
727 : }
728 : }
729 2 : return rv;
730 : }
731 :
732 : nsresult
733 0 : NS_NewAsyncStreamCopier(nsIAsyncStreamCopier **result,
734 : nsIInputStream *source,
735 : nsIOutputStream *sink,
736 : nsIEventTarget *target,
737 : bool sourceBuffered /* = true */,
738 : bool sinkBuffered /* = true */,
739 : uint32_t chunkSize /* = 0 */,
740 : bool closeSource /* = true */,
741 : bool closeSink /* = true */)
742 : {
743 : nsresult rv;
744 : nsCOMPtr<nsIAsyncStreamCopier> copier =
745 0 : do_CreateInstance(NS_ASYNCSTREAMCOPIER_CONTRACTID, &rv);
746 0 : if (NS_SUCCEEDED(rv)) {
747 0 : rv = copier->Init(source, sink, target, sourceBuffered, sinkBuffered,
748 0 : chunkSize, closeSource, closeSink);
749 0 : if (NS_SUCCEEDED(rv)) {
750 0 : *result = nullptr;
751 0 : copier.swap(*result);
752 : }
753 : }
754 0 : return rv;
755 : }
756 :
757 : nsresult
758 8 : NS_NewLoadGroup(nsILoadGroup **result,
759 : nsIRequestObserver *obs)
760 : {
761 : nsresult rv;
762 : nsCOMPtr<nsILoadGroup> group =
763 16 : do_CreateInstance(NS_LOADGROUP_CONTRACTID, &rv);
764 8 : if (NS_SUCCEEDED(rv)) {
765 8 : rv = group->SetGroupObserver(obs);
766 8 : if (NS_SUCCEEDED(rv)) {
767 8 : *result = nullptr;
768 8 : group.swap(*result);
769 : }
770 : }
771 16 : return rv;
772 : }
773 :
774 6 : bool NS_IsReasonableHTTPHeaderValue(const nsACString &aValue)
775 : {
776 6 : return mozilla::net::nsHttp::IsReasonableHeaderValue(aValue);
777 : }
778 :
779 12 : bool NS_IsValidHTTPToken(const nsACString &aToken)
780 : {
781 12 : return mozilla::net::nsHttp::IsValidToken(aToken);
782 : }
783 :
784 : void
785 4 : NS_TrimHTTPWhitespace(const nsACString& aSource, nsACString& aDest)
786 : {
787 4 : mozilla::net::nsHttp::TrimHTTPWhitespace(aSource, aDest);
788 4 : }
789 :
790 : nsresult
791 1 : NS_NewLoadGroup(nsILoadGroup **aResult, nsIPrincipal *aPrincipal)
792 : {
793 : using mozilla::LoadContext;
794 : nsresult rv;
795 :
796 : nsCOMPtr<nsILoadGroup> group =
797 2 : do_CreateInstance(NS_LOADGROUP_CONTRACTID, &rv);
798 1 : NS_ENSURE_SUCCESS(rv, rv);
799 :
800 2 : RefPtr<LoadContext> loadContext = new LoadContext(aPrincipal);
801 1 : rv = group->SetNotificationCallbacks(loadContext);
802 1 : NS_ENSURE_SUCCESS(rv, rv);
803 :
804 1 : group.forget(aResult);
805 1 : return rv;
806 : }
807 :
808 : bool
809 23 : NS_LoadGroupMatchesPrincipal(nsILoadGroup *aLoadGroup,
810 : nsIPrincipal *aPrincipal)
811 : {
812 23 : if (!aPrincipal) {
813 0 : return false;
814 : }
815 :
816 : // If this is a null principal then the load group doesn't really matter.
817 : // The principal will not be allowed to perform any actions that actually
818 : // use the load group. Unconditionally treat null principals as a match.
819 23 : if (aPrincipal->GetIsNullPrincipal()) {
820 0 : return true;
821 : }
822 :
823 23 : if (!aLoadGroup) {
824 0 : return false;
825 : }
826 :
827 46 : nsCOMPtr<nsILoadContext> loadContext;
828 23 : NS_QueryNotificationCallbacks(nullptr, aLoadGroup, NS_GET_IID(nsILoadContext),
829 46 : getter_AddRefs(loadContext));
830 23 : NS_ENSURE_TRUE(loadContext, false);
831 :
832 : // Verify load context browser flag match the principal
833 : bool contextInIsolatedBrowser;
834 23 : nsresult rv = loadContext->GetIsInIsolatedMozBrowserElement(&contextInIsolatedBrowser);
835 23 : NS_ENSURE_SUCCESS(rv, false);
836 :
837 23 : return contextInIsolatedBrowser == aPrincipal->GetIsInIsolatedMozBrowserElement();
838 : }
839 :
840 : nsresult
841 0 : NS_NewDownloader(nsIStreamListener **result,
842 : nsIDownloadObserver *observer,
843 : nsIFile *downloadLocation /* = nullptr */)
844 : {
845 : nsresult rv;
846 : nsCOMPtr<nsIDownloader> downloader =
847 0 : do_CreateInstance(NS_DOWNLOADER_CONTRACTID, &rv);
848 0 : if (NS_SUCCEEDED(rv)) {
849 0 : rv = downloader->Init(observer, downloadLocation);
850 0 : if (NS_SUCCEEDED(rv)) {
851 0 : downloader.forget(result);
852 : }
853 : }
854 0 : return rv;
855 : }
856 :
857 : nsresult
858 4 : NS_NewIncrementalStreamLoader(nsIIncrementalStreamLoader **result,
859 : nsIIncrementalStreamLoaderObserver *observer)
860 : {
861 : nsresult rv;
862 : nsCOMPtr<nsIIncrementalStreamLoader> loader =
863 8 : do_CreateInstance(NS_INCREMENTALSTREAMLOADER_CONTRACTID, &rv);
864 4 : if (NS_SUCCEEDED(rv)) {
865 4 : rv = loader->Init(observer);
866 4 : if (NS_SUCCEEDED(rv)) {
867 4 : *result = nullptr;
868 4 : loader.swap(*result);
869 : }
870 : }
871 8 : return rv;
872 : }
873 :
874 : nsresult
875 9 : NS_NewStreamLoader(nsIStreamLoader **result,
876 : nsIStreamLoaderObserver *observer,
877 : nsIRequestObserver *requestObserver /* = nullptr */)
878 : {
879 : nsresult rv;
880 : nsCOMPtr<nsIStreamLoader> loader =
881 18 : do_CreateInstance(NS_STREAMLOADER_CONTRACTID, &rv);
882 9 : if (NS_SUCCEEDED(rv)) {
883 9 : rv = loader->Init(observer, requestObserver);
884 9 : if (NS_SUCCEEDED(rv)) {
885 9 : *result = nullptr;
886 9 : loader.swap(*result);
887 : }
888 : }
889 18 : return rv;
890 : }
891 :
892 : nsresult
893 0 : NS_NewStreamLoaderInternal(nsIStreamLoader **outStream,
894 : nsIURI *aUri,
895 : nsIStreamLoaderObserver *aObserver,
896 : nsINode *aLoadingNode,
897 : nsIPrincipal *aLoadingPrincipal,
898 : nsSecurityFlags aSecurityFlags,
899 : nsContentPolicyType aContentPolicyType,
900 : nsILoadGroup *aLoadGroup /* = nullptr */,
901 : nsIInterfaceRequestor *aCallbacks /* = nullptr */,
902 : nsLoadFlags aLoadFlags /* = nsIRequest::LOAD_NORMAL */,
903 : nsIURI *aReferrer /* = nullptr */)
904 : {
905 0 : nsCOMPtr<nsIChannel> channel;
906 0 : nsresult rv = NS_NewChannelInternal(getter_AddRefs(channel),
907 : aUri,
908 : aLoadingNode,
909 : aLoadingPrincipal,
910 : nullptr, // aTriggeringPrincipal
911 : aSecurityFlags,
912 : aContentPolicyType,
913 : aLoadGroup,
914 : aCallbacks,
915 0 : aLoadFlags);
916 :
917 0 : NS_ENSURE_SUCCESS(rv, rv);
918 0 : nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
919 0 : if (httpChannel) {
920 0 : rv = httpChannel->SetReferrer(aReferrer);
921 0 : MOZ_ASSERT(NS_SUCCEEDED(rv));
922 : }
923 0 : rv = NS_NewStreamLoader(outStream, aObserver);
924 0 : NS_ENSURE_SUCCESS(rv, rv);
925 0 : return channel->AsyncOpen2(*outStream);
926 : }
927 :
928 :
929 : nsresult /* NS_NewStreamLoaderNode */
930 0 : NS_NewStreamLoader(nsIStreamLoader **outStream,
931 : nsIURI *aUri,
932 : nsIStreamLoaderObserver *aObserver,
933 : nsINode *aLoadingNode,
934 : nsSecurityFlags aSecurityFlags,
935 : nsContentPolicyType aContentPolicyType,
936 : nsILoadGroup *aLoadGroup /* = nullptr */,
937 : nsIInterfaceRequestor *aCallbacks /* = nullptr */,
938 : nsLoadFlags aLoadFlags /* = nsIRequest::LOAD_NORMAL */,
939 : nsIURI *aReferrer /* = nullptr */)
940 : {
941 0 : NS_ASSERTION(aLoadingNode, "Can not create stream loader without a loading Node!");
942 0 : return NS_NewStreamLoaderInternal(outStream,
943 : aUri,
944 : aObserver,
945 : aLoadingNode,
946 : aLoadingNode->NodePrincipal(),
947 : aSecurityFlags,
948 : aContentPolicyType,
949 : aLoadGroup,
950 : aCallbacks,
951 : aLoadFlags,
952 0 : aReferrer);
953 : }
954 :
955 : nsresult /* NS_NewStreamLoaderPrincipal */
956 0 : NS_NewStreamLoader(nsIStreamLoader **outStream,
957 : nsIURI *aUri,
958 : nsIStreamLoaderObserver *aObserver,
959 : nsIPrincipal *aLoadingPrincipal,
960 : nsSecurityFlags aSecurityFlags,
961 : nsContentPolicyType aContentPolicyType,
962 : nsILoadGroup *aLoadGroup /* = nullptr */,
963 : nsIInterfaceRequestor *aCallbacks /* = nullptr */,
964 : nsLoadFlags aLoadFlags /* = nsIRequest::LOAD_NORMAL */,
965 : nsIURI *aReferrer /* = nullptr */)
966 : {
967 : return NS_NewStreamLoaderInternal(outStream,
968 : aUri,
969 : aObserver,
970 : nullptr, // aLoadingNode
971 : aLoadingPrincipal,
972 : aSecurityFlags,
973 : aContentPolicyType,
974 : aLoadGroup,
975 : aCallbacks,
976 : aLoadFlags,
977 0 : aReferrer);
978 : }
979 :
980 : nsresult
981 53 : NS_NewUnicharStreamLoader(nsIUnicharStreamLoader **result,
982 : nsIUnicharStreamLoaderObserver *observer)
983 : {
984 : nsresult rv;
985 : nsCOMPtr<nsIUnicharStreamLoader> loader =
986 106 : do_CreateInstance(NS_UNICHARSTREAMLOADER_CONTRACTID, &rv);
987 53 : if (NS_SUCCEEDED(rv)) {
988 53 : rv = loader->Init(observer);
989 53 : if (NS_SUCCEEDED(rv)) {
990 53 : *result = nullptr;
991 53 : loader.swap(*result);
992 : }
993 : }
994 106 : return rv;
995 : }
996 :
997 : nsresult
998 0 : NS_NewSyncStreamListener(nsIStreamListener **result,
999 : nsIInputStream **stream)
1000 : {
1001 : nsresult rv;
1002 : nsCOMPtr<nsISyncStreamListener> listener =
1003 0 : do_CreateInstance(NS_SYNCSTREAMLISTENER_CONTRACTID, &rv);
1004 0 : if (NS_SUCCEEDED(rv)) {
1005 0 : rv = listener->GetInputStream(stream);
1006 0 : if (NS_SUCCEEDED(rv)) {
1007 0 : listener.forget(result);
1008 : }
1009 : }
1010 0 : return rv;
1011 : }
1012 :
1013 : nsresult
1014 0 : NS_ImplementChannelOpen(nsIChannel *channel,
1015 : nsIInputStream **result)
1016 : {
1017 0 : nsCOMPtr<nsIStreamListener> listener;
1018 0 : nsCOMPtr<nsIInputStream> stream;
1019 0 : nsresult rv = NS_NewSyncStreamListener(getter_AddRefs(listener),
1020 0 : getter_AddRefs(stream));
1021 0 : NS_ENSURE_SUCCESS(rv, rv);
1022 :
1023 0 : rv = NS_MaybeOpenChannelUsingAsyncOpen2(channel, listener);
1024 0 : NS_ENSURE_SUCCESS(rv, rv);
1025 :
1026 : uint64_t n;
1027 : // block until the initial response is received or an error occurs.
1028 0 : rv = stream->Available(&n);
1029 0 : NS_ENSURE_SUCCESS(rv, rv);
1030 :
1031 0 : *result = nullptr;
1032 0 : stream.swap(*result);
1033 :
1034 0 : return NS_OK;
1035 : }
1036 :
1037 : nsresult
1038 0 : NS_NewRequestObserverProxy(nsIRequestObserver **result,
1039 : nsIRequestObserver *observer,
1040 : nsISupports *context)
1041 : {
1042 : nsresult rv;
1043 : nsCOMPtr<nsIRequestObserverProxy> proxy =
1044 0 : do_CreateInstance(NS_REQUESTOBSERVERPROXY_CONTRACTID, &rv);
1045 0 : if (NS_SUCCEEDED(rv)) {
1046 0 : rv = proxy->Init(observer, context);
1047 0 : if (NS_SUCCEEDED(rv)) {
1048 0 : proxy.forget(result);
1049 : }
1050 : }
1051 0 : return rv;
1052 : }
1053 :
1054 : nsresult
1055 0 : NS_NewSimpleStreamListener(nsIStreamListener **result,
1056 : nsIOutputStream *sink,
1057 : nsIRequestObserver *observer /* = nullptr */)
1058 : {
1059 : nsresult rv;
1060 : nsCOMPtr<nsISimpleStreamListener> listener =
1061 0 : do_CreateInstance(NS_SIMPLESTREAMLISTENER_CONTRACTID, &rv);
1062 0 : if (NS_SUCCEEDED(rv)) {
1063 0 : rv = listener->Init(sink, observer);
1064 0 : if (NS_SUCCEEDED(rv)) {
1065 0 : listener.forget(result);
1066 : }
1067 : }
1068 0 : return rv;
1069 : }
1070 :
1071 : nsresult
1072 8 : NS_CheckPortSafety(int32_t port,
1073 : const char *scheme,
1074 : nsIIOService *ioService /* = nullptr */)
1075 : {
1076 : nsresult rv;
1077 16 : nsCOMPtr<nsIIOService> grip;
1078 8 : rv = net_EnsureIOService(&ioService, grip);
1079 8 : if (ioService) {
1080 : bool allow;
1081 8 : rv = ioService->AllowPort(port, scheme, &allow);
1082 8 : if (NS_SUCCEEDED(rv) && !allow) {
1083 0 : NS_WARNING("port blocked");
1084 0 : rv = NS_ERROR_PORT_ACCESS_NOT_ALLOWED;
1085 : }
1086 : }
1087 16 : return rv;
1088 : }
1089 :
1090 : nsresult
1091 75 : NS_CheckPortSafety(nsIURI *uri)
1092 : {
1093 : int32_t port;
1094 75 : nsresult rv = uri->GetPort(&port);
1095 75 : if (NS_FAILED(rv) || port == -1) // port undefined or default-valued
1096 67 : return NS_OK;
1097 16 : nsAutoCString scheme;
1098 8 : uri->GetScheme(scheme);
1099 8 : return NS_CheckPortSafety(port, scheme.get());
1100 : }
1101 :
1102 : nsresult
1103 0 : NS_NewProxyInfo(const nsACString &type,
1104 : const nsACString &host,
1105 : int32_t port,
1106 : uint32_t flags,
1107 : nsIProxyInfo **result)
1108 : {
1109 : nsresult rv;
1110 : nsCOMPtr<nsIProtocolProxyService> pps =
1111 0 : do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &rv);
1112 0 : if (NS_SUCCEEDED(rv))
1113 0 : rv = pps->NewProxyInfo(type, host, port, flags, UINT32_MAX, nullptr,
1114 0 : result);
1115 0 : return rv;
1116 : }
1117 :
1118 : nsresult
1119 962 : NS_GetFileProtocolHandler(nsIFileProtocolHandler **result,
1120 : nsIIOService *ioService /* = nullptr */)
1121 : {
1122 : nsresult rv;
1123 1924 : nsCOMPtr<nsIIOService> grip;
1124 962 : rv = net_EnsureIOService(&ioService, grip);
1125 962 : if (ioService) {
1126 1924 : nsCOMPtr<nsIProtocolHandler> handler;
1127 962 : rv = ioService->GetProtocolHandler("file", getter_AddRefs(handler));
1128 962 : if (NS_SUCCEEDED(rv))
1129 962 : rv = CallQueryInterface(handler, result);
1130 : }
1131 1924 : return rv;
1132 : }
1133 :
1134 : nsresult
1135 0 : NS_GetFileFromURLSpec(const nsACString &inURL,
1136 : nsIFile **result,
1137 : nsIIOService *ioService /* = nullptr */)
1138 : {
1139 : nsresult rv;
1140 0 : nsCOMPtr<nsIFileProtocolHandler> fileHandler;
1141 0 : rv = NS_GetFileProtocolHandler(getter_AddRefs(fileHandler), ioService);
1142 0 : if (NS_SUCCEEDED(rv))
1143 0 : rv = fileHandler->GetFileFromURLSpec(inURL, result);
1144 0 : return rv;
1145 : }
1146 :
1147 : nsresult
1148 0 : NS_GetURLSpecFromFile(nsIFile *file,
1149 : nsACString &url,
1150 : nsIIOService *ioService /* = nullptr */)
1151 : {
1152 : nsresult rv;
1153 0 : nsCOMPtr<nsIFileProtocolHandler> fileHandler;
1154 0 : rv = NS_GetFileProtocolHandler(getter_AddRefs(fileHandler), ioService);
1155 0 : if (NS_SUCCEEDED(rv))
1156 0 : rv = fileHandler->GetURLSpecFromFile(file, url);
1157 0 : return rv;
1158 : }
1159 :
1160 : nsresult
1161 790 : NS_GetURLSpecFromActualFile(nsIFile *file,
1162 : nsACString &url,
1163 : nsIIOService *ioService /* = nullptr */)
1164 : {
1165 : nsresult rv;
1166 1580 : nsCOMPtr<nsIFileProtocolHandler> fileHandler;
1167 790 : rv = NS_GetFileProtocolHandler(getter_AddRefs(fileHandler), ioService);
1168 790 : if (NS_SUCCEEDED(rv))
1169 790 : rv = fileHandler->GetURLSpecFromActualFile(file, url);
1170 1580 : return rv;
1171 : }
1172 :
1173 : nsresult
1174 0 : NS_GetURLSpecFromDir(nsIFile *file,
1175 : nsACString &url,
1176 : nsIIOService *ioService /* = nullptr */)
1177 : {
1178 : nsresult rv;
1179 0 : nsCOMPtr<nsIFileProtocolHandler> fileHandler;
1180 0 : rv = NS_GetFileProtocolHandler(getter_AddRefs(fileHandler), ioService);
1181 0 : if (NS_SUCCEEDED(rv))
1182 0 : rv = fileHandler->GetURLSpecFromDir(file, url);
1183 0 : return rv;
1184 : }
1185 :
1186 : nsresult
1187 2 : NS_GetReferrerFromChannel(nsIChannel *channel,
1188 : nsIURI **referrer)
1189 : {
1190 2 : nsresult rv = NS_ERROR_NOT_AVAILABLE;
1191 2 : *referrer = nullptr;
1192 :
1193 4 : nsCOMPtr<nsIPropertyBag2> props(do_QueryInterface(channel));
1194 2 : if (props) {
1195 : // We have to check for a property on a property bag because the
1196 : // referrer may be empty for security reasons (for example, when loading
1197 : // an http page with an https referrer).
1198 8 : rv = props->GetPropertyAsInterface(NS_LITERAL_STRING("docshell.internalReferrer"),
1199 : NS_GET_IID(nsIURI),
1200 6 : reinterpret_cast<void **>(referrer));
1201 2 : if (NS_FAILED(rv))
1202 0 : *referrer = nullptr;
1203 : }
1204 :
1205 : // if that didn't work, we can still try to get the referrer from the
1206 : // nsIHttpChannel (if we can QI to it)
1207 2 : if (!(*referrer)) {
1208 4 : nsCOMPtr<nsIHttpChannel> chan(do_QueryInterface(channel));
1209 2 : if (chan) {
1210 2 : rv = chan->GetReferrer(referrer);
1211 2 : if (NS_FAILED(rv))
1212 0 : *referrer = nullptr;
1213 : }
1214 : }
1215 4 : return rv;
1216 : }
1217 :
1218 : already_AddRefed<nsINetUtil>
1219 1519 : do_GetNetUtil(nsresult *error /* = 0 */)
1220 : {
1221 3038 : nsCOMPtr<nsIIOService> io = mozilla::services::GetIOService();
1222 3038 : nsCOMPtr<nsINetUtil> util;
1223 1519 : if (io)
1224 1519 : util = do_QueryInterface(io);
1225 :
1226 1519 : if (error)
1227 1290 : *error = !!util ? NS_OK : NS_ERROR_FAILURE;
1228 3038 : return util.forget();
1229 : }
1230 :
1231 : nsresult
1232 0 : NS_ParseRequestContentType(const nsACString &rawContentType,
1233 : nsCString &contentType,
1234 : nsCString &contentCharset)
1235 : {
1236 : // contentCharset is left untouched if not present in rawContentType
1237 : nsresult rv;
1238 0 : nsCOMPtr<nsINetUtil> util = do_GetNetUtil(&rv);
1239 0 : NS_ENSURE_SUCCESS(rv, rv);
1240 0 : nsCString charset;
1241 : bool hadCharset;
1242 0 : rv = util->ParseRequestContentType(rawContentType, charset, &hadCharset,
1243 0 : contentType);
1244 0 : if (NS_SUCCEEDED(rv) && hadCharset)
1245 0 : contentCharset = charset;
1246 0 : return rv;
1247 : }
1248 :
1249 : nsresult
1250 0 : NS_ParseResponseContentType(const nsACString &rawContentType,
1251 : nsCString &contentType,
1252 : nsCString &contentCharset)
1253 : {
1254 : // contentCharset is left untouched if not present in rawContentType
1255 : nsresult rv;
1256 0 : nsCOMPtr<nsINetUtil> util = do_GetNetUtil(&rv);
1257 0 : NS_ENSURE_SUCCESS(rv, rv);
1258 0 : nsCString charset;
1259 : bool hadCharset;
1260 0 : rv = util->ParseResponseContentType(rawContentType, charset, &hadCharset,
1261 0 : contentType);
1262 0 : if (NS_SUCCEEDED(rv) && hadCharset)
1263 0 : contentCharset = charset;
1264 0 : return rv;
1265 : }
1266 :
1267 : nsresult
1268 0 : NS_ExtractCharsetFromContentType(const nsACString &rawContentType,
1269 : nsCString &contentCharset,
1270 : bool *hadCharset,
1271 : int32_t *charsetStart,
1272 : int32_t *charsetEnd)
1273 : {
1274 : // contentCharset is left untouched if not present in rawContentType
1275 : nsresult rv;
1276 0 : nsCOMPtr<nsINetUtil> util = do_GetNetUtil(&rv);
1277 0 : NS_ENSURE_SUCCESS(rv, rv);
1278 :
1279 0 : return util->ExtractCharsetFromContentType(rawContentType,
1280 : contentCharset,
1281 : charsetStart,
1282 : charsetEnd,
1283 0 : hadCharset);
1284 : }
1285 :
1286 : nsresult
1287 0 : NS_NewAtomicFileOutputStream(nsIOutputStream **result,
1288 : nsIFile *file,
1289 : int32_t ioFlags /* = -1 */,
1290 : int32_t perm /* = -1 */,
1291 : int32_t behaviorFlags /* = 0 */)
1292 : {
1293 : nsresult rv;
1294 : nsCOMPtr<nsIFileOutputStream> out =
1295 0 : do_CreateInstance(NS_ATOMICLOCALFILEOUTPUTSTREAM_CONTRACTID, &rv);
1296 0 : if (NS_SUCCEEDED(rv)) {
1297 0 : rv = out->Init(file, ioFlags, perm, behaviorFlags);
1298 0 : if (NS_SUCCEEDED(rv))
1299 0 : out.forget(result);
1300 : }
1301 0 : return rv;
1302 : }
1303 :
1304 : nsresult
1305 6 : NS_NewSafeLocalFileOutputStream(nsIOutputStream **result,
1306 : nsIFile *file,
1307 : int32_t ioFlags /* = -1 */,
1308 : int32_t perm /* = -1 */,
1309 : int32_t behaviorFlags /* = 0 */)
1310 : {
1311 : nsresult rv;
1312 : nsCOMPtr<nsIFileOutputStream> out =
1313 12 : do_CreateInstance(NS_SAFELOCALFILEOUTPUTSTREAM_CONTRACTID, &rv);
1314 6 : if (NS_SUCCEEDED(rv)) {
1315 6 : rv = out->Init(file, ioFlags, perm, behaviorFlags);
1316 6 : if (NS_SUCCEEDED(rv))
1317 6 : out.forget(result);
1318 : }
1319 12 : return rv;
1320 : }
1321 :
1322 : nsresult
1323 0 : NS_NewLocalFileStream(nsIFileStream **result,
1324 : nsIFile *file,
1325 : int32_t ioFlags /* = -1 */,
1326 : int32_t perm /* = -1 */,
1327 : int32_t behaviorFlags /* = 0 */)
1328 : {
1329 : nsresult rv;
1330 : nsCOMPtr<nsIFileStream> stream =
1331 0 : do_CreateInstance(NS_LOCALFILESTREAM_CONTRACTID, &rv);
1332 0 : if (NS_SUCCEEDED(rv)) {
1333 0 : rv = stream->Init(file, ioFlags, perm, behaviorFlags);
1334 0 : if (NS_SUCCEEDED(rv))
1335 0 : stream.forget(result);
1336 : }
1337 0 : return rv;
1338 : }
1339 :
1340 : nsresult
1341 0 : NS_BackgroundInputStream(nsIInputStream **result,
1342 : nsIInputStream *stream,
1343 : uint32_t segmentSize /* = 0 */,
1344 : uint32_t segmentCount /* = 0 */)
1345 : {
1346 : nsresult rv;
1347 : nsCOMPtr<nsIStreamTransportService> sts =
1348 0 : do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv);
1349 0 : if (NS_SUCCEEDED(rv)) {
1350 0 : nsCOMPtr<nsITransport> inTransport;
1351 0 : rv = sts->CreateInputTransport(stream, int64_t(-1), int64_t(-1),
1352 0 : true, getter_AddRefs(inTransport));
1353 0 : if (NS_SUCCEEDED(rv))
1354 0 : rv = inTransport->OpenInputStream(nsITransport::OPEN_BLOCKING,
1355 : segmentSize, segmentCount,
1356 0 : result);
1357 : }
1358 0 : return rv;
1359 : }
1360 :
1361 : nsresult
1362 0 : NS_BackgroundOutputStream(nsIOutputStream **result,
1363 : nsIOutputStream *stream,
1364 : uint32_t segmentSize /* = 0 */,
1365 : uint32_t segmentCount /* = 0 */)
1366 : {
1367 : nsresult rv;
1368 : nsCOMPtr<nsIStreamTransportService> sts =
1369 0 : do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID, &rv);
1370 0 : if (NS_SUCCEEDED(rv)) {
1371 0 : nsCOMPtr<nsITransport> inTransport;
1372 0 : rv = sts->CreateOutputTransport(stream, int64_t(-1), int64_t(-1),
1373 0 : true, getter_AddRefs(inTransport));
1374 0 : if (NS_SUCCEEDED(rv))
1375 0 : rv = inTransport->OpenOutputStream(nsITransport::OPEN_BLOCKING,
1376 : segmentSize, segmentCount,
1377 0 : result);
1378 : }
1379 0 : return rv;
1380 : }
1381 :
1382 : nsresult
1383 6 : NS_NewBufferedOutputStream(nsIOutputStream **result,
1384 : nsIOutputStream *str,
1385 : uint32_t bufferSize)
1386 : {
1387 : nsresult rv;
1388 : nsCOMPtr<nsIBufferedOutputStream> out =
1389 12 : do_CreateInstance(NS_BUFFEREDOUTPUTSTREAM_CONTRACTID, &rv);
1390 6 : if (NS_SUCCEEDED(rv)) {
1391 6 : rv = out->Init(str, bufferSize);
1392 6 : if (NS_SUCCEEDED(rv)) {
1393 6 : out.forget(result);
1394 : }
1395 : }
1396 12 : return rv;
1397 : }
1398 :
1399 : already_AddRefed<nsIOutputStream>
1400 6 : NS_BufferOutputStream(nsIOutputStream *aOutputStream,
1401 : uint32_t aBufferSize)
1402 : {
1403 6 : NS_ASSERTION(aOutputStream, "No output stream given!");
1404 :
1405 12 : nsCOMPtr<nsIOutputStream> bos;
1406 12 : nsresult rv = NS_NewBufferedOutputStream(getter_AddRefs(bos), aOutputStream,
1407 6 : aBufferSize);
1408 6 : if (NS_SUCCEEDED(rv))
1409 6 : return bos.forget();
1410 :
1411 0 : bos = aOutputStream;
1412 0 : return bos.forget();
1413 : }
1414 :
1415 : MOZ_MUST_USE nsresult
1416 101 : NS_NewBufferedInputStream(nsIInputStream **result,
1417 : nsIInputStream *str,
1418 : uint32_t bufferSize)
1419 : {
1420 : nsresult rv;
1421 : nsCOMPtr<nsIBufferedInputStream> in =
1422 202 : do_CreateInstance(NS_BUFFEREDINPUTSTREAM_CONTRACTID, &rv);
1423 101 : if (NS_SUCCEEDED(rv)) {
1424 101 : rv = in->Init(str, bufferSize);
1425 101 : if (NS_SUCCEEDED(rv)) {
1426 101 : in.forget(result);
1427 : }
1428 : }
1429 202 : return rv;
1430 : }
1431 :
1432 : already_AddRefed<nsIInputStream>
1433 54 : NS_BufferInputStream(nsIInputStream *aInputStream,
1434 : uint32_t aBufferSize)
1435 : {
1436 54 : NS_ASSERTION(aInputStream, "No input stream given!");
1437 :
1438 108 : nsCOMPtr<nsIInputStream> bis;
1439 108 : nsresult rv = NS_NewBufferedInputStream(getter_AddRefs(bis), aInputStream,
1440 54 : aBufferSize);
1441 54 : if (NS_SUCCEEDED(rv))
1442 54 : return bis.forget();
1443 :
1444 0 : bis = aInputStream;
1445 0 : return bis.forget();
1446 : }
1447 :
1448 : nsresult
1449 0 : NS_NewPostDataStream(nsIInputStream **result,
1450 : bool isFile,
1451 : const nsACString &data)
1452 : {
1453 : nsresult rv;
1454 :
1455 0 : if (isFile) {
1456 0 : nsCOMPtr<nsIFile> file;
1457 0 : nsCOMPtr<nsIInputStream> fileStream;
1458 :
1459 0 : rv = NS_NewNativeLocalFile(data, false, getter_AddRefs(file));
1460 0 : if (NS_SUCCEEDED(rv)) {
1461 0 : rv = NS_NewLocalFileInputStream(getter_AddRefs(fileStream), file);
1462 0 : if (NS_SUCCEEDED(rv)) {
1463 : // wrap the file stream with a buffered input stream
1464 0 : rv = NS_NewBufferedInputStream(result, fileStream, 8192);
1465 : }
1466 : }
1467 0 : return rv;
1468 : }
1469 :
1470 : // otherwise, create a string stream for the data (copies)
1471 : nsCOMPtr<nsIStringInputStream> stream
1472 0 : (do_CreateInstance("@mozilla.org/io/string-input-stream;1", &rv));
1473 0 : if (NS_FAILED(rv))
1474 0 : return rv;
1475 :
1476 0 : rv = stream->SetData(data.BeginReading(), data.Length());
1477 0 : if (NS_FAILED(rv))
1478 0 : return rv;
1479 :
1480 0 : stream.forget(result);
1481 0 : return NS_OK;
1482 : }
1483 :
1484 : nsresult
1485 250 : NS_ReadInputStreamToBuffer(nsIInputStream *aInputStream,
1486 : void **aDest,
1487 : uint32_t aCount)
1488 : {
1489 : nsresult rv;
1490 :
1491 250 : if (!*aDest) {
1492 0 : *aDest = malloc(aCount);
1493 0 : if (!*aDest)
1494 0 : return NS_ERROR_OUT_OF_MEMORY;
1495 : }
1496 :
1497 250 : char * p = reinterpret_cast<char*>(*aDest);
1498 : uint32_t bytesRead;
1499 250 : uint32_t totalRead = 0;
1500 : while (1) {
1501 250 : rv = aInputStream->Read(p + totalRead, aCount - totalRead, &bytesRead);
1502 250 : if (!NS_SUCCEEDED(rv))
1503 0 : return rv;
1504 250 : totalRead += bytesRead;
1505 250 : if (totalRead == aCount)
1506 250 : break;
1507 : // if Read reads 0 bytes, we've hit EOF
1508 0 : if (bytesRead == 0)
1509 0 : return NS_ERROR_UNEXPECTED;
1510 : }
1511 250 : return rv;
1512 : }
1513 :
1514 : nsresult
1515 46 : NS_ReadInputStreamToString(nsIInputStream *aInputStream,
1516 : nsACString &aDest,
1517 : uint32_t aCount)
1518 : {
1519 46 : if (!aDest.SetLength(aCount, mozilla::fallible))
1520 0 : return NS_ERROR_OUT_OF_MEMORY;
1521 46 : void* dest = aDest.BeginWriting();
1522 46 : return NS_ReadInputStreamToBuffer(aInputStream, &dest, aCount);
1523 : }
1524 :
1525 : nsresult
1526 2206 : NS_NewURI(nsIURI **result,
1527 : const nsACString &spec,
1528 : const char *charset /* = nullptr */,
1529 : nsIURI *baseURI /* = nullptr */,
1530 : nsIIOService *ioService /* = nullptr */) // pass in nsIIOService to optimize callers
1531 : {
1532 : nsresult rv;
1533 4412 : nsCOMPtr<nsIIOService> grip;
1534 2206 : rv = net_EnsureIOService(&ioService, grip);
1535 2206 : if (ioService)
1536 2206 : rv = ioService->NewURI(spec, charset, baseURI, result);
1537 4412 : return rv;
1538 : }
1539 :
1540 : nsresult
1541 82 : NS_NewURI(nsIURI **result,
1542 : const nsACString &spec,
1543 : NotNull<const Encoding*> encoding,
1544 : nsIURI *baseURI /* = nullptr */,
1545 : nsIIOService *ioService /* = nullptr */) // pass in nsIIOService to optimize callers
1546 : {
1547 164 : nsAutoCString charset;
1548 82 : encoding->Name(charset);
1549 164 : return NS_NewURI(result, spec, charset.get(), baseURI, ioService);
1550 : }
1551 :
1552 : nsresult
1553 21 : NS_NewURI(nsIURI **result,
1554 : const nsAString &spec,
1555 : const char *charset /* = nullptr */,
1556 : nsIURI *baseURI /* = nullptr */,
1557 : nsIIOService *ioService /* = nullptr */) // pass in nsIIOService to optimize callers
1558 : {
1559 21 : return NS_NewURI(result, NS_ConvertUTF16toUTF8(spec), charset, baseURI, ioService);
1560 : }
1561 :
1562 : nsresult
1563 82 : NS_NewURI(nsIURI **result,
1564 : const nsAString &spec,
1565 : NotNull<const Encoding*> encoding,
1566 : nsIURI *baseURI /* = nullptr */,
1567 : nsIIOService *ioService /* = nullptr */) // pass in nsIIOService to optimize callers
1568 : {
1569 82 : return NS_NewURI(result, NS_ConvertUTF16toUTF8(spec), encoding, baseURI, ioService);
1570 : }
1571 :
1572 : nsresult
1573 192 : NS_NewURI(nsIURI **result,
1574 : const char *spec,
1575 : nsIURI *baseURI /* = nullptr */,
1576 : nsIIOService *ioService /* = nullptr */) // pass in nsIIOService to optimize callers
1577 : {
1578 192 : return NS_NewURI(result, nsDependentCString(spec), nullptr, baseURI, ioService);
1579 : }
1580 :
1581 : nsresult
1582 0 : NS_LoadPersistentPropertiesFromURISpec(nsIPersistentProperties **outResult,
1583 : const nsACString &aSpec)
1584 : {
1585 0 : nsCOMPtr<nsIURI> uri;
1586 0 : nsresult rv = NS_NewURI(getter_AddRefs(uri), aSpec);
1587 0 : NS_ENSURE_SUCCESS(rv, rv);
1588 :
1589 0 : nsCOMPtr<nsIChannel> channel;
1590 0 : rv = NS_NewChannel(getter_AddRefs(channel),
1591 : uri,
1592 : nsContentUtils::GetSystemPrincipal(),
1593 : nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
1594 : nsIContentPolicy::TYPE_OTHER);
1595 0 : NS_ENSURE_SUCCESS(rv, rv);
1596 0 : nsCOMPtr<nsIInputStream> in;
1597 0 : rv = channel->Open2(getter_AddRefs(in));
1598 0 : NS_ENSURE_SUCCESS(rv, rv);
1599 :
1600 : nsCOMPtr<nsIPersistentProperties> properties =
1601 0 : do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID, &rv);
1602 0 : NS_ENSURE_SUCCESS(rv, rv);
1603 0 : rv = properties->Load(in);
1604 0 : NS_ENSURE_SUCCESS(rv, rv);
1605 :
1606 0 : properties.swap(*outResult);
1607 0 : return NS_OK;
1608 : }
1609 :
1610 : bool
1611 54 : NS_UsePrivateBrowsing(nsIChannel *channel)
1612 : {
1613 108 : OriginAttributes attrs;
1614 54 : bool result = NS_GetOriginAttributes(channel, attrs);
1615 54 : NS_ENSURE_TRUE(result, result);
1616 54 : return attrs.mPrivateBrowsingId > 0;
1617 : }
1618 :
1619 : bool
1620 93 : NS_GetOriginAttributes(nsIChannel *aChannel,
1621 : mozilla::OriginAttributes &aAttributes)
1622 : {
1623 186 : nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
1624 : // For some channels, they might not have loadInfo, like ExternalHelperAppParent..
1625 93 : if (loadInfo) {
1626 93 : loadInfo->GetOriginAttributes(&aAttributes);
1627 : }
1628 :
1629 93 : bool isPrivate = false;
1630 186 : nsCOMPtr<nsIPrivateBrowsingChannel> pbChannel = do_QueryInterface(aChannel);
1631 93 : if (pbChannel) {
1632 93 : nsresult rv = pbChannel->GetIsChannelPrivate(&isPrivate);
1633 93 : NS_ENSURE_SUCCESS(rv, false);
1634 : } else {
1635 : // Some channels may not implement nsIPrivateBrowsingChannel
1636 0 : nsCOMPtr<nsILoadContext> loadContext;
1637 0 : NS_QueryNotificationCallbacks(aChannel, loadContext);
1638 0 : isPrivate = loadContext && loadContext->UsePrivateBrowsing();
1639 : }
1640 93 : aAttributes.SyncAttributesWithPrivateBrowsing(isPrivate);
1641 93 : return true;
1642 : }
1643 :
1644 : bool
1645 53 : NS_HasBeenCrossOrigin(nsIChannel* aChannel, bool aReport)
1646 : {
1647 106 : nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
1648 53 : MOZ_RELEASE_ASSERT(loadInfo, "Origin tracking only works for channels created with a loadinfo");
1649 :
1650 53 : if (!loadInfo) {
1651 0 : return false;
1652 : }
1653 :
1654 : // TYPE_DOCUMENT loads have a null LoadingPrincipal and can not be cross origin.
1655 53 : if (!loadInfo->LoadingPrincipal()) {
1656 5 : return false;
1657 : }
1658 :
1659 : // Always treat tainted channels as cross-origin.
1660 48 : if (loadInfo->GetTainting() != LoadTainting::Basic) {
1661 0 : return true;
1662 : }
1663 :
1664 96 : nsCOMPtr<nsIPrincipal> loadingPrincipal = loadInfo->LoadingPrincipal();
1665 48 : uint32_t mode = loadInfo->GetSecurityMode();
1666 : bool dataInherits =
1667 48 : mode == nsILoadInfo::SEC_REQUIRE_SAME_ORIGIN_DATA_INHERITS ||
1668 54 : mode == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS ||
1669 48 : mode == nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
1670 :
1671 48 : bool aboutBlankInherits = dataInherits && loadInfo->GetAboutBlankInherits();
1672 :
1673 48 : for (nsIRedirectHistoryEntry* redirectHistoryEntry : loadInfo->RedirectChain()) {
1674 0 : nsCOMPtr<nsIPrincipal> principal;
1675 0 : redirectHistoryEntry->GetPrincipal(getter_AddRefs(principal));
1676 0 : if (!principal) {
1677 0 : return true;
1678 : }
1679 :
1680 0 : nsCOMPtr<nsIURI> uri;
1681 0 : principal->GetURI(getter_AddRefs(uri));
1682 0 : if (!uri) {
1683 0 : return true;
1684 : }
1685 :
1686 0 : if (aboutBlankInherits && NS_IsAboutBlank(uri)) {
1687 0 : continue;
1688 : }
1689 :
1690 0 : if (NS_FAILED(loadingPrincipal->CheckMayLoad(uri, aReport, dataInherits))) {
1691 0 : return true;
1692 : }
1693 : }
1694 :
1695 96 : nsCOMPtr<nsIURI> uri;
1696 48 : NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
1697 48 : if (!uri) {
1698 0 : return true;
1699 : }
1700 :
1701 48 : if (aboutBlankInherits && NS_IsAboutBlank(uri)) {
1702 0 : return false;
1703 : }
1704 :
1705 48 : return NS_FAILED(loadingPrincipal->CheckMayLoad(uri, aReport, dataInherits));
1706 : }
1707 :
1708 : bool
1709 1 : NS_ShouldCheckAppCache(nsIPrincipal *aPrincipal)
1710 : {
1711 1 : uint32_t privateBrowsingId = 0;
1712 1 : nsresult rv = aPrincipal->GetPrivateBrowsingId(&privateBrowsingId);
1713 1 : if (NS_SUCCEEDED(rv) && (privateBrowsingId > 0)) {
1714 0 : return false;
1715 : }
1716 :
1717 : nsCOMPtr<nsIOfflineCacheUpdateService> offlineService =
1718 2 : do_GetService("@mozilla.org/offlinecacheupdate-service;1");
1719 1 : if (!offlineService) {
1720 0 : return false;
1721 : }
1722 :
1723 : bool allowed;
1724 1 : rv = offlineService->OfflineAppAllowed(aPrincipal, nullptr, &allowed);
1725 1 : return NS_SUCCEEDED(rv) && allowed;
1726 : }
1727 :
1728 : void
1729 0 : NS_WrapAuthPrompt(nsIAuthPrompt *aAuthPrompt,
1730 : nsIAuthPrompt2 **aAuthPrompt2)
1731 : {
1732 : nsCOMPtr<nsIAuthPromptAdapterFactory> factory =
1733 0 : do_GetService(NS_AUTHPROMPT_ADAPTER_FACTORY_CONTRACTID);
1734 0 : if (!factory)
1735 0 : return;
1736 :
1737 0 : NS_WARNING("Using deprecated nsIAuthPrompt");
1738 0 : factory->CreateAdapter(aAuthPrompt, aAuthPrompt2);
1739 : }
1740 :
1741 : void
1742 0 : NS_QueryAuthPrompt2(nsIInterfaceRequestor *aCallbacks,
1743 : nsIAuthPrompt2 **aAuthPrompt)
1744 : {
1745 0 : CallGetInterface(aCallbacks, aAuthPrompt);
1746 0 : if (*aAuthPrompt)
1747 0 : return;
1748 :
1749 : // Maybe only nsIAuthPrompt is provided and we have to wrap it.
1750 0 : nsCOMPtr<nsIAuthPrompt> prompt(do_GetInterface(aCallbacks));
1751 0 : if (!prompt)
1752 0 : return;
1753 :
1754 0 : NS_WrapAuthPrompt(prompt, aAuthPrompt);
1755 : }
1756 :
1757 : void
1758 0 : NS_QueryAuthPrompt2(nsIChannel *aChannel,
1759 : nsIAuthPrompt2 **aAuthPrompt)
1760 : {
1761 0 : *aAuthPrompt = nullptr;
1762 :
1763 : // We want to use any auth prompt we can find on the channel's callbacks,
1764 : // and if that fails use the loadgroup's prompt (if any)
1765 : // Therefore, we can't just use NS_QueryNotificationCallbacks, because
1766 : // that would prefer a loadgroup's nsIAuthPrompt2 over a channel's
1767 : // nsIAuthPrompt.
1768 0 : nsCOMPtr<nsIInterfaceRequestor> callbacks;
1769 0 : aChannel->GetNotificationCallbacks(getter_AddRefs(callbacks));
1770 0 : if (callbacks) {
1771 0 : NS_QueryAuthPrompt2(callbacks, aAuthPrompt);
1772 0 : if (*aAuthPrompt)
1773 0 : return;
1774 : }
1775 :
1776 0 : nsCOMPtr<nsILoadGroup> group;
1777 0 : aChannel->GetLoadGroup(getter_AddRefs(group));
1778 0 : if (!group)
1779 0 : return;
1780 :
1781 0 : group->GetNotificationCallbacks(getter_AddRefs(callbacks));
1782 0 : if (!callbacks)
1783 0 : return;
1784 0 : NS_QueryAuthPrompt2(callbacks, aAuthPrompt);
1785 : }
1786 :
1787 : nsresult
1788 18 : NS_NewNotificationCallbacksAggregation(nsIInterfaceRequestor *callbacks,
1789 : nsILoadGroup *loadGroup,
1790 : nsIEventTarget *target,
1791 : nsIInterfaceRequestor **result)
1792 : {
1793 36 : nsCOMPtr<nsIInterfaceRequestor> cbs;
1794 18 : if (loadGroup)
1795 0 : loadGroup->GetNotificationCallbacks(getter_AddRefs(cbs));
1796 36 : return NS_NewInterfaceRequestorAggregation(callbacks, cbs, target, result);
1797 : }
1798 :
1799 : nsresult
1800 8 : NS_NewNotificationCallbacksAggregation(nsIInterfaceRequestor *callbacks,
1801 : nsILoadGroup *loadGroup,
1802 : nsIInterfaceRequestor **result)
1803 : {
1804 8 : return NS_NewNotificationCallbacksAggregation(callbacks, loadGroup, nullptr, result);
1805 : }
1806 :
1807 : nsresult
1808 11 : NS_DoImplGetInnermostURI(nsINestedURI *nestedURI, nsIURI **result)
1809 : {
1810 11 : NS_PRECONDITION(nestedURI, "Must have a nested URI!");
1811 11 : NS_PRECONDITION(!*result, "Must have null *result");
1812 :
1813 22 : nsCOMPtr<nsIURI> inner;
1814 11 : nsresult rv = nestedURI->GetInnerURI(getter_AddRefs(inner));
1815 11 : NS_ENSURE_SUCCESS(rv, rv);
1816 :
1817 : // We may need to loop here until we reach the innermost
1818 : // URI.
1819 22 : nsCOMPtr<nsINestedURI> nestedInner(do_QueryInterface(inner));
1820 11 : while (nestedInner) {
1821 0 : rv = nestedInner->GetInnerURI(getter_AddRefs(inner));
1822 0 : NS_ENSURE_SUCCESS(rv, rv);
1823 0 : nestedInner = do_QueryInterface(inner);
1824 : }
1825 :
1826 : // Found the innermost one if we reach here.
1827 11 : inner.swap(*result);
1828 :
1829 11 : return rv;
1830 : }
1831 :
1832 : nsresult
1833 11 : NS_ImplGetInnermostURI(nsINestedURI *nestedURI, nsIURI **result)
1834 : {
1835 : // Make it safe to use swap()
1836 11 : *result = nullptr;
1837 :
1838 11 : return NS_DoImplGetInnermostURI(nestedURI, result);
1839 : }
1840 :
1841 : nsresult
1842 337 : NS_EnsureSafeToReturn(nsIURI *uri, nsIURI **result)
1843 : {
1844 337 : NS_PRECONDITION(uri, "Must have a URI");
1845 :
1846 : // Assume mutable until told otherwise
1847 337 : bool isMutable = true;
1848 674 : nsCOMPtr<nsIMutable> mutableObj(do_QueryInterface(uri));
1849 337 : if (mutableObj) {
1850 304 : nsresult rv = mutableObj->GetMutable(&isMutable);
1851 304 : isMutable = NS_FAILED(rv) || isMutable;
1852 : }
1853 :
1854 337 : if (!isMutable) {
1855 172 : NS_ADDREF(*result = uri);
1856 172 : return NS_OK;
1857 : }
1858 :
1859 165 : nsresult rv = uri->Clone(result);
1860 165 : if (NS_SUCCEEDED(rv) && !*result) {
1861 0 : NS_ERROR("nsIURI.clone contract was violated");
1862 0 : return NS_ERROR_UNEXPECTED;
1863 : }
1864 :
1865 165 : return rv;
1866 : }
1867 :
1868 : void
1869 399 : NS_TryToSetImmutable(nsIURI *uri)
1870 : {
1871 798 : nsCOMPtr<nsIMutable> mutableObj(do_QueryInterface(uri));
1872 399 : if (mutableObj) {
1873 399 : mutableObj->SetMutable(false);
1874 : }
1875 399 : }
1876 :
1877 : already_AddRefed<nsIURI>
1878 262 : NS_TryToMakeImmutable(nsIURI *uri,
1879 : nsresult *outRv /* = nullptr */)
1880 : {
1881 : nsresult rv;
1882 524 : nsCOMPtr<nsINetUtil> util = do_GetNetUtil(&rv);
1883 :
1884 524 : nsCOMPtr<nsIURI> result;
1885 262 : if (NS_SUCCEEDED(rv)) {
1886 262 : NS_ASSERTION(util, "do_GetNetUtil lied");
1887 262 : rv = util->ToImmutableURI(uri, getter_AddRefs(result));
1888 : }
1889 :
1890 262 : if (NS_FAILED(rv)) {
1891 0 : result = uri;
1892 : }
1893 :
1894 262 : if (outRv) {
1895 0 : *outRv = rv;
1896 : }
1897 :
1898 524 : return result.forget();
1899 : }
1900 :
1901 : already_AddRefed<nsIURI>
1902 632 : NS_GetInnermostURI(nsIURI *aURI)
1903 : {
1904 632 : NS_PRECONDITION(aURI, "Must have URI");
1905 :
1906 1264 : nsCOMPtr<nsIURI> uri = aURI;
1907 :
1908 1264 : nsCOMPtr<nsINestedURI> nestedURI(do_QueryInterface(uri));
1909 632 : if (!nestedURI) {
1910 621 : return uri.forget();
1911 : }
1912 :
1913 11 : nsresult rv = nestedURI->GetInnermostURI(getter_AddRefs(uri));
1914 11 : if (NS_FAILED(rv)) {
1915 0 : return nullptr;
1916 : }
1917 :
1918 11 : return uri.forget();
1919 : }
1920 :
1921 : nsresult
1922 728 : NS_GetFinalChannelURI(nsIChannel *channel, nsIURI **uri)
1923 : {
1924 728 : *uri = nullptr;
1925 :
1926 1456 : nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
1927 728 : if (loadInfo) {
1928 1426 : nsCOMPtr<nsIURI> resultPrincipalURI;
1929 728 : loadInfo->GetResultPrincipalURI(getter_AddRefs(resultPrincipalURI));
1930 728 : if (resultPrincipalURI) {
1931 30 : resultPrincipalURI.forget(uri);
1932 30 : return NS_OK;
1933 : }
1934 : }
1935 :
1936 698 : return channel->GetOriginalURI(uri);
1937 : }
1938 :
1939 : nsresult
1940 1028 : NS_URIChainHasFlags(nsIURI *uri,
1941 : uint32_t flags,
1942 : bool *result)
1943 : {
1944 : nsresult rv;
1945 2056 : nsCOMPtr<nsINetUtil> util = do_GetNetUtil(&rv);
1946 1028 : NS_ENSURE_SUCCESS(rv, rv);
1947 :
1948 1028 : return util->URIChainHasFlags(uri, flags, result);
1949 : }
1950 :
1951 : uint32_t
1952 0 : NS_SecurityHashURI(nsIURI *aURI)
1953 : {
1954 0 : nsCOMPtr<nsIURI> baseURI = NS_GetInnermostURI(aURI);
1955 :
1956 0 : nsAutoCString scheme;
1957 0 : uint32_t schemeHash = 0;
1958 0 : if (NS_SUCCEEDED(baseURI->GetScheme(scheme)))
1959 0 : schemeHash = mozilla::HashString(scheme);
1960 :
1961 : // TODO figure out how to hash file:// URIs
1962 0 : if (scheme.EqualsLiteral("file"))
1963 0 : return schemeHash; // sad face
1964 :
1965 : #if IS_ORIGIN_IS_FULL_SPEC_DEFINED
1966 : bool hasFlag;
1967 : if (NS_FAILED(NS_URIChainHasFlags(baseURI,
1968 : nsIProtocolHandler::ORIGIN_IS_FULL_SPEC, &hasFlag)) ||
1969 : hasFlag)
1970 : {
1971 : nsAutoCString spec;
1972 : uint32_t specHash;
1973 : nsresult res = baseURI->GetSpec(spec);
1974 : if (NS_SUCCEEDED(res))
1975 : specHash = mozilla::HashString(spec);
1976 : else
1977 : specHash = static_cast<uint32_t>(res);
1978 : return specHash;
1979 : }
1980 : #endif
1981 :
1982 0 : nsAutoCString host;
1983 0 : uint32_t hostHash = 0;
1984 0 : if (NS_SUCCEEDED(baseURI->GetAsciiHost(host)))
1985 0 : hostHash = mozilla::HashString(host);
1986 :
1987 0 : return mozilla::AddToHash(schemeHash, hostHash, NS_GetRealPort(baseURI));
1988 : }
1989 :
1990 : bool
1991 89 : NS_SecurityCompareURIs(nsIURI *aSourceURI,
1992 : nsIURI *aTargetURI,
1993 : bool aStrictFileOriginPolicy)
1994 : {
1995 : // Note that this is not an Equals() test on purpose -- for URIs that don't
1996 : // support host/port, we want equality to basically be object identity, for
1997 : // security purposes. Otherwise, for example, two javascript: URIs that
1998 : // are otherwise unrelated could end up "same origin", which would be
1999 : // unfortunate.
2000 89 : if (aSourceURI && aSourceURI == aTargetURI)
2001 : {
2002 0 : return true;
2003 : }
2004 :
2005 89 : if (!aTargetURI || !aSourceURI)
2006 : {
2007 83 : return false;
2008 : }
2009 :
2010 : // If either URI is a nested URI, get the base URI
2011 12 : nsCOMPtr<nsIURI> sourceBaseURI = NS_GetInnermostURI(aSourceURI);
2012 12 : nsCOMPtr<nsIURI> targetBaseURI = NS_GetInnermostURI(aTargetURI);
2013 :
2014 : // If either uri is an nsIURIWithPrincipal
2015 12 : nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(sourceBaseURI);
2016 6 : if (uriPrinc) {
2017 0 : uriPrinc->GetPrincipalUri(getter_AddRefs(sourceBaseURI));
2018 : }
2019 :
2020 6 : uriPrinc = do_QueryInterface(targetBaseURI);
2021 6 : if (uriPrinc) {
2022 0 : uriPrinc->GetPrincipalUri(getter_AddRefs(targetBaseURI));
2023 : }
2024 :
2025 6 : if (!sourceBaseURI || !targetBaseURI)
2026 0 : return false;
2027 :
2028 : // Compare schemes
2029 12 : nsAutoCString targetScheme;
2030 6 : bool sameScheme = false;
2031 18 : if (NS_FAILED( targetBaseURI->GetScheme(targetScheme) ) ||
2032 12 : NS_FAILED( sourceBaseURI->SchemeIs(targetScheme.get(), &sameScheme) ) ||
2033 6 : !sameScheme)
2034 : {
2035 : // Not same-origin if schemes differ
2036 3 : return false;
2037 : }
2038 :
2039 : // For file scheme, reject unless the files are identical. See
2040 : // NS_RelaxStrictFileOriginPolicy for enforcing file same-origin checking
2041 3 : if (targetScheme.EqualsLiteral("file"))
2042 : {
2043 : // in traditional unsafe behavior all files are the same origin
2044 0 : if (!aStrictFileOriginPolicy)
2045 0 : return true;
2046 :
2047 0 : nsCOMPtr<nsIFileURL> sourceFileURL(do_QueryInterface(sourceBaseURI));
2048 0 : nsCOMPtr<nsIFileURL> targetFileURL(do_QueryInterface(targetBaseURI));
2049 :
2050 0 : if (!sourceFileURL || !targetFileURL)
2051 0 : return false;
2052 :
2053 0 : nsCOMPtr<nsIFile> sourceFile, targetFile;
2054 :
2055 0 : sourceFileURL->GetFile(getter_AddRefs(sourceFile));
2056 0 : targetFileURL->GetFile(getter_AddRefs(targetFile));
2057 :
2058 0 : if (!sourceFile || !targetFile)
2059 0 : return false;
2060 :
2061 : // Otherwise they had better match
2062 0 : bool filesAreEqual = false;
2063 0 : nsresult rv = sourceFile->Equals(targetFile, &filesAreEqual);
2064 0 : return NS_SUCCEEDED(rv) && filesAreEqual;
2065 : }
2066 :
2067 : #if IS_ORIGIN_IS_FULL_SPEC_DEFINED
2068 : bool hasFlag;
2069 : if (NS_FAILED(NS_URIChainHasFlags(targetBaseURI,
2070 : nsIProtocolHandler::ORIGIN_IS_FULL_SPEC, &hasFlag)) ||
2071 : hasFlag)
2072 : {
2073 : // URIs with this flag have the whole spec as a distinct trust
2074 : // domain; use the whole spec for comparison
2075 : nsAutoCString targetSpec;
2076 : nsAutoCString sourceSpec;
2077 : return ( NS_SUCCEEDED( targetBaseURI->GetSpec(targetSpec) ) &&
2078 : NS_SUCCEEDED( sourceBaseURI->GetSpec(sourceSpec) ) &&
2079 : targetSpec.Equals(sourceSpec) );
2080 : }
2081 : #endif
2082 :
2083 : // Compare hosts
2084 6 : nsAutoCString targetHost;
2085 6 : nsAutoCString sourceHost;
2086 6 : if (NS_FAILED( targetBaseURI->GetAsciiHost(targetHost) ) ||
2087 3 : NS_FAILED( sourceBaseURI->GetAsciiHost(sourceHost) ))
2088 : {
2089 0 : return false;
2090 : }
2091 :
2092 6 : nsCOMPtr<nsIStandardURL> targetURL(do_QueryInterface(targetBaseURI));
2093 6 : nsCOMPtr<nsIStandardURL> sourceURL(do_QueryInterface(sourceBaseURI));
2094 3 : if (!targetURL || !sourceURL)
2095 : {
2096 0 : return false;
2097 : }
2098 :
2099 3 : if (!targetHost.Equals(sourceHost, nsCaseInsensitiveCStringComparator() ))
2100 : {
2101 0 : return false;
2102 : }
2103 :
2104 3 : return NS_GetRealPort(targetBaseURI) == NS_GetRealPort(sourceBaseURI);
2105 : }
2106 :
2107 : bool
2108 229 : NS_URIIsLocalFile(nsIURI *aURI)
2109 : {
2110 458 : nsCOMPtr<nsINetUtil> util = do_GetNetUtil();
2111 :
2112 : bool isFile;
2113 458 : return util && NS_SUCCEEDED(util->ProtocolHasFlags(aURI,
2114 : nsIProtocolHandler::URI_IS_LOCAL_FILE,
2115 458 : &isFile)) &&
2116 458 : isFile;
2117 : }
2118 :
2119 : bool
2120 0 : NS_RelaxStrictFileOriginPolicy(nsIURI *aTargetURI,
2121 : nsIURI *aSourceURI,
2122 : bool aAllowDirectoryTarget /* = false */)
2123 : {
2124 0 : if (!NS_URIIsLocalFile(aTargetURI)) {
2125 : // This is probably not what the caller intended
2126 0 : NS_NOTREACHED("NS_RelaxStrictFileOriginPolicy called with non-file URI");
2127 0 : return false;
2128 : }
2129 :
2130 0 : if (!NS_URIIsLocalFile(aSourceURI)) {
2131 : // If the source is not also a file: uri then forget it
2132 : // (don't want resource: principals in a file: doc)
2133 : //
2134 : // note: we're not de-nesting jar: uris here, we want to
2135 : // keep archive content bottled up in its own little island
2136 0 : return false;
2137 : }
2138 :
2139 : //
2140 : // pull out the internal files
2141 : //
2142 0 : nsCOMPtr<nsIFileURL> targetFileURL(do_QueryInterface(aTargetURI));
2143 0 : nsCOMPtr<nsIFileURL> sourceFileURL(do_QueryInterface(aSourceURI));
2144 0 : nsCOMPtr<nsIFile> targetFile;
2145 0 : nsCOMPtr<nsIFile> sourceFile;
2146 : bool targetIsDir;
2147 :
2148 : // Make sure targetFile is not a directory (bug 209234)
2149 : // and that it exists w/out unescaping (bug 395343)
2150 0 : if (!sourceFileURL || !targetFileURL ||
2151 0 : NS_FAILED(targetFileURL->GetFile(getter_AddRefs(targetFile))) ||
2152 0 : NS_FAILED(sourceFileURL->GetFile(getter_AddRefs(sourceFile))) ||
2153 0 : !targetFile || !sourceFile ||
2154 0 : NS_FAILED(targetFile->Normalize()) ||
2155 : #ifndef MOZ_WIDGET_ANDROID
2156 0 : NS_FAILED(sourceFile->Normalize()) ||
2157 : #endif
2158 0 : (!aAllowDirectoryTarget &&
2159 0 : (NS_FAILED(targetFile->IsDirectory(&targetIsDir)) || targetIsDir))) {
2160 0 : return false;
2161 : }
2162 :
2163 : //
2164 : // If the file to be loaded is in a subdirectory of the source
2165 : // (or same-dir if source is not a directory) then it will
2166 : // inherit its source principal and be scriptable by that source.
2167 : //
2168 : bool sourceIsDir;
2169 0 : bool allowed = false;
2170 0 : nsresult rv = sourceFile->IsDirectory(&sourceIsDir);
2171 0 : if (NS_SUCCEEDED(rv) && sourceIsDir) {
2172 0 : rv = sourceFile->Contains(targetFile, &allowed);
2173 : } else {
2174 0 : nsCOMPtr<nsIFile> sourceParent;
2175 0 : rv = sourceFile->GetParent(getter_AddRefs(sourceParent));
2176 0 : if (NS_SUCCEEDED(rv) && sourceParent) {
2177 0 : rv = sourceParent->Equals(targetFile, &allowed);
2178 0 : if (NS_FAILED(rv) || !allowed) {
2179 0 : rv = sourceParent->Contains(targetFile, &allowed);
2180 : } else {
2181 0 : MOZ_ASSERT(aAllowDirectoryTarget,
2182 : "sourceFile->Parent == targetFile, but targetFile "
2183 : "should've been disallowed if it is a directory");
2184 : }
2185 : }
2186 : }
2187 :
2188 0 : if (NS_SUCCEEDED(rv) && allowed) {
2189 0 : return true;
2190 : }
2191 :
2192 0 : return false;
2193 : }
2194 :
2195 : bool
2196 0 : NS_IsInternalSameURIRedirect(nsIChannel *aOldChannel,
2197 : nsIChannel *aNewChannel,
2198 : uint32_t aFlags)
2199 : {
2200 0 : if (!(aFlags & nsIChannelEventSink::REDIRECT_INTERNAL)) {
2201 0 : return false;
2202 : }
2203 :
2204 0 : nsCOMPtr<nsIURI> oldURI, newURI;
2205 0 : aOldChannel->GetURI(getter_AddRefs(oldURI));
2206 0 : aNewChannel->GetURI(getter_AddRefs(newURI));
2207 :
2208 0 : if (!oldURI || !newURI) {
2209 0 : return false;
2210 : }
2211 :
2212 : bool res;
2213 0 : return NS_SUCCEEDED(oldURI->Equals(newURI, &res)) && res;
2214 : }
2215 :
2216 : bool
2217 0 : NS_IsHSTSUpgradeRedirect(nsIChannel *aOldChannel,
2218 : nsIChannel *aNewChannel,
2219 : uint32_t aFlags)
2220 : {
2221 0 : if (!(aFlags & nsIChannelEventSink::REDIRECT_STS_UPGRADE)) {
2222 0 : return false;
2223 : }
2224 :
2225 0 : nsCOMPtr<nsIURI> oldURI, newURI;
2226 0 : aOldChannel->GetURI(getter_AddRefs(oldURI));
2227 0 : aNewChannel->GetURI(getter_AddRefs(newURI));
2228 :
2229 0 : if (!oldURI || !newURI) {
2230 0 : return false;
2231 : }
2232 :
2233 : bool isHttp;
2234 0 : if (NS_FAILED(oldURI->SchemeIs("http", &isHttp)) || !isHttp) {
2235 0 : return false;
2236 : }
2237 :
2238 0 : nsCOMPtr<nsIURI> upgradedURI;
2239 0 : nsresult rv = NS_GetSecureUpgradedURI(oldURI, getter_AddRefs(upgradedURI));
2240 0 : if (NS_FAILED(rv)) {
2241 0 : return false;
2242 : }
2243 :
2244 : bool res;
2245 0 : return NS_SUCCEEDED(upgradedURI->Equals(newURI, &res)) && res;
2246 : }
2247 :
2248 : nsresult
2249 0 : NS_LinkRedirectChannels(uint32_t channelId,
2250 : nsIParentChannel *parentChannel,
2251 : nsIChannel **_result)
2252 : {
2253 : nsresult rv;
2254 :
2255 : nsCOMPtr<nsIRedirectChannelRegistrar> registrar =
2256 0 : do_GetService("@mozilla.org/redirectchannelregistrar;1", &rv);
2257 0 : NS_ENSURE_SUCCESS(rv, rv);
2258 :
2259 0 : return registrar->LinkChannels(channelId,
2260 : parentChannel,
2261 0 : _result);
2262 : }
2263 :
2264 : #define NS_FAKE_SCHEME "http://"
2265 : #define NS_FAKE_TLD ".invalid"
2266 0 : nsresult NS_MakeRandomInvalidURLString(nsCString &result)
2267 : {
2268 : nsresult rv;
2269 : nsCOMPtr<nsIUUIDGenerator> uuidgen =
2270 0 : do_GetService("@mozilla.org/uuid-generator;1", &rv);
2271 0 : NS_ENSURE_SUCCESS(rv, rv);
2272 :
2273 : nsID idee;
2274 0 : rv = uuidgen->GenerateUUIDInPlace(&idee);
2275 0 : NS_ENSURE_SUCCESS(rv, rv);
2276 :
2277 : char chars[NSID_LENGTH];
2278 0 : idee.ToProvidedString(chars);
2279 :
2280 0 : result.AssignLiteral(NS_FAKE_SCHEME);
2281 : // Strip off the '{' and '}' at the beginning and end of the UUID
2282 0 : result.Append(chars + 1, NSID_LENGTH - 3);
2283 0 : result.AppendLiteral(NS_FAKE_TLD);
2284 :
2285 0 : return NS_OK;
2286 : }
2287 : #undef NS_FAKE_SCHEME
2288 : #undef NS_FAKE_TLD
2289 :
2290 0 : nsresult NS_MaybeOpenChannelUsingOpen2(nsIChannel* aChannel,
2291 : nsIInputStream **aStream)
2292 : {
2293 0 : nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
2294 0 : if (loadInfo && loadInfo->GetSecurityMode() != 0) {
2295 0 : return aChannel->Open2(aStream);
2296 : }
2297 0 : return aChannel->Open(aStream);
2298 : }
2299 :
2300 0 : nsresult NS_MaybeOpenChannelUsingAsyncOpen2(nsIChannel* aChannel,
2301 : nsIStreamListener *aListener)
2302 : {
2303 0 : nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
2304 0 : if (loadInfo && loadInfo->GetSecurityMode() != 0) {
2305 0 : return aChannel->AsyncOpen2(aListener);
2306 : }
2307 0 : return aChannel->AsyncOpen(aListener, nullptr);
2308 : }
2309 :
2310 : nsresult
2311 0 : NS_CheckIsJavaCompatibleURLString(nsCString &urlString, bool *result)
2312 : {
2313 0 : *result = false; // Default to "no"
2314 :
2315 0 : nsresult rv = NS_OK;
2316 : nsCOMPtr<nsIURLParser> urlParser =
2317 0 : do_GetService(NS_STDURLPARSER_CONTRACTID, &rv);
2318 0 : if (NS_FAILED(rv) || !urlParser)
2319 0 : return NS_ERROR_FAILURE;
2320 :
2321 0 : bool compatible = true;
2322 0 : uint32_t schemePos = 0;
2323 0 : int32_t schemeLen = 0;
2324 0 : urlParser->ParseURL(urlString.get(), -1, &schemePos, &schemeLen,
2325 0 : nullptr, nullptr, nullptr, nullptr);
2326 0 : if (schemeLen != -1) {
2327 0 : nsCString scheme;
2328 0 : scheme.Assign(urlString.get() + schemePos, schemeLen);
2329 : // By default Java only understands a small number of URL schemes, and of
2330 : // these only some can legitimately represent a browser page's "origin"
2331 : // (and be something we can legitimately expect Java to handle ... or not
2332 : // to mishandle).
2333 : //
2334 : // Besides those listed below, the OJI plugin understands the "jar",
2335 : // "mailto", "netdoc", "javascript" and "rmi" schemes, and Java Plugin2
2336 : // also understands the "about" scheme. We actually pass "about" URLs
2337 : // to Java ("about:blank" when processing a javascript: URL (one that
2338 : // calls Java) from the location bar of a blank page, and (in FF4 and up)
2339 : // "about:home" when processing a javascript: URL from the home page).
2340 : // And Java doesn't appear to mishandle them (for example it doesn't allow
2341 : // connections to "about" URLs). But it doesn't make any sense to do
2342 : // same-origin checks on "about" URLs, so we don't include them in our
2343 : // scheme whitelist.
2344 : //
2345 : // The OJI plugin doesn't understand "chrome" URLs (only Java Plugin2
2346 : // does) -- so we mustn't pass them to the OJI plugin. But we do need to
2347 : // pass "chrome" URLs to Java Plugin2: Java Plugin2 grants additional
2348 : // privileges to chrome "origins", and some extensions take advantage of
2349 : // this. For more information see bug 620773.
2350 : //
2351 : // As of FF4, we no longer support the OJI plugin.
2352 0 : if (PL_strcasecmp(scheme.get(), "http") &&
2353 0 : PL_strcasecmp(scheme.get(), "https") &&
2354 0 : PL_strcasecmp(scheme.get(), "file") &&
2355 0 : PL_strcasecmp(scheme.get(), "ftp") &&
2356 0 : PL_strcasecmp(scheme.get(), "gopher") &&
2357 0 : PL_strcasecmp(scheme.get(), "chrome"))
2358 0 : compatible = false;
2359 : } else {
2360 0 : compatible = false;
2361 : }
2362 :
2363 0 : *result = compatible;
2364 :
2365 0 : return NS_OK;
2366 : }
2367 :
2368 : /** Given the first (disposition) token from a Content-Disposition header,
2369 : * tell whether it indicates the content is inline or attachment
2370 : * @param aDispToken the disposition token from the content-disposition header
2371 : */
2372 : uint32_t
2373 0 : NS_GetContentDispositionFromToken(const nsAString &aDispToken)
2374 : {
2375 : // RFC 2183, section 2.8 says that an unknown disposition
2376 : // value should be treated as "attachment"
2377 : // If all of these tests eval to false, then we have a content-disposition of
2378 : // "attachment" or unknown
2379 0 : if (aDispToken.IsEmpty() ||
2380 0 : aDispToken.LowerCaseEqualsLiteral("inline") ||
2381 : // Broken sites just send
2382 : // Content-Disposition: filename="file"
2383 : // without a disposition token... screen those out.
2384 0 : StringHead(aDispToken, 8).LowerCaseEqualsLiteral("filename"))
2385 0 : return nsIChannel::DISPOSITION_INLINE;
2386 :
2387 0 : return nsIChannel::DISPOSITION_ATTACHMENT;
2388 : }
2389 :
2390 : uint32_t
2391 0 : NS_GetContentDispositionFromHeader(const nsACString &aHeader,
2392 : nsIChannel *aChan /* = nullptr */)
2393 : {
2394 : nsresult rv;
2395 0 : nsCOMPtr<nsIMIMEHeaderParam> mimehdrpar = do_GetService(NS_MIMEHEADERPARAM_CONTRACTID, &rv);
2396 0 : if (NS_FAILED(rv))
2397 0 : return nsIChannel::DISPOSITION_ATTACHMENT;
2398 :
2399 0 : nsAutoCString fallbackCharset;
2400 0 : if (aChan) {
2401 0 : nsCOMPtr<nsIURI> uri;
2402 0 : aChan->GetURI(getter_AddRefs(uri));
2403 0 : if (uri)
2404 0 : uri->GetOriginCharset(fallbackCharset);
2405 : }
2406 :
2407 0 : nsAutoString dispToken;
2408 0 : rv = mimehdrpar->GetParameterHTTP(aHeader, "", fallbackCharset, true, nullptr,
2409 0 : dispToken);
2410 :
2411 0 : if (NS_FAILED(rv)) {
2412 : // special case (see bug 272541): empty disposition type handled as "inline"
2413 0 : if (rv == NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY)
2414 0 : return nsIChannel::DISPOSITION_INLINE;
2415 0 : return nsIChannel::DISPOSITION_ATTACHMENT;
2416 : }
2417 :
2418 0 : return NS_GetContentDispositionFromToken(dispToken);
2419 : }
2420 :
2421 : nsresult
2422 0 : NS_GetFilenameFromDisposition(nsAString &aFilename,
2423 : const nsACString &aDisposition,
2424 : nsIURI *aURI /* = nullptr */)
2425 : {
2426 0 : aFilename.Truncate();
2427 :
2428 : nsresult rv;
2429 : nsCOMPtr<nsIMIMEHeaderParam> mimehdrpar =
2430 0 : do_GetService(NS_MIMEHEADERPARAM_CONTRACTID, &rv);
2431 0 : if (NS_FAILED(rv))
2432 0 : return rv;
2433 :
2434 0 : nsCOMPtr<nsIURL> url = do_QueryInterface(aURI);
2435 :
2436 0 : nsAutoCString fallbackCharset;
2437 0 : if (url)
2438 0 : url->GetOriginCharset(fallbackCharset);
2439 : // Get the value of 'filename' parameter
2440 0 : rv = mimehdrpar->GetParameterHTTP(aDisposition, "filename",
2441 : fallbackCharset, true, nullptr,
2442 0 : aFilename);
2443 :
2444 0 : if (NS_FAILED(rv)) {
2445 0 : aFilename.Truncate();
2446 0 : return rv;
2447 : }
2448 :
2449 0 : if (aFilename.IsEmpty())
2450 0 : return NS_ERROR_NOT_AVAILABLE;
2451 :
2452 0 : return NS_OK;
2453 : }
2454 :
2455 12 : void net_EnsurePSMInit()
2456 : {
2457 : nsresult rv;
2458 24 : nsCOMPtr<nsISupports> psm = do_GetService(PSM_COMPONENT_CONTRACTID, &rv);
2459 12 : MOZ_ASSERT(NS_SUCCEEDED(rv));
2460 12 : }
2461 :
2462 232 : bool NS_IsAboutBlank(nsIURI *uri)
2463 : {
2464 : // GetSpec can be expensive for some URIs, so check the scheme first.
2465 232 : bool isAbout = false;
2466 232 : if (NS_FAILED(uri->SchemeIs("about", &isAbout)) || !isAbout) {
2467 209 : return false;
2468 : }
2469 :
2470 23 : return uri->GetSpecOrDefault().EqualsLiteral("about:blank");
2471 : }
2472 :
2473 : nsresult
2474 18 : NS_GenerateHostPort(const nsCString& host, int32_t port,
2475 : nsACString &hostLine)
2476 : {
2477 18 : if (strchr(host.get(), ':')) {
2478 : // host is an IPv6 address literal and must be encapsulated in []'s
2479 0 : hostLine.Assign('[');
2480 : // scope id is not needed for Host header.
2481 0 : int scopeIdPos = host.FindChar('%');
2482 0 : if (scopeIdPos == -1)
2483 0 : hostLine.Append(host);
2484 0 : else if (scopeIdPos > 0)
2485 0 : hostLine.Append(Substring(host, 0, scopeIdPos));
2486 : else
2487 0 : return NS_ERROR_MALFORMED_URI;
2488 0 : hostLine.Append(']');
2489 : }
2490 : else
2491 18 : hostLine.Assign(host);
2492 18 : if (port != -1) {
2493 16 : hostLine.Append(':');
2494 16 : hostLine.AppendInt(port);
2495 : }
2496 18 : return NS_OK;
2497 : }
2498 :
2499 : void
2500 4 : NS_SniffContent(const char *aSnifferType, nsIRequest *aRequest,
2501 : const uint8_t *aData, uint32_t aLength,
2502 : nsACString &aSniffedType)
2503 : {
2504 : typedef nsCategoryCache<nsIContentSniffer> ContentSnifferCache;
2505 : extern ContentSnifferCache* gNetSniffers;
2506 : extern ContentSnifferCache* gDataSniffers;
2507 4 : ContentSnifferCache* cache = nullptr;
2508 4 : if (!strcmp(aSnifferType, NS_CONTENT_SNIFFER_CATEGORY)) {
2509 3 : if (!gNetSniffers) {
2510 1 : gNetSniffers = new ContentSnifferCache(NS_CONTENT_SNIFFER_CATEGORY);
2511 : }
2512 3 : cache = gNetSniffers;
2513 1 : } else if (!strcmp(aSnifferType, NS_DATA_SNIFFER_CATEGORY)) {
2514 1 : if (!gDataSniffers) {
2515 1 : gDataSniffers = new ContentSnifferCache(NS_DATA_SNIFFER_CATEGORY);
2516 : }
2517 1 : cache = gDataSniffers;
2518 : } else {
2519 : // Invalid content sniffer type was requested
2520 0 : MOZ_ASSERT(false);
2521 : return;
2522 : }
2523 :
2524 8 : nsCOMArray<nsIContentSniffer> sniffers;
2525 4 : cache->GetEntries(sniffers);
2526 16 : for (int32_t i = 0; i < sniffers.Count(); ++i) {
2527 12 : nsresult rv = sniffers[i]->GetMIMETypeFromContent(aRequest, aData, aLength, aSniffedType);
2528 12 : if (NS_SUCCEEDED(rv) && !aSniffedType.IsEmpty()) {
2529 0 : return;
2530 : }
2531 : }
2532 :
2533 4 : aSniffedType.Truncate();
2534 : }
2535 :
2536 : bool
2537 4 : NS_IsSrcdocChannel(nsIChannel *aChannel)
2538 : {
2539 : bool isSrcdoc;
2540 8 : nsCOMPtr<nsIInputStreamChannel> isr = do_QueryInterface(aChannel);
2541 4 : if (isr) {
2542 0 : isr->GetIsSrcdocChannel(&isSrcdoc);
2543 0 : return isSrcdoc;
2544 : }
2545 8 : nsCOMPtr<nsIViewSourceChannel> vsc = do_QueryInterface(aChannel);
2546 4 : if (vsc) {
2547 0 : nsresult rv = vsc->GetIsSrcdocChannel(&isSrcdoc);
2548 0 : if (NS_SUCCEEDED(rv)) {
2549 0 : return isSrcdoc;
2550 : }
2551 : }
2552 4 : return false;
2553 : }
2554 :
2555 : nsresult
2556 9 : NS_ShouldSecureUpgrade(nsIURI* aURI,
2557 : nsILoadInfo* aLoadInfo,
2558 : nsIPrincipal* aChannelResultPrincipal,
2559 : bool aPrivateBrowsing,
2560 : bool aAllowSTS,
2561 : const OriginAttributes& aOriginAttributes,
2562 : bool& aShouldUpgrade)
2563 : {
2564 : // Even if we're in private browsing mode, we still enforce existing STS
2565 : // data (it is read-only).
2566 : // if the connection is not using SSL and either the exact host matches or
2567 : // a superdomain wants to force HTTPS, do it.
2568 9 : bool isHttps = false;
2569 9 : nsresult rv = aURI->SchemeIs("https", &isHttps);
2570 9 : NS_ENSURE_SUCCESS(rv, rv);
2571 :
2572 9 : if (!isHttps) {
2573 : // If any of the documents up the chain to the root doucment makes use of
2574 : // the CSP directive 'upgrade-insecure-requests', then it's time to fulfill
2575 : // the promise to CSP and mixed content blocking to upgrade the channel
2576 : // from http to https.
2577 9 : if (aLoadInfo) {
2578 : // Please note that cross origin top level navigations are not subject
2579 : // to upgrade-insecure-requests, see:
2580 : // http://www.w3.org/TR/upgrade-insecure-requests/#examples
2581 : // Compare the principal we are navigating to (aChannelResultPrincipal)
2582 : // with the referring/triggering Principal.
2583 : bool crossOriginNavigation =
2584 11 : (aLoadInfo->GetExternalContentPolicyType() == nsIContentPolicy::TYPE_DOCUMENT) &&
2585 11 : (!aChannelResultPrincipal->Equals(aLoadInfo->TriggeringPrincipal()));
2586 :
2587 9 : if (aLoadInfo->GetUpgradeInsecureRequests() && !crossOriginNavigation) {
2588 : // let's log a message to the console that we are upgrading a request
2589 0 : nsAutoCString scheme;
2590 0 : aURI->GetScheme(scheme);
2591 : // append the additional 's' for security to the scheme :-)
2592 0 : scheme.AppendASCII("s");
2593 0 : NS_ConvertUTF8toUTF16 reportSpec(aURI->GetSpecOrDefault());
2594 0 : NS_ConvertUTF8toUTF16 reportScheme(scheme);
2595 :
2596 0 : const char16_t* params[] = { reportSpec.get(), reportScheme.get() };
2597 0 : uint32_t innerWindowId = aLoadInfo->GetInnerWindowID();
2598 0 : CSP_LogLocalizedStr(u"upgradeInsecureRequest",
2599 0 : params, ArrayLength(params),
2600 0 : EmptyString(), // aSourceFile
2601 0 : EmptyString(), // aScriptSample
2602 : 0, // aLineNumber
2603 : 0, // aColumnNumber
2604 : nsIScriptError::warningFlag, "CSP",
2605 0 : innerWindowId);
2606 :
2607 0 : Telemetry::Accumulate(Telemetry::HTTP_SCHEME_UPGRADE, 4);
2608 0 : aShouldUpgrade = true;
2609 0 : return NS_OK;
2610 : }
2611 :
2612 9 : if (aLoadInfo->GetForceHSTSPriming()) {
2613 : // don't log requests which might be upgraded due to HSTS Priming
2614 : // they get logged in nsHttpChannel::OnHSTSPrimingSucceeded or
2615 : // nsHttpChannel::OnHSTSPrimingFailed if the load is allowed to proceed.
2616 0 : aShouldUpgrade = false;
2617 0 : return NS_OK;
2618 : }
2619 : }
2620 :
2621 : // enforce Strict-Transport-Security
2622 9 : nsISiteSecurityService* sss = gHttpHandler->GetSSService();
2623 9 : NS_ENSURE_TRUE(sss, NS_ERROR_OUT_OF_MEMORY);
2624 :
2625 9 : bool isStsHost = false;
2626 9 : uint32_t hstsSource = 0;
2627 9 : uint32_t flags = aPrivateBrowsing ? nsISocketProvider::NO_PERMANENT_STORAGE : 0;
2628 : rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, aURI, flags,
2629 9 : aOriginAttributes, nullptr, &hstsSource, &isStsHost);
2630 :
2631 : // if the SSS check fails, it's likely because this load is on a
2632 : // malformed URI or something else in the setup is wrong, so any error
2633 : // should be reported.
2634 9 : NS_ENSURE_SUCCESS(rv, rv);
2635 :
2636 9 : if (isStsHost) {
2637 0 : LOG(("nsHttpChannel::Connect() STS permissions found\n"));
2638 0 : if (aAllowSTS) {
2639 0 : Telemetry::Accumulate(Telemetry::HTTP_SCHEME_UPGRADE, 3);
2640 0 : aShouldUpgrade = true;
2641 0 : switch (hstsSource) {
2642 : case nsISiteSecurityService::SOURCE_PRELOAD_LIST:
2643 0 : Telemetry::Accumulate(Telemetry::HSTS_UPGRADE_SOURCE, 0);
2644 0 : break;
2645 : case nsISiteSecurityService::SOURCE_ORGANIC_REQUEST:
2646 0 : Telemetry::Accumulate(Telemetry::HSTS_UPGRADE_SOURCE, 1);
2647 0 : break;
2648 : case nsISiteSecurityService::SOURCE_HSTS_PRIMING:
2649 0 : Telemetry::Accumulate(Telemetry::HSTS_UPGRADE_SOURCE, 2);
2650 0 : break;
2651 : case nsISiteSecurityService::SOURCE_UNKNOWN:
2652 : default:
2653 : // record this as an organic request
2654 0 : Telemetry::Accumulate(Telemetry::HSTS_UPGRADE_SOURCE, 1);
2655 0 : break;
2656 : }
2657 0 : return NS_OK;
2658 : } else {
2659 0 : Telemetry::Accumulate(Telemetry::HTTP_SCHEME_UPGRADE, 2);
2660 : }
2661 : } else {
2662 9 : Telemetry::Accumulate(Telemetry::HTTP_SCHEME_UPGRADE, 1);
2663 : }
2664 : } else {
2665 0 : if (aLoadInfo) {
2666 0 : if (aLoadInfo->GetIsHSTSPriming()) {
2667 : // don't log HSTS priming requests
2668 0 : aShouldUpgrade = false;
2669 0 : return NS_OK;
2670 : }
2671 :
2672 0 : if (aLoadInfo->GetIsHSTSPrimingUpgrade()) {
2673 : // if the upgrade occured due to HSTS priming, it was logged in
2674 : // nsHttpChannel::OnHSTSPrimingSucceeded before redirect
2675 0 : aShouldUpgrade = false;
2676 0 : return NS_OK;
2677 : }
2678 : }
2679 :
2680 0 : Telemetry::Accumulate(Telemetry::HTTP_SCHEME_UPGRADE, 0);
2681 : }
2682 9 : aShouldUpgrade = false;
2683 9 : return NS_OK;
2684 : }
2685 :
2686 : nsresult
2687 0 : NS_GetSecureUpgradedURI(nsIURI* aURI, nsIURI** aUpgradedURI)
2688 : {
2689 0 : nsCOMPtr<nsIURI> upgradedURI;
2690 :
2691 0 : nsresult rv = aURI->Clone(getter_AddRefs(upgradedURI));
2692 0 : NS_ENSURE_SUCCESS(rv,rv);
2693 :
2694 : // Change the scheme to HTTPS:
2695 0 : upgradedURI->SetScheme(NS_LITERAL_CSTRING("https"));
2696 :
2697 : // Change the default port to 443:
2698 0 : nsCOMPtr<nsIStandardURL> upgradedStandardURL = do_QueryInterface(upgradedURI);
2699 0 : if (upgradedStandardURL) {
2700 0 : upgradedStandardURL->SetDefaultPort(443);
2701 : } else {
2702 : // If we don't have a nsStandardURL, fall back to using GetPort/SetPort.
2703 : // XXXdholbert Is this function even called with a non-nsStandardURL arg,
2704 : // in practice?
2705 0 : int32_t oldPort = -1;
2706 0 : rv = aURI->GetPort(&oldPort);
2707 0 : if (NS_FAILED(rv)) return rv;
2708 :
2709 : // Keep any nonstandard ports so only the scheme is changed.
2710 : // For example:
2711 : // http://foo.com:80 -> https://foo.com:443
2712 : // http://foo.com:81 -> https://foo.com:81
2713 :
2714 0 : if (oldPort == 80 || oldPort == -1) {
2715 0 : upgradedURI->SetPort(-1);
2716 : } else {
2717 0 : upgradedURI->SetPort(oldPort);
2718 : }
2719 : }
2720 :
2721 0 : upgradedURI.forget(aUpgradedURI);
2722 0 : return NS_OK;
2723 : }
2724 :
2725 : nsresult
2726 9 : NS_CompareLoadInfoAndLoadContext(nsIChannel *aChannel)
2727 : {
2728 18 : nsCOMPtr<nsILoadInfo> loadInfo;
2729 9 : aChannel->GetLoadInfo(getter_AddRefs(loadInfo));
2730 :
2731 18 : nsCOMPtr<nsILoadContext> loadContext;
2732 9 : NS_QueryNotificationCallbacks(aChannel, loadContext);
2733 9 : if (!loadInfo || !loadContext) {
2734 2 : return NS_OK;
2735 : }
2736 :
2737 : // We try to skip about:newtab.
2738 : // about:newtab will use SystemPrincipal to download thumbnails through
2739 : // https:// and blob URLs.
2740 7 : bool isAboutPage = false;
2741 7 : nsINode* node = loadInfo->LoadingNode();
2742 7 : if (node) {
2743 2 : nsIDocument* doc = node->OwnerDoc();
2744 2 : if (doc) {
2745 2 : nsIURI* uri = doc->GetDocumentURI();
2746 2 : nsresult rv = uri->SchemeIs("about", &isAboutPage);
2747 2 : NS_ENSURE_SUCCESS(rv, rv);
2748 : }
2749 : }
2750 :
2751 7 : if (isAboutPage) {
2752 0 : return NS_OK;
2753 : }
2754 :
2755 : // We skip the favicon loading here. The favicon loading might be
2756 : // triggered by the XUL image. For that case, the loadContext will have
2757 : // default originAttributes since the XUL image uses SystemPrincipal, but
2758 : // the loadInfo will use originAttributes from the content. Thus, the
2759 : // originAttributes between loadInfo and loadContext will be different.
2760 : // That's why we have to skip the comparison for the favicon loading.
2761 9 : if (nsContentUtils::IsSystemPrincipal(loadInfo->LoadingPrincipal()) &&
2762 2 : loadInfo->InternalContentPolicyType() ==
2763 : nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON) {
2764 1 : return NS_OK;
2765 : }
2766 :
2767 6 : bool loadContextIsInBE = false;
2768 6 : nsresult rv = loadContext->GetIsInIsolatedMozBrowserElement(&loadContextIsInBE);
2769 6 : if (NS_FAILED(rv)) {
2770 0 : return NS_ERROR_UNEXPECTED;
2771 : }
2772 :
2773 12 : OriginAttributes originAttrsLoadInfo = loadInfo->GetOriginAttributes();
2774 12 : OriginAttributes originAttrsLoadContext;
2775 6 : loadContext->GetOriginAttributes(originAttrsLoadContext);
2776 :
2777 6 : LOG(("NS_CompareLoadInfoAndLoadContext - loadInfo: %d, %d, %d; "
2778 : "loadContext: %d %d, %d. [channel=%p]",
2779 : originAttrsLoadInfo.mInIsolatedMozBrowser, originAttrsLoadInfo.mUserContextId,
2780 : originAttrsLoadInfo.mPrivateBrowsingId, loadContextIsInBE,
2781 : originAttrsLoadContext.mUserContextId, originAttrsLoadContext.mPrivateBrowsingId,
2782 : aChannel));
2783 :
2784 6 : MOZ_ASSERT(originAttrsLoadInfo.mInIsolatedMozBrowser ==
2785 : loadContextIsInBE,
2786 : "The value of InIsolatedMozBrowser in the loadContext and in "
2787 : "the loadInfo are not the same!");
2788 :
2789 6 : MOZ_ASSERT(originAttrsLoadInfo.mUserContextId ==
2790 : originAttrsLoadContext.mUserContextId,
2791 : "The value of mUserContextId in the loadContext and in the "
2792 : "loadInfo are not the same!");
2793 :
2794 6 : MOZ_ASSERT(originAttrsLoadInfo.mPrivateBrowsingId ==
2795 : originAttrsLoadContext.mPrivateBrowsingId,
2796 : "The value of mPrivateBrowsingId in the loadContext and in the "
2797 : "loadInfo are not the same!");
2798 :
2799 6 : return NS_OK;
2800 : }
2801 :
2802 : uint32_t
2803 13 : NS_GetDefaultReferrerPolicy()
2804 : {
2805 : static bool preferencesInitialized = false;
2806 :
2807 13 : if (!preferencesInitialized) {
2808 : mozilla::Preferences::AddUintVarCache(&sUserControlRp,
2809 : "network.http.referer.userControlPolicy",
2810 2 : DEFAULT_USER_CONTROL_RP);
2811 2 : preferencesInitialized = true;
2812 : }
2813 :
2814 13 : switch (sUserControlRp) {
2815 : case 0:
2816 0 : return nsIHttpChannel::REFERRER_POLICY_NO_REFERRER;
2817 : case 1:
2818 0 : return nsIHttpChannel::REFERRER_POLICY_SAME_ORIGIN;
2819 : case 2:
2820 0 : return nsIHttpChannel::REFERRER_POLICY_STRICT_ORIGIN_WHEN_XORIGIN;
2821 : }
2822 :
2823 13 : return nsIHttpChannel::REFERRER_POLICY_NO_REFERRER_WHEN_DOWNGRADE;
2824 : }
2825 :
2826 : bool
2827 13 : NS_IsOffline()
2828 : {
2829 13 : bool offline = true;
2830 13 : bool connectivity = true;
2831 26 : nsCOMPtr<nsIIOService> ios = do_GetIOService();
2832 13 : if (ios) {
2833 13 : ios->GetOffline(&offline);
2834 13 : ios->GetConnectivity(&connectivity);
2835 : }
2836 26 : return offline || !connectivity;
2837 : }
2838 :
2839 : nsresult
2840 4 : NS_NotifyCurrentTopLevelOuterContentWindowId(uint64_t aWindowId)
2841 : {
2842 : nsCOMPtr<nsIObserverService> obs =
2843 8 : do_GetService("@mozilla.org/observer-service;1");
2844 4 : if (!obs) {
2845 0 : return NS_ERROR_FAILURE;
2846 : }
2847 :
2848 : nsCOMPtr<nsISupportsPRUint64> wrapper =
2849 8 : do_CreateInstance(NS_SUPPORTS_PRUINT64_CONTRACTID);
2850 4 : if (!wrapper) {
2851 0 : return NS_ERROR_FAILURE;
2852 : }
2853 :
2854 4 : wrapper->SetData(aWindowId);
2855 4 : return obs->NotifyObservers(wrapper,
2856 : "net:current-toplevel-outer-content-windowid",
2857 4 : nullptr);
2858 : }
2859 :
2860 : namespace mozilla {
2861 : namespace net {
2862 :
2863 : bool
2864 10 : InScriptableRange(int64_t val)
2865 : {
2866 10 : return (val <= kJS_MAX_SAFE_INTEGER) && (val >= kJS_MIN_SAFE_INTEGER);
2867 : }
2868 :
2869 : bool
2870 3 : InScriptableRange(uint64_t val)
2871 : {
2872 3 : return val <= kJS_MAX_SAFE_UINTEGER;
2873 : }
2874 :
2875 : } // namespace net
2876 : } // namespace mozilla
|