1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 #include "LoadContextInfo.h"
6 
7 #include "mozilla/dom/ToJSValue.h"
8 #include "mozilla/StoragePrincipalHelper.h"
9 #include "nsDocShell.h"
10 #include "nsIChannel.h"
11 #include "nsILoadContext.h"
12 #include "nsIWebNavigation.h"
13 #include "nsNetUtil.h"
14 
15 using namespace mozilla::dom;
16 namespace mozilla {
17 namespace net {
18 
19 // LoadContextInfo
20 
NS_IMPL_ISUPPORTS(LoadContextInfo,nsILoadContextInfo)21 NS_IMPL_ISUPPORTS(LoadContextInfo, nsILoadContextInfo)
22 
23 LoadContextInfo::LoadContextInfo(bool aIsAnonymous,
24                                  OriginAttributes aOriginAttributes)
25     : mIsAnonymous(aIsAnonymous),
26       mOriginAttributes(std::move(aOriginAttributes)) {}
27 
GetIsPrivate(bool * aIsPrivate)28 NS_IMETHODIMP LoadContextInfo::GetIsPrivate(bool* aIsPrivate) {
29   *aIsPrivate = mOriginAttributes.mPrivateBrowsingId > 0;
30   return NS_OK;
31 }
32 
GetIsAnonymous(bool * aIsAnonymous)33 NS_IMETHODIMP LoadContextInfo::GetIsAnonymous(bool* aIsAnonymous) {
34   *aIsAnonymous = mIsAnonymous;
35   return NS_OK;
36 }
37 
OriginAttributesPtr()38 OriginAttributes const* LoadContextInfo::OriginAttributesPtr() {
39   return &mOriginAttributes;
40 }
41 
GetOriginAttributes(JSContext * aCx,JS::MutableHandle<JS::Value> aVal)42 NS_IMETHODIMP LoadContextInfo::GetOriginAttributes(
43     JSContext* aCx, JS::MutableHandle<JS::Value> aVal) {
44   if (NS_WARN_IF(!ToJSValue(aCx, mOriginAttributes, aVal))) {
45     return NS_ERROR_FAILURE;
46   }
47   return NS_OK;
48 }
49 
50 // LoadContextInfoFactory
51 
NS_IMPL_ISUPPORTS(LoadContextInfoFactory,nsILoadContextInfoFactory)52 NS_IMPL_ISUPPORTS(LoadContextInfoFactory, nsILoadContextInfoFactory)
53 
54 NS_IMETHODIMP LoadContextInfoFactory::GetDefault(
55     nsILoadContextInfo** aDefault) {
56   nsCOMPtr<nsILoadContextInfo> info =
57       GetLoadContextInfo(false, OriginAttributes());
58   info.forget(aDefault);
59   return NS_OK;
60 }
61 
GetPrivate(nsILoadContextInfo ** aPrivate)62 NS_IMETHODIMP LoadContextInfoFactory::GetPrivate(
63     nsILoadContextInfo** aPrivate) {
64   OriginAttributes attrs;
65   attrs.SyncAttributesWithPrivateBrowsing(true);
66   nsCOMPtr<nsILoadContextInfo> info = GetLoadContextInfo(false, attrs);
67   info.forget(aPrivate);
68   return NS_OK;
69 }
70 
GetAnonymous(nsILoadContextInfo ** aAnonymous)71 NS_IMETHODIMP LoadContextInfoFactory::GetAnonymous(
72     nsILoadContextInfo** aAnonymous) {
73   nsCOMPtr<nsILoadContextInfo> info =
74       GetLoadContextInfo(true, OriginAttributes());
75   info.forget(aAnonymous);
76   return NS_OK;
77 }
78 
Custom(bool aAnonymous,JS::HandleValue aOriginAttributes,JSContext * cx,nsILoadContextInfo ** _retval)79 NS_IMETHODIMP LoadContextInfoFactory::Custom(bool aAnonymous,
80                                              JS::HandleValue aOriginAttributes,
81                                              JSContext* cx,
82                                              nsILoadContextInfo** _retval) {
83   OriginAttributes attrs;
84   bool status = attrs.Init(cx, aOriginAttributes);
85   NS_ENSURE_TRUE(status, NS_ERROR_FAILURE);
86 
87   nsCOMPtr<nsILoadContextInfo> info = GetLoadContextInfo(aAnonymous, attrs);
88   info.forget(_retval);
89   return NS_OK;
90 }
91 
FromLoadContext(nsILoadContext * aLoadContext,bool aAnonymous,nsILoadContextInfo ** _retval)92 NS_IMETHODIMP LoadContextInfoFactory::FromLoadContext(
93     nsILoadContext* aLoadContext, bool aAnonymous,
94     nsILoadContextInfo** _retval) {
95   nsCOMPtr<nsILoadContextInfo> info =
96       GetLoadContextInfo(aLoadContext, aAnonymous);
97   info.forget(_retval);
98   return NS_OK;
99 }
100 
FromWindow(nsIDOMWindow * aWindow,bool aAnonymous,nsILoadContextInfo ** _retval)101 NS_IMETHODIMP LoadContextInfoFactory::FromWindow(nsIDOMWindow* aWindow,
102                                                  bool aAnonymous,
103                                                  nsILoadContextInfo** _retval) {
104   nsCOMPtr<nsILoadContextInfo> info = GetLoadContextInfo(aWindow, aAnonymous);
105   info.forget(_retval);
106   return NS_OK;
107 }
108 
109 // Helper functions
110 
GetLoadContextInfo(nsIChannel * aChannel)111 LoadContextInfo* GetLoadContextInfo(nsIChannel* aChannel) {
112   nsresult rv;
113 
114   DebugOnly<bool> pb = NS_UsePrivateBrowsing(aChannel);
115 
116   bool anon = false;
117   nsLoadFlags loadFlags;
118   rv = aChannel->GetLoadFlags(&loadFlags);
119   if (NS_SUCCEEDED(rv)) {
120     anon = !!(loadFlags & nsIChannel::LOAD_ANONYMOUS);
121   }
122 
123   OriginAttributes oa;
124   StoragePrincipalHelper::GetOriginAttributesForNetworkState(aChannel, oa);
125   MOZ_ASSERT(pb == (oa.mPrivateBrowsingId > 0));
126 
127   return new LoadContextInfo(anon, oa);
128 }
129 
GetLoadContextInfo(nsILoadContext * aLoadContext,bool aIsAnonymous)130 LoadContextInfo* GetLoadContextInfo(nsILoadContext* aLoadContext,
131                                     bool aIsAnonymous) {
132   if (!aLoadContext) {
133     return new LoadContextInfo(aIsAnonymous, OriginAttributes());
134   }
135 
136   OriginAttributes oa;
137   aLoadContext->GetOriginAttributes(oa);
138 
139 #ifdef DEBUG
140   nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(aLoadContext);
141   if (!docShell ||
142       nsDocShell::Cast(docShell)->GetBrowsingContext()->IsContent()) {
143     MOZ_ASSERT(aLoadContext->UsePrivateBrowsing() ==
144                (oa.mPrivateBrowsingId > 0));
145   }
146 #endif
147 
148   return new LoadContextInfo(aIsAnonymous, oa);
149 }
150 
GetLoadContextInfo(nsIDOMWindow * aWindow,bool aIsAnonymous)151 LoadContextInfo* GetLoadContextInfo(nsIDOMWindow* aWindow, bool aIsAnonymous) {
152   nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(aWindow);
153   nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(webNav);
154 
155   return GetLoadContextInfo(loadContext, aIsAnonymous);
156 }
157 
GetLoadContextInfo(nsILoadContextInfo * aInfo)158 LoadContextInfo* GetLoadContextInfo(nsILoadContextInfo* aInfo) {
159   return new LoadContextInfo(aInfo->IsAnonymous(),
160                              *aInfo->OriginAttributesPtr());
161 }
162 
GetLoadContextInfo(bool const aIsAnonymous,OriginAttributes const & aOriginAttributes)163 LoadContextInfo* GetLoadContextInfo(bool const aIsAnonymous,
164                                     OriginAttributes const& aOriginAttributes) {
165   return new LoadContextInfo(aIsAnonymous, aOriginAttributes);
166 }
167 
168 }  // namespace net
169 }  // namespace mozilla
170