Bug 1890277: part 1) Add CSP parser tests for `require-trusted-types-for`. r=tschuster
[gecko.git] / uriloader / exthandler / ExternalHelperAppParent.cpp
blob96c7444abac7b1bcf8220b5c905ae98f7bbd7feb
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
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/. */
7 #include "mozilla/DebugOnly.h"
9 #include "ExternalHelperAppParent.h"
10 #include "nsExternalHelperAppService.h"
11 #include "nsIContent.h"
12 #include "nsCExternalHandlerService.h"
13 #include "nsIExternalHelperAppService.h"
14 #include "mozilla/dom/ContentParent.h"
15 #include "mozilla/dom/Element.h"
16 #include "mozilla/dom/BrowserParent.h"
17 #include "nsStringStream.h"
18 #include "mozilla/ipc/URIUtils.h"
19 #include "nsNetUtil.h"
20 #include "mozilla/dom/Document.h"
21 #include "mozilla/dom/CanonicalBrowsingContext.h"
22 #include "mozilla/dom/WindowGlobalParent.h"
23 #include "nsQueryObject.h"
25 #include "mozilla/Unused.h"
27 using namespace mozilla::ipc;
29 namespace mozilla {
30 namespace dom {
32 NS_IMPL_ISUPPORTS_INHERITED(ExternalHelperAppParent, nsHashPropertyBag,
33 nsIRequest, nsIChannel, nsIMultiPartChannel,
34 nsIPrivateBrowsingChannel, nsIResumableChannel,
35 nsIStreamListener, nsIExternalHelperAppParent)
37 ExternalHelperAppParent::ExternalHelperAppParent(
38 nsIURI* uri, const int64_t& aContentLength, const bool& aWasFileChannel,
39 const nsACString& aContentDispositionHeader,
40 const uint32_t& aContentDispositionHint,
41 const nsAString& aContentDispositionFilename)
42 : mURI(uri),
43 mPending(false),
44 mIPCClosed(false),
45 mLoadFlags(0),
46 mStatus(NS_OK),
47 mCanceled(false),
48 mContentLength(aContentLength),
49 mWasFileChannel(aWasFileChannel) {
50 mContentDispositionHeader = aContentDispositionHeader;
51 if (!mContentDispositionHeader.IsEmpty()) {
52 NS_GetFilenameFromDisposition(mContentDispositionFilename,
53 mContentDispositionHeader);
54 mContentDisposition =
55 NS_GetContentDispositionFromHeader(mContentDispositionHeader, this);
56 } else {
57 mContentDisposition = aContentDispositionHint;
58 mContentDispositionFilename = aContentDispositionFilename;
62 bool ExternalHelperAppParent::Init(
63 const mozilla::net::LoadInfoArgs& aLoadInfoArgs,
64 const nsACString& aMimeContentType, const bool& aForceSave,
65 nsIURI* aReferrer, BrowsingContext* aContext,
66 const bool& aShouldCloseWindow) {
67 nsresult rv = mozilla::ipc::LoadInfoArgsToLoadInfo(
68 aLoadInfoArgs, ContentParent::Cast(Manager())->GetRemoteType(),
69 getter_AddRefs(mLoadInfo));
70 if (NS_FAILED(rv)) {
71 return false;
74 nsCOMPtr<nsIExternalHelperAppService> helperAppService =
75 do_GetService(NS_EXTERNALHELPERAPPSERVICE_CONTRACTID);
76 NS_ASSERTION(helperAppService, "No Helper App Service!");
78 if (aReferrer) {
79 SetPropertyAsInterface(u"docshell.internalReferrer"_ns, aReferrer);
82 if (aContext) {
83 WindowGlobalParent* parent =
84 aContext->Canonical()->GetCurrentWindowGlobal();
85 if (parent) {
86 RefPtr<BrowserParent> browser = parent->GetBrowserParent();
87 if (browser) {
88 bool isPrivate = false;
89 nsCOMPtr<nsILoadContext> loadContext = browser->GetLoadContext();
90 loadContext->GetUsePrivateBrowsing(&isPrivate);
91 SetPrivate(isPrivate);
96 helperAppService->CreateListener(aMimeContentType, this, aContext, aForceSave,
97 nullptr, getter_AddRefs(mListener));
98 if (!mListener) {
99 return false;
102 if (aShouldCloseWindow) {
103 RefPtr<nsExternalAppHandler> handler = do_QueryObject(mListener);
104 if (handler) {
105 handler->SetShouldCloseWindow();
109 return true;
112 void ExternalHelperAppParent::ActorDestroy(ActorDestroyReason why) {
113 mIPCClosed = true;
116 void ExternalHelperAppParent::Delete() {
117 if (!mIPCClosed) {
118 Unused << Send__delete__(this);
122 mozilla::ipc::IPCResult ExternalHelperAppParent::RecvOnStartRequest(
123 const nsACString& entityID) {
124 mEntityID = entityID;
125 mPending = true;
126 mStatus = mListener->OnStartRequest(this);
127 return IPC_OK();
130 mozilla::ipc::IPCResult ExternalHelperAppParent::RecvOnDataAvailable(
131 const nsACString& data, const uint64_t& offset, const uint32_t& count) {
132 if (NS_FAILED(mStatus)) {
133 return IPC_OK();
136 MOZ_ASSERT(mPending, "must be pending!");
138 nsCOMPtr<nsIInputStream> stringStream;
139 DebugOnly<nsresult> rv = NS_NewByteInputStream(
140 getter_AddRefs(stringStream), Span(data).To(count), NS_ASSIGNMENT_DEPEND);
141 NS_ASSERTION(NS_SUCCEEDED(rv), "failed to create dependent string!");
142 mStatus = mListener->OnDataAvailable(this, stringStream, offset, count);
144 return IPC_OK();
147 mozilla::ipc::IPCResult ExternalHelperAppParent::RecvOnStopRequest(
148 const nsresult& code) {
149 mPending = false;
150 mListener->OnStopRequest(
151 this, (NS_SUCCEEDED(code) && NS_FAILED(mStatus)) ? mStatus : code);
152 Delete();
153 return IPC_OK();
157 // nsIStreamListener
160 NS_IMETHODIMP
161 ExternalHelperAppParent::OnDataAvailable(nsIRequest* request,
162 nsIInputStream* input, uint64_t offset,
163 uint32_t count) {
164 return mListener->OnDataAvailable(request, input, offset, count);
167 NS_IMETHODIMP
168 ExternalHelperAppParent::OnStartRequest(nsIRequest* request) {
169 return mListener->OnStartRequest(request);
172 NS_IMETHODIMP
173 ExternalHelperAppParent::OnStopRequest(nsIRequest* request, nsresult status) {
174 nsresult rv = mListener->OnStopRequest(request, status);
175 Delete();
176 return rv;
179 ExternalHelperAppParent::~ExternalHelperAppParent() {}
182 // nsIRequest implementation...
185 NS_IMETHODIMP
186 ExternalHelperAppParent::GetName(nsACString& aResult) {
187 if (!mURI) {
188 aResult.Truncate();
189 return NS_ERROR_NOT_AVAILABLE;
191 mURI->GetAsciiSpec(aResult);
192 return NS_OK;
195 NS_IMETHODIMP
196 ExternalHelperAppParent::IsPending(bool* aResult) {
197 *aResult = mPending;
198 return NS_OK;
201 NS_IMETHODIMP
202 ExternalHelperAppParent::GetStatus(nsresult* aResult) {
203 *aResult = mStatus;
204 return NS_OK;
207 NS_IMETHODIMP ExternalHelperAppParent::SetCanceledReason(
208 const nsACString& aReason) {
209 return SetCanceledReasonImpl(aReason);
212 NS_IMETHODIMP ExternalHelperAppParent::GetCanceledReason(nsACString& aReason) {
213 return GetCanceledReasonImpl(aReason);
216 NS_IMETHODIMP ExternalHelperAppParent::CancelWithReason(
217 nsresult aStatus, const nsACString& aReason) {
218 return CancelWithReasonImpl(aStatus, aReason);
221 NS_IMETHODIMP
222 ExternalHelperAppParent::Cancel(nsresult aStatus) {
223 mCanceled = true;
224 mStatus = aStatus;
225 Unused << SendCancel(aStatus);
226 return NS_OK;
229 NS_IMETHODIMP
230 ExternalHelperAppParent::GetCanceled(bool* aCanceled) {
231 *aCanceled = mCanceled;
232 return NS_OK;
235 NS_IMETHODIMP
236 ExternalHelperAppParent::Suspend() { return NS_ERROR_NOT_IMPLEMENTED; }
238 NS_IMETHODIMP
239 ExternalHelperAppParent::Resume() { return NS_ERROR_NOT_IMPLEMENTED; }
242 // nsIChannel implementation
245 NS_IMETHODIMP
246 ExternalHelperAppParent::GetOriginalURI(nsIURI** aURI) {
247 NS_IF_ADDREF(*aURI = mURI);
248 return NS_OK;
251 NS_IMETHODIMP
252 ExternalHelperAppParent::SetOriginalURI(nsIURI* aURI) {
253 return NS_ERROR_NOT_IMPLEMENTED;
256 NS_IMETHODIMP
257 ExternalHelperAppParent::GetURI(nsIURI** aURI) {
258 NS_IF_ADDREF(*aURI = mURI);
259 return NS_OK;
262 NS_IMETHODIMP
263 ExternalHelperAppParent::Open(nsIInputStream** aResult) {
264 return NS_ERROR_NOT_IMPLEMENTED;
267 NS_IMETHODIMP
268 ExternalHelperAppParent::AsyncOpen(nsIStreamListener* aListener) {
269 return NS_ERROR_NOT_IMPLEMENTED;
272 NS_IMETHODIMP
273 ExternalHelperAppParent::GetLoadFlags(nsLoadFlags* aLoadFlags) {
274 *aLoadFlags = mLoadFlags;
275 return NS_OK;
278 NS_IMETHODIMP
279 ExternalHelperAppParent::SetLoadFlags(nsLoadFlags aLoadFlags) {
280 mLoadFlags = aLoadFlags;
281 return NS_OK;
284 NS_IMETHODIMP
285 ExternalHelperAppParent::GetTRRMode(nsIRequest::TRRMode* aTRRMode) {
286 return GetTRRModeImpl(aTRRMode);
289 NS_IMETHODIMP
290 ExternalHelperAppParent::SetTRRMode(nsIRequest::TRRMode aTRRMode) {
291 return SetTRRModeImpl(aTRRMode);
294 NS_IMETHODIMP
295 ExternalHelperAppParent::GetIsDocument(bool* aIsDocument) {
296 return NS_GetIsDocumentChannel(this, aIsDocument);
299 NS_IMETHODIMP
300 ExternalHelperAppParent::GetLoadGroup(nsILoadGroup** aLoadGroup) {
301 *aLoadGroup = nullptr;
302 return NS_OK;
305 NS_IMETHODIMP
306 ExternalHelperAppParent::SetLoadGroup(nsILoadGroup* aLoadGroup) {
307 return NS_ERROR_NOT_IMPLEMENTED;
310 NS_IMETHODIMP
311 ExternalHelperAppParent::GetOwner(nsISupports** aOwner) {
312 *aOwner = nullptr;
313 return NS_OK;
316 NS_IMETHODIMP
317 ExternalHelperAppParent::SetOwner(nsISupports* aOwner) {
318 return NS_ERROR_NOT_IMPLEMENTED;
321 NS_IMETHODIMP
322 ExternalHelperAppParent::GetLoadInfo(nsILoadInfo** aLoadInfo) {
323 NS_IF_ADDREF(*aLoadInfo = mLoadInfo);
324 return NS_OK;
327 NS_IMETHODIMP
328 ExternalHelperAppParent::SetLoadInfo(nsILoadInfo* aLoadInfo) {
329 return NS_ERROR_NOT_IMPLEMENTED;
332 NS_IMETHODIMP
333 ExternalHelperAppParent::GetNotificationCallbacks(
334 nsIInterfaceRequestor** aCallbacks) {
335 *aCallbacks = nullptr;
336 return NS_OK;
339 NS_IMETHODIMP
340 ExternalHelperAppParent::SetNotificationCallbacks(
341 nsIInterfaceRequestor* aCallbacks) {
342 return NS_ERROR_NOT_IMPLEMENTED;
345 NS_IMETHODIMP
346 ExternalHelperAppParent::GetSecurityInfo(
347 nsITransportSecurityInfo** aSecurityInfo) {
348 *aSecurityInfo = nullptr;
349 return NS_OK;
352 NS_IMETHODIMP
353 ExternalHelperAppParent::GetContentType(nsACString& aContentType) {
354 aContentType.Truncate();
355 return NS_OK;
358 NS_IMETHODIMP
359 ExternalHelperAppParent::SetContentType(const nsACString& aContentType) {
360 return NS_ERROR_NOT_IMPLEMENTED;
363 NS_IMETHODIMP
364 ExternalHelperAppParent::GetContentCharset(nsACString& aContentCharset) {
365 aContentCharset.Truncate();
366 return NS_OK;
369 NS_IMETHODIMP
370 ExternalHelperAppParent::SetContentCharset(const nsACString& aContentCharset) {
371 return NS_ERROR_NOT_IMPLEMENTED;
374 NS_IMETHODIMP
375 ExternalHelperAppParent::GetContentDisposition(uint32_t* aContentDisposition) {
376 // NB: mContentDisposition may or may not be set to a non UINT32_MAX value in
377 // nsExternalHelperAppService::DoContentContentProcessHelper
378 if (mContentDispositionHeader.IsEmpty() && mContentDisposition == UINT32_MAX)
379 return NS_ERROR_NOT_AVAILABLE;
381 *aContentDisposition = mContentDisposition;
382 return NS_OK;
385 NS_IMETHODIMP
386 ExternalHelperAppParent::SetContentDisposition(uint32_t aContentDisposition) {
387 mContentDisposition = aContentDisposition;
388 return NS_OK;
391 NS_IMETHODIMP
392 ExternalHelperAppParent::GetContentDispositionFilename(
393 nsAString& aContentDispositionFilename) {
394 if (mContentDispositionFilename.IsEmpty()) {
395 return NS_ERROR_NOT_AVAILABLE;
398 aContentDispositionFilename = mContentDispositionFilename;
399 return NS_OK;
402 NS_IMETHODIMP
403 ExternalHelperAppParent::SetContentDispositionFilename(
404 const nsAString& aContentDispositionFilename) {
405 mContentDispositionFilename = aContentDispositionFilename;
406 return NS_OK;
409 NS_IMETHODIMP
410 ExternalHelperAppParent::GetContentDispositionHeader(
411 nsACString& aContentDispositionHeader) {
412 if (mContentDispositionHeader.IsEmpty()) {
413 return NS_ERROR_NOT_AVAILABLE;
416 aContentDispositionHeader = mContentDispositionHeader;
417 return NS_OK;
420 NS_IMETHODIMP
421 ExternalHelperAppParent::GetContentLength(int64_t* aContentLength) {
422 if (mContentLength < 0) {
423 *aContentLength = -1;
424 } else {
425 *aContentLength = mContentLength;
427 return NS_OK;
430 NS_IMETHODIMP
431 ExternalHelperAppParent::SetContentLength(int64_t aContentLength) {
432 mContentLength = aContentLength;
433 return NS_OK;
437 // nsIResumableChannel implementation
440 NS_IMETHODIMP
441 ExternalHelperAppParent::ResumeAt(uint64_t startPos,
442 const nsACString& entityID) {
443 return NS_ERROR_NOT_IMPLEMENTED;
446 NS_IMETHODIMP
447 ExternalHelperAppParent::GetEntityID(nsACString& aEntityID) {
448 aEntityID = mEntityID;
449 return NS_OK;
453 // nsIMultiPartChannel implementation
456 NS_IMETHODIMP
457 ExternalHelperAppParent::GetBaseChannel(nsIChannel** aChannel) {
458 return NS_ERROR_NOT_IMPLEMENTED;
461 NS_IMETHODIMP
462 ExternalHelperAppParent::GetPartID(uint32_t* aPartID) {
463 return NS_ERROR_NOT_IMPLEMENTED;
466 NS_IMETHODIMP
467 ExternalHelperAppParent::GetIsFirstPart(bool* aIsLastPart) {
468 return NS_ERROR_NOT_IMPLEMENTED;
471 NS_IMETHODIMP
472 ExternalHelperAppParent::GetIsLastPart(bool* aIsLastPart) {
473 return NS_ERROR_NOT_IMPLEMENTED;
476 } // namespace dom
477 } // namespace mozilla