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 "nsIContent.h"
11 #include "nsCExternalHandlerService.h"
12 #include "nsIExternalHelperAppService.h"
13 #include "mozilla/dom/ContentParent.h"
14 #include "mozilla/dom/Element.h"
15 #include "mozilla/dom/BrowserParent.h"
16 #include "nsStringStream.h"
17 #include "mozilla/ipc/URIUtils.h"
18 #include "nsNetUtil.h"
19 #include "mozilla/dom/Document.h"
20 #include "mozilla/dom/CanonicalBrowsingContext.h"
21 #include "mozilla/dom/WindowGlobalParent.h"
22 #include "nsQueryObject.h"
24 #include "mozilla/Unused.h"
26 using namespace mozilla::ipc
;
31 NS_IMPL_ISUPPORTS_INHERITED(ExternalHelperAppParent
, nsHashPropertyBag
,
32 nsIRequest
, nsIChannel
, nsIMultiPartChannel
,
33 nsIPrivateBrowsingChannel
, nsIResumableChannel
,
34 nsIStreamListener
, nsIExternalHelperAppParent
)
36 ExternalHelperAppParent::ExternalHelperAppParent(
37 nsIURI
* uri
, const int64_t& aContentLength
, const bool& aWasFileChannel
,
38 const nsCString
& aContentDispositionHeader
,
39 const uint32_t& aContentDispositionHint
,
40 const nsString
& aContentDispositionFilename
)
47 mContentLength(aContentLength
),
48 mWasFileChannel(aWasFileChannel
) {
49 mContentDispositionHeader
= aContentDispositionHeader
;
50 if (!mContentDispositionHeader
.IsEmpty()) {
51 NS_GetFilenameFromDisposition(mContentDispositionFilename
,
52 mContentDispositionHeader
);
54 NS_GetContentDispositionFromHeader(mContentDispositionHeader
, this);
56 mContentDisposition
= aContentDispositionHint
;
57 mContentDispositionFilename
= aContentDispositionFilename
;
61 void ExternalHelperAppParent::Init(
62 const Maybe
<mozilla::net::LoadInfoArgs
>& aLoadInfoArgs
,
63 const nsCString
& aMimeContentType
, const bool& aForceSave
,
64 nsIURI
* aReferrer
, BrowsingContext
* aContext
,
65 const bool& aShouldCloseWindow
) {
66 mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfoArgs
,
67 getter_AddRefs(mLoadInfo
));
69 nsCOMPtr
<nsIExternalHelperAppService
> helperAppService
=
70 do_GetService(NS_EXTERNALHELPERAPPSERVICE_CONTRACTID
);
71 NS_ASSERTION(helperAppService
, "No Helper App Service!");
74 SetPropertyAsInterface(u
"docshell.internalReferrer"_ns
, aReferrer
);
78 WindowGlobalParent
* parent
=
79 aContext
->Canonical()->GetCurrentWindowGlobal();
81 RefPtr
<BrowserParent
> browser
= parent
->GetBrowserParent();
83 bool isPrivate
= false;
84 nsCOMPtr
<nsILoadContext
> loadContext
= browser
->GetLoadContext();
85 loadContext
->GetUsePrivateBrowsing(&isPrivate
);
86 SetPrivate(isPrivate
);
91 helperAppService
->CreateListener(aMimeContentType
, this, aContext
, aForceSave
,
92 nullptr, getter_AddRefs(mListener
));
93 if (aShouldCloseWindow
) {
94 RefPtr
<nsExternalAppHandler
> handler
= do_QueryObject(mListener
);
96 handler
->SetShouldCloseWindow();
101 void ExternalHelperAppParent::ActorDestroy(ActorDestroyReason why
) {
105 void ExternalHelperAppParent::Delete() {
107 Unused
<< Send__delete__(this);
111 mozilla::ipc::IPCResult
ExternalHelperAppParent::RecvOnStartRequest(
112 const nsCString
& entityID
) {
113 mEntityID
= entityID
;
115 mStatus
= mListener
->OnStartRequest(this);
119 mozilla::ipc::IPCResult
ExternalHelperAppParent::RecvOnDataAvailable(
120 const nsCString
& data
, const uint64_t& offset
, const uint32_t& count
) {
121 if (NS_FAILED(mStatus
)) {
125 MOZ_ASSERT(mPending
, "must be pending!");
127 nsCOMPtr
<nsIInputStream
> stringStream
;
128 DebugOnly
<nsresult
> rv
= NS_NewByteInputStream(
129 getter_AddRefs(stringStream
), Span(data
).To(count
), NS_ASSIGNMENT_DEPEND
);
130 NS_ASSERTION(NS_SUCCEEDED(rv
), "failed to create dependent string!");
131 mStatus
= mListener
->OnDataAvailable(this, stringStream
, offset
, count
);
136 mozilla::ipc::IPCResult
ExternalHelperAppParent::RecvOnStopRequest(
137 const nsresult
& code
) {
139 mListener
->OnStopRequest(
140 this, (NS_SUCCEEDED(code
) && NS_FAILED(mStatus
)) ? mStatus
: code
);
150 ExternalHelperAppParent::OnDataAvailable(nsIRequest
* request
,
151 nsIInputStream
* input
, uint64_t offset
,
153 return mListener
->OnDataAvailable(request
, input
, offset
, count
);
157 ExternalHelperAppParent::OnStartRequest(nsIRequest
* request
) {
158 return mListener
->OnStartRequest(request
);
162 ExternalHelperAppParent::OnStopRequest(nsIRequest
* request
, nsresult status
) {
163 nsresult rv
= mListener
->OnStopRequest(request
, status
);
168 ExternalHelperAppParent::~ExternalHelperAppParent() {}
171 // nsIRequest implementation...
175 ExternalHelperAppParent::GetName(nsACString
& aResult
) {
178 return NS_ERROR_NOT_AVAILABLE
;
180 mURI
->GetAsciiSpec(aResult
);
185 ExternalHelperAppParent::IsPending(bool* aResult
) {
191 ExternalHelperAppParent::GetStatus(nsresult
* aResult
) {
197 ExternalHelperAppParent::Cancel(nsresult aStatus
) {
200 Unused
<< SendCancel(aStatus
);
205 ExternalHelperAppParent::GetCanceled(bool* aCanceled
) {
206 *aCanceled
= mCanceled
;
211 ExternalHelperAppParent::Suspend() { return NS_ERROR_NOT_IMPLEMENTED
; }
214 ExternalHelperAppParent::Resume() { return NS_ERROR_NOT_IMPLEMENTED
; }
217 // nsIChannel implementation
221 ExternalHelperAppParent::GetOriginalURI(nsIURI
** aURI
) {
222 NS_IF_ADDREF(*aURI
= mURI
);
227 ExternalHelperAppParent::SetOriginalURI(nsIURI
* aURI
) {
228 return NS_ERROR_NOT_IMPLEMENTED
;
232 ExternalHelperAppParent::GetURI(nsIURI
** aURI
) {
233 NS_IF_ADDREF(*aURI
= mURI
);
238 ExternalHelperAppParent::Open(nsIInputStream
** aResult
) {
239 return NS_ERROR_NOT_IMPLEMENTED
;
243 ExternalHelperAppParent::AsyncOpen(nsIStreamListener
* aListener
) {
244 return NS_ERROR_NOT_IMPLEMENTED
;
248 ExternalHelperAppParent::GetLoadFlags(nsLoadFlags
* aLoadFlags
) {
249 *aLoadFlags
= mLoadFlags
;
254 ExternalHelperAppParent::SetLoadFlags(nsLoadFlags aLoadFlags
) {
255 mLoadFlags
= aLoadFlags
;
260 ExternalHelperAppParent::GetTRRMode(nsIRequest::TRRMode
* aTRRMode
) {
261 return GetTRRModeImpl(aTRRMode
);
265 ExternalHelperAppParent::SetTRRMode(nsIRequest::TRRMode aTRRMode
) {
266 return SetTRRModeImpl(aTRRMode
);
270 ExternalHelperAppParent::GetIsDocument(bool* aIsDocument
) {
271 return NS_GetIsDocumentChannel(this, aIsDocument
);
275 ExternalHelperAppParent::GetLoadGroup(nsILoadGroup
** aLoadGroup
) {
276 *aLoadGroup
= nullptr;
281 ExternalHelperAppParent::SetLoadGroup(nsILoadGroup
* aLoadGroup
) {
282 return NS_ERROR_NOT_IMPLEMENTED
;
286 ExternalHelperAppParent::GetOwner(nsISupports
** aOwner
) {
292 ExternalHelperAppParent::SetOwner(nsISupports
* aOwner
) {
293 return NS_ERROR_NOT_IMPLEMENTED
;
297 ExternalHelperAppParent::GetLoadInfo(nsILoadInfo
** aLoadInfo
) {
298 NS_IF_ADDREF(*aLoadInfo
= mLoadInfo
);
303 ExternalHelperAppParent::SetLoadInfo(nsILoadInfo
* aLoadInfo
) {
304 return NS_ERROR_NOT_IMPLEMENTED
;
308 ExternalHelperAppParent::GetNotificationCallbacks(
309 nsIInterfaceRequestor
** aCallbacks
) {
310 *aCallbacks
= nullptr;
315 ExternalHelperAppParent::SetNotificationCallbacks(
316 nsIInterfaceRequestor
* aCallbacks
) {
317 return NS_ERROR_NOT_IMPLEMENTED
;
321 ExternalHelperAppParent::GetSecurityInfo(nsISupports
** aSecurityInfo
) {
322 *aSecurityInfo
= nullptr;
327 ExternalHelperAppParent::GetContentType(nsACString
& aContentType
) {
328 aContentType
.Truncate();
333 ExternalHelperAppParent::SetContentType(const nsACString
& aContentType
) {
334 return NS_ERROR_NOT_IMPLEMENTED
;
338 ExternalHelperAppParent::GetContentCharset(nsACString
& aContentCharset
) {
339 aContentCharset
.Truncate();
344 ExternalHelperAppParent::SetContentCharset(const nsACString
& aContentCharset
) {
345 return NS_ERROR_NOT_IMPLEMENTED
;
349 ExternalHelperAppParent::GetContentDisposition(uint32_t* aContentDisposition
) {
350 // NB: mContentDisposition may or may not be set to a non UINT32_MAX value in
351 // nsExternalHelperAppService::DoContentContentProcessHelper
352 if (mContentDispositionHeader
.IsEmpty() && mContentDisposition
== UINT32_MAX
)
353 return NS_ERROR_NOT_AVAILABLE
;
355 *aContentDisposition
= mContentDisposition
;
360 ExternalHelperAppParent::SetContentDisposition(uint32_t aContentDisposition
) {
361 mContentDisposition
= aContentDisposition
;
366 ExternalHelperAppParent::GetContentDispositionFilename(
367 nsAString
& aContentDispositionFilename
) {
368 if (mContentDispositionFilename
.IsEmpty()) {
369 return NS_ERROR_NOT_AVAILABLE
;
372 aContentDispositionFilename
= mContentDispositionFilename
;
377 ExternalHelperAppParent::SetContentDispositionFilename(
378 const nsAString
& aContentDispositionFilename
) {
379 mContentDispositionFilename
= aContentDispositionFilename
;
384 ExternalHelperAppParent::GetContentDispositionHeader(
385 nsACString
& aContentDispositionHeader
) {
386 if (mContentDispositionHeader
.IsEmpty()) {
387 return NS_ERROR_NOT_AVAILABLE
;
390 aContentDispositionHeader
= mContentDispositionHeader
;
395 ExternalHelperAppParent::GetContentLength(int64_t* aContentLength
) {
396 if (mContentLength
< 0) {
397 *aContentLength
= -1;
399 *aContentLength
= mContentLength
;
405 ExternalHelperAppParent::SetContentLength(int64_t aContentLength
) {
406 mContentLength
= aContentLength
;
411 // nsIResumableChannel implementation
415 ExternalHelperAppParent::ResumeAt(uint64_t startPos
,
416 const nsACString
& entityID
) {
417 return NS_ERROR_NOT_IMPLEMENTED
;
421 ExternalHelperAppParent::GetEntityID(nsACString
& aEntityID
) {
422 aEntityID
= mEntityID
;
427 // nsIMultiPartChannel implementation
431 ExternalHelperAppParent::GetBaseChannel(nsIChannel
** aChannel
) {
432 return NS_ERROR_NOT_IMPLEMENTED
;
436 ExternalHelperAppParent::GetPartID(uint32_t* aPartID
) {
437 return NS_ERROR_NOT_IMPLEMENTED
;
441 ExternalHelperAppParent::GetIsLastPart(bool* aIsLastPart
) {
442 return NS_ERROR_NOT_IMPLEMENTED
;
446 } // namespace mozilla