1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  *
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "WebBrowserPersistRemoteDocument.h"
8 #include "WebBrowserPersistDocumentParent.h"
9 #include "WebBrowserPersistResourcesParent.h"
10 #include "WebBrowserPersistSerializeParent.h"
11 #include "mozilla/Unused.h"
12 #include "mozilla/ipc/BackgroundUtils.h"
13 
14 #include "nsDebug.h"
15 #include "nsIPrincipal.h"
16 
17 namespace mozilla {
18 
NS_IMPL_ISUPPORTS(WebBrowserPersistRemoteDocument,nsIWebBrowserPersistDocument)19 NS_IMPL_ISUPPORTS(WebBrowserPersistRemoteDocument, nsIWebBrowserPersistDocument)
20 
21 WebBrowserPersistRemoteDocument ::WebBrowserPersistRemoteDocument(
22     WebBrowserPersistDocumentParent* aActor, const Attrs& aAttrs,
23     nsIInputStream* aPostData)
24     : mActor(aActor), mAttrs(aAttrs), mPostData(aPostData) {
25   auto principalOrErr = ipc::PrincipalInfoToPrincipal(mAttrs.principal());
26   if (principalOrErr.isOk()) {
27     mPrincipal = principalOrErr.unwrap();
28   } else {
29     NS_WARNING("Failed to obtain principal!");
30   }
31 }
32 
~WebBrowserPersistRemoteDocument()33 WebBrowserPersistRemoteDocument::~WebBrowserPersistRemoteDocument() {
34   if (mActor) {
35     Unused << WebBrowserPersistDocumentParent::Send__delete__(mActor);
36     // That will call mActor->ActorDestroy, which calls this->ActorDestroy
37     // (whether or not the IPC send succeeds).
38   }
39   MOZ_ASSERT(!mActor);
40 }
41 
ActorDestroy(void)42 void WebBrowserPersistRemoteDocument::ActorDestroy(void) { mActor = nullptr; }
43 
44 NS_IMETHODIMP
GetIsPrivate(bool * aIsPrivate)45 WebBrowserPersistRemoteDocument::GetIsPrivate(bool* aIsPrivate) {
46   *aIsPrivate = mAttrs.isPrivate();
47   return NS_OK;
48 }
49 
50 NS_IMETHODIMP
GetDocumentURI(nsACString & aURISpec)51 WebBrowserPersistRemoteDocument::GetDocumentURI(nsACString& aURISpec) {
52   aURISpec = mAttrs.documentURI();
53   return NS_OK;
54 }
55 
56 NS_IMETHODIMP
GetBaseURI(nsACString & aURISpec)57 WebBrowserPersistRemoteDocument::GetBaseURI(nsACString& aURISpec) {
58   aURISpec = mAttrs.baseURI();
59   return NS_OK;
60 }
61 
62 NS_IMETHODIMP
GetContentType(nsACString & aContentType)63 WebBrowserPersistRemoteDocument::GetContentType(nsACString& aContentType) {
64   aContentType = mAttrs.contentType();
65   return NS_OK;
66 }
67 
68 NS_IMETHODIMP
GetCharacterSet(nsACString & aCharSet)69 WebBrowserPersistRemoteDocument::GetCharacterSet(nsACString& aCharSet) {
70   aCharSet = mAttrs.characterSet();
71   return NS_OK;
72 }
73 
74 NS_IMETHODIMP
GetTitle(nsAString & aTitle)75 WebBrowserPersistRemoteDocument::GetTitle(nsAString& aTitle) {
76   aTitle = mAttrs.title();
77   return NS_OK;
78 }
79 
80 NS_IMETHODIMP
GetReferrerInfo(nsIReferrerInfo ** aReferrerInfo)81 WebBrowserPersistRemoteDocument::GetReferrerInfo(
82     nsIReferrerInfo** aReferrerInfo) {
83   *aReferrerInfo = mAttrs.referrerInfo();
84   NS_IF_ADDREF(*aReferrerInfo);
85   return NS_OK;
86 }
87 
88 NS_IMETHODIMP
GetContentDisposition(nsAString & aDisp)89 WebBrowserPersistRemoteDocument::GetContentDisposition(nsAString& aDisp) {
90   aDisp = mAttrs.contentDisposition();
91   return NS_OK;
92 }
93 
94 NS_IMETHODIMP
GetCacheKey(uint32_t * aCacheKey)95 WebBrowserPersistRemoteDocument::GetCacheKey(uint32_t* aCacheKey) {
96   *aCacheKey = 0;
97   if (mAttrs.sessionHistoryEntryOrCacheKey().type() ==
98       SessionHistoryEntryOrCacheKey::Tuint32_t) {
99     *aCacheKey = mAttrs.sessionHistoryEntryOrCacheKey();
100   }
101   return NS_OK;
102 }
103 
104 NS_IMETHODIMP
GetPersistFlags(uint32_t * aFlags)105 WebBrowserPersistRemoteDocument::GetPersistFlags(uint32_t* aFlags) {
106   *aFlags = mAttrs.persistFlags();
107   return NS_OK;
108 }
109 
110 NS_IMETHODIMP
SetPersistFlags(uint32_t aFlags)111 WebBrowserPersistRemoteDocument::SetPersistFlags(uint32_t aFlags) {
112   if (!mActor) {
113     return NS_ERROR_FAILURE;
114   }
115   if (!mActor->SendSetPersistFlags(aFlags)) {
116     return NS_ERROR_FAILURE;
117   }
118   mAttrs.persistFlags() = aFlags;
119   return NS_OK;
120 }
121 
122 NS_IMETHODIMP
GetPostData(nsIInputStream ** aStream)123 WebBrowserPersistRemoteDocument::GetPostData(nsIInputStream** aStream) {
124   nsCOMPtr<nsIInputStream> stream = mPostData;
125   stream.forget(aStream);
126   return NS_OK;
127 }
128 
129 NS_IMETHODIMP
GetPrincipal(nsIPrincipal ** aPrincipal)130 WebBrowserPersistRemoteDocument::GetPrincipal(nsIPrincipal** aPrincipal) {
131   nsCOMPtr<nsIPrincipal> nodePrincipal = mPrincipal;
132   nodePrincipal.forget(aPrincipal);
133   return NS_OK;
134 }
135 
136 NS_IMETHODIMP
ReadResources(nsIWebBrowserPersistResourceVisitor * aVisitor)137 WebBrowserPersistRemoteDocument::ReadResources(
138     nsIWebBrowserPersistResourceVisitor* aVisitor) {
139   if (!mActor) {
140     return NS_ERROR_FAILURE;
141   }
142   RefPtr<WebBrowserPersistResourcesParent> subActor =
143       new WebBrowserPersistResourcesParent(this, aVisitor);
144   return mActor->SendPWebBrowserPersistResourcesConstructor(
145              subActor.forget().take())
146              ? NS_OK
147              : NS_ERROR_FAILURE;
148 }
149 
150 NS_IMETHODIMP
WriteContent(nsIOutputStream * aStream,nsIWebBrowserPersistURIMap * aMap,const nsACString & aRequestedContentType,uint32_t aEncoderFlags,uint32_t aWrapColumn,nsIWebBrowserPersistWriteCompletion * aCompletion)151 WebBrowserPersistRemoteDocument::WriteContent(
152     nsIOutputStream* aStream, nsIWebBrowserPersistURIMap* aMap,
153     const nsACString& aRequestedContentType, uint32_t aEncoderFlags,
154     uint32_t aWrapColumn, nsIWebBrowserPersistWriteCompletion* aCompletion) {
155   if (!mActor) {
156     return NS_ERROR_FAILURE;
157   }
158 
159   nsresult rv;
160   WebBrowserPersistURIMap map;
161   uint32_t numMappedURIs;
162   if (aMap) {
163     rv = aMap->GetTargetBaseURI(map.targetBaseURI());
164     NS_ENSURE_SUCCESS(rv, rv);
165     rv = aMap->GetNumMappedURIs(&numMappedURIs);
166     NS_ENSURE_SUCCESS(rv, rv);
167     for (uint32_t i = 0; i < numMappedURIs; ++i) {
168       WebBrowserPersistURIMapEntry& nextEntry =
169           *(map.mapURIs().AppendElement());
170       rv = aMap->GetURIMapping(i, nextEntry.mapFrom(), nextEntry.mapTo());
171       NS_ENSURE_SUCCESS(rv, rv);
172     }
173   }
174 
175   auto* subActor =
176       new WebBrowserPersistSerializeParent(this, aStream, aCompletion);
177   nsCString requestedContentType(aRequestedContentType);  // Sigh.
178   return mActor->SendPWebBrowserPersistSerializeConstructor(
179              subActor, map, requestedContentType, aEncoderFlags, aWrapColumn)
180              ? NS_OK
181              : NS_ERROR_FAILURE;
182 }
183 
184 // Forcing WebBrowserPersistRemoteDocument to implement GetHistory is the
185 // easiest way to ensure that we can call GetHistory in
186 // WebBrowserPersistDocumentChild::Start
GetHistory()187 already_AddRefed<nsISHEntry> WebBrowserPersistRemoteDocument::GetHistory() {
188   MOZ_CRASH("We should not call GetHistory on WebBrowserPersistRemoteDocument");
189   return nullptr;
190 }
191 
192 }  // namespace mozilla
193