1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/uriloader/exthandler/ExternalHelperAppParent.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,471 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "mozilla/DebugOnly.h" 1.11 + 1.12 +#include "ExternalHelperAppParent.h" 1.13 +#include "nsIContent.h" 1.14 +#include "nsCExternalHandlerService.h" 1.15 +#include "nsIExternalHelperAppService.h" 1.16 +#include "mozilla/dom/ContentParent.h" 1.17 +#include "mozilla/dom/Element.h" 1.18 +#include "mozilla/dom/TabParent.h" 1.19 +#include "nsIBrowserDOMWindow.h" 1.20 +#include "nsStringStream.h" 1.21 +#include "mozilla/ipc/URIUtils.h" 1.22 +#include "nsNetUtil.h" 1.23 +#include "nsIDocument.h" 1.24 +#include "mozilla/net/ChannelDiverterParent.h" 1.25 + 1.26 +#include "mozilla/unused.h" 1.27 + 1.28 +using namespace mozilla::ipc; 1.29 + 1.30 +namespace mozilla { 1.31 +namespace dom { 1.32 + 1.33 +NS_IMPL_ISUPPORTS_INHERITED(ExternalHelperAppParent, 1.34 + nsHashPropertyBag, 1.35 + nsIRequest, 1.36 + nsIChannel, 1.37 + nsIMultiPartChannel, 1.38 + nsIResumableChannel, 1.39 + nsIStreamListener) 1.40 + 1.41 +ExternalHelperAppParent::ExternalHelperAppParent( 1.42 + const OptionalURIParams& uri, 1.43 + const int64_t& aContentLength) 1.44 + : mURI(DeserializeURI(uri)) 1.45 + , mPending(false) 1.46 + , mDiverted(false) 1.47 + , mIPCClosed(false) 1.48 + , mLoadFlags(0) 1.49 + , mStatus(NS_OK) 1.50 + , mContentLength(aContentLength) 1.51 +{ 1.52 +} 1.53 + 1.54 +void 1.55 +ExternalHelperAppParent::Init(ContentParent *parent, 1.56 + const nsCString& aMimeContentType, 1.57 + const nsCString& aContentDispositionHeader, 1.58 + const uint32_t& aContentDispositionHint, 1.59 + const nsString& aContentDispositionFilename, 1.60 + const bool& aForceSave, 1.61 + const OptionalURIParams& aReferrer, 1.62 + PBrowserParent* aBrowser) 1.63 +{ 1.64 + nsCOMPtr<nsIExternalHelperAppService> helperAppService = 1.65 + do_GetService(NS_EXTERNALHELPERAPPSERVICE_CONTRACTID); 1.66 + NS_ASSERTION(helperAppService, "No Helper App Service!"); 1.67 + 1.68 + nsCOMPtr<nsIURI> referrer = DeserializeURI(aReferrer); 1.69 + if (referrer) 1.70 + SetPropertyAsInterface(NS_LITERAL_STRING("docshell.internalReferrer"), referrer); 1.71 + 1.72 + mContentDispositionHeader = aContentDispositionHeader; 1.73 + if (!mContentDispositionHeader.IsEmpty()) { 1.74 + NS_GetFilenameFromDisposition(mContentDispositionFilename, 1.75 + mContentDispositionHeader, 1.76 + mURI); 1.77 + mContentDisposition = 1.78 + NS_GetContentDispositionFromHeader(mContentDispositionHeader, this); 1.79 + } 1.80 + else { 1.81 + mContentDisposition = aContentDispositionHint; 1.82 + mContentDispositionFilename = aContentDispositionFilename; 1.83 + } 1.84 + 1.85 + nsCOMPtr<nsIInterfaceRequestor> window; 1.86 + if (aBrowser) { 1.87 + TabParent* tabParent = static_cast<TabParent*>(aBrowser); 1.88 + if (tabParent->GetOwnerElement()) 1.89 + window = do_QueryInterface(tabParent->GetOwnerElement()->OwnerDoc()->GetWindow()); 1.90 + } 1.91 + 1.92 + helperAppService->DoContent(aMimeContentType, this, window, 1.93 + aForceSave, getter_AddRefs(mListener)); 1.94 +} 1.95 + 1.96 +void 1.97 +ExternalHelperAppParent::ActorDestroy(ActorDestroyReason why) 1.98 +{ 1.99 + mIPCClosed = true; 1.100 +} 1.101 + 1.102 +void 1.103 +ExternalHelperAppParent::Delete() 1.104 +{ 1.105 + if (!mIPCClosed) { 1.106 + unused << Send__delete__(this); 1.107 + } 1.108 +} 1.109 + 1.110 +bool 1.111 +ExternalHelperAppParent::RecvOnStartRequest(const nsCString& entityID) 1.112 +{ 1.113 + MOZ_ASSERT(!mDiverted, "child forwarding callbacks after request was diverted"); 1.114 + 1.115 + mEntityID = entityID; 1.116 + mPending = true; 1.117 + mStatus = mListener->OnStartRequest(this, nullptr); 1.118 + return true; 1.119 +} 1.120 + 1.121 +bool 1.122 +ExternalHelperAppParent::RecvOnDataAvailable(const nsCString& data, 1.123 + const uint64_t& offset, 1.124 + const uint32_t& count) 1.125 +{ 1.126 + if (NS_FAILED(mStatus)) 1.127 + return true; 1.128 + 1.129 + MOZ_ASSERT(!mDiverted, "child forwarding callbacks after request was diverted"); 1.130 + MOZ_ASSERT(mPending, "must be pending!"); 1.131 + 1.132 + nsCOMPtr<nsIInputStream> stringStream; 1.133 + DebugOnly<nsresult> rv = NS_NewByteInputStream(getter_AddRefs(stringStream), data.get(), count, NS_ASSIGNMENT_DEPEND); 1.134 + NS_ASSERTION(NS_SUCCEEDED(rv), "failed to create dependent string!"); 1.135 + mStatus = mListener->OnDataAvailable(this, nullptr, stringStream, offset, count); 1.136 + 1.137 + return true; 1.138 +} 1.139 + 1.140 +bool 1.141 +ExternalHelperAppParent::RecvOnStopRequest(const nsresult& code) 1.142 +{ 1.143 + MOZ_ASSERT(!mDiverted, "child forwarding callbacks after request was diverted"); 1.144 + 1.145 + mPending = false; 1.146 + mListener->OnStopRequest(this, nullptr, 1.147 + (NS_SUCCEEDED(code) && NS_FAILED(mStatus)) ? mStatus : code); 1.148 + Delete(); 1.149 + return true; 1.150 +} 1.151 + 1.152 +bool 1.153 +ExternalHelperAppParent::RecvDivertToParentUsing(PChannelDiverterParent* diverter) 1.154 +{ 1.155 + MOZ_ASSERT(diverter); 1.156 + auto p = static_cast<mozilla::net::ChannelDiverterParent*>(diverter); 1.157 + p->DivertTo(this); 1.158 + mDiverted = true; 1.159 + unused << p->Send__delete__(p); 1.160 + return true; 1.161 +} 1.162 + 1.163 +// 1.164 +// nsIStreamListener 1.165 +// 1.166 + 1.167 +NS_IMETHODIMP 1.168 +ExternalHelperAppParent::OnDataAvailable(nsIRequest *request, 1.169 + nsISupports *ctx, 1.170 + nsIInputStream *input, 1.171 + uint64_t offset, 1.172 + uint32_t count) 1.173 +{ 1.174 + MOZ_ASSERT(mDiverted); 1.175 + return mListener->OnDataAvailable(request, ctx, input, offset, count); 1.176 +} 1.177 + 1.178 +NS_IMETHODIMP 1.179 +ExternalHelperAppParent::OnStartRequest(nsIRequest *request, nsISupports *ctx) 1.180 +{ 1.181 + MOZ_ASSERT(mDiverted); 1.182 + return mListener->OnStartRequest(request, ctx); 1.183 +} 1.184 + 1.185 +NS_IMETHODIMP 1.186 +ExternalHelperAppParent::OnStopRequest(nsIRequest *request, 1.187 + nsISupports *ctx, 1.188 + nsresult status) 1.189 +{ 1.190 + MOZ_ASSERT(mDiverted); 1.191 + nsresult rv = mListener->OnStopRequest(request, ctx, status); 1.192 + Delete(); 1.193 + return rv; 1.194 +} 1.195 + 1.196 +ExternalHelperAppParent::~ExternalHelperAppParent() 1.197 +{ 1.198 +} 1.199 + 1.200 +// 1.201 +// nsIRequest implementation... 1.202 +// 1.203 + 1.204 +NS_IMETHODIMP 1.205 +ExternalHelperAppParent::GetName(nsACString& aResult) 1.206 +{ 1.207 + if (!mURI) { 1.208 + aResult.Truncate(); 1.209 + return NS_ERROR_NOT_AVAILABLE; 1.210 + } 1.211 + mURI->GetAsciiSpec(aResult); 1.212 + return NS_OK; 1.213 +} 1.214 + 1.215 +NS_IMETHODIMP 1.216 +ExternalHelperAppParent::IsPending(bool *aResult) 1.217 +{ 1.218 + *aResult = mPending; 1.219 + return NS_OK; 1.220 +} 1.221 + 1.222 +NS_IMETHODIMP 1.223 +ExternalHelperAppParent::GetStatus(nsresult *aResult) 1.224 +{ 1.225 + *aResult = mStatus; 1.226 + return NS_OK; 1.227 +} 1.228 + 1.229 +NS_IMETHODIMP 1.230 +ExternalHelperAppParent::Cancel(nsresult aStatus) 1.231 +{ 1.232 + mStatus = aStatus; 1.233 + unused << SendCancel(aStatus); 1.234 + return NS_OK; 1.235 +} 1.236 + 1.237 +NS_IMETHODIMP 1.238 +ExternalHelperAppParent::Suspend() 1.239 +{ 1.240 + return NS_ERROR_NOT_IMPLEMENTED; 1.241 +} 1.242 + 1.243 +NS_IMETHODIMP 1.244 +ExternalHelperAppParent::Resume() 1.245 +{ 1.246 + return NS_ERROR_NOT_IMPLEMENTED; 1.247 +} 1.248 + 1.249 +// 1.250 +// nsIChannel implementation 1.251 +// 1.252 + 1.253 +NS_IMETHODIMP 1.254 +ExternalHelperAppParent::GetOriginalURI(nsIURI * *aURI) 1.255 +{ 1.256 + NS_IF_ADDREF(*aURI = mURI); 1.257 + return NS_OK; 1.258 +} 1.259 + 1.260 +NS_IMETHODIMP 1.261 +ExternalHelperAppParent::SetOriginalURI(nsIURI *aURI) 1.262 +{ 1.263 + return NS_ERROR_NOT_IMPLEMENTED; 1.264 +} 1.265 + 1.266 +NS_IMETHODIMP 1.267 +ExternalHelperAppParent::GetURI(nsIURI **aURI) 1.268 +{ 1.269 + NS_IF_ADDREF(*aURI = mURI); 1.270 + return NS_OK; 1.271 +} 1.272 + 1.273 +NS_IMETHODIMP 1.274 +ExternalHelperAppParent::Open(nsIInputStream **aResult) 1.275 +{ 1.276 + return NS_ERROR_NOT_IMPLEMENTED; 1.277 +} 1.278 + 1.279 +NS_IMETHODIMP 1.280 +ExternalHelperAppParent::AsyncOpen(nsIStreamListener *aListener, 1.281 + nsISupports *aContext) 1.282 +{ 1.283 + return NS_ERROR_NOT_IMPLEMENTED; 1.284 +} 1.285 + 1.286 + 1.287 +NS_IMETHODIMP 1.288 +ExternalHelperAppParent::GetLoadFlags(nsLoadFlags *aLoadFlags) 1.289 +{ 1.290 + *aLoadFlags = mLoadFlags; 1.291 + return NS_OK; 1.292 +} 1.293 + 1.294 +NS_IMETHODIMP 1.295 +ExternalHelperAppParent::SetLoadFlags(nsLoadFlags aLoadFlags) 1.296 +{ 1.297 + mLoadFlags = aLoadFlags; 1.298 + return NS_OK; 1.299 +} 1.300 + 1.301 +NS_IMETHODIMP 1.302 +ExternalHelperAppParent::GetLoadGroup(nsILoadGroup* *aLoadGroup) 1.303 +{ 1.304 + *aLoadGroup = nullptr; 1.305 + return NS_OK; 1.306 +} 1.307 + 1.308 +NS_IMETHODIMP 1.309 +ExternalHelperAppParent::SetLoadGroup(nsILoadGroup* aLoadGroup) 1.310 +{ 1.311 + return NS_ERROR_NOT_IMPLEMENTED; 1.312 +} 1.313 + 1.314 +NS_IMETHODIMP 1.315 +ExternalHelperAppParent::GetOwner(nsISupports* *aOwner) 1.316 +{ 1.317 + *aOwner = nullptr; 1.318 + return NS_OK; 1.319 +} 1.320 + 1.321 +NS_IMETHODIMP 1.322 +ExternalHelperAppParent::SetOwner(nsISupports* aOwner) 1.323 +{ 1.324 + return NS_ERROR_NOT_IMPLEMENTED; 1.325 +} 1.326 + 1.327 +NS_IMETHODIMP 1.328 +ExternalHelperAppParent::GetNotificationCallbacks(nsIInterfaceRequestor* *aCallbacks) 1.329 +{ 1.330 + *aCallbacks = nullptr; 1.331 + return NS_OK; 1.332 +} 1.333 + 1.334 +NS_IMETHODIMP 1.335 +ExternalHelperAppParent::SetNotificationCallbacks(nsIInterfaceRequestor* aCallbacks) 1.336 +{ 1.337 + return NS_ERROR_NOT_IMPLEMENTED; 1.338 +} 1.339 + 1.340 +NS_IMETHODIMP 1.341 +ExternalHelperAppParent::GetSecurityInfo(nsISupports * *aSecurityInfo) 1.342 +{ 1.343 + *aSecurityInfo = nullptr; 1.344 + return NS_OK; 1.345 +} 1.346 + 1.347 +NS_IMETHODIMP 1.348 +ExternalHelperAppParent::GetContentType(nsACString& aContentType) 1.349 +{ 1.350 + aContentType.Truncate(); 1.351 + return NS_OK; 1.352 +} 1.353 + 1.354 +NS_IMETHODIMP 1.355 +ExternalHelperAppParent::SetContentType(const nsACString& aContentType) 1.356 +{ 1.357 + return NS_ERROR_NOT_IMPLEMENTED; 1.358 +} 1.359 + 1.360 +NS_IMETHODIMP 1.361 +ExternalHelperAppParent::GetContentCharset(nsACString& aContentCharset) 1.362 +{ 1.363 + aContentCharset.Truncate(); 1.364 + return NS_OK; 1.365 +} 1.366 + 1.367 +NS_IMETHODIMP 1.368 +ExternalHelperAppParent::SetContentCharset(const nsACString& aContentCharset) 1.369 +{ 1.370 + return NS_ERROR_NOT_IMPLEMENTED; 1.371 +} 1.372 + 1.373 +NS_IMETHODIMP 1.374 +ExternalHelperAppParent::GetContentDisposition(uint32_t *aContentDisposition) 1.375 +{ 1.376 + if (mContentDispositionHeader.IsEmpty()) 1.377 + return NS_ERROR_NOT_AVAILABLE; 1.378 + 1.379 + *aContentDisposition = mContentDisposition; 1.380 + return NS_OK; 1.381 +} 1.382 + 1.383 +NS_IMETHODIMP 1.384 +ExternalHelperAppParent::SetContentDisposition(uint32_t aContentDisposition) 1.385 +{ 1.386 + mContentDisposition = aContentDisposition; 1.387 + return NS_OK; 1.388 +} 1.389 + 1.390 +NS_IMETHODIMP 1.391 +ExternalHelperAppParent::GetContentDispositionFilename(nsAString& aContentDispositionFilename) 1.392 +{ 1.393 + if (mContentDispositionFilename.IsEmpty()) 1.394 + return NS_ERROR_NOT_AVAILABLE; 1.395 + 1.396 + aContentDispositionFilename = mContentDispositionFilename; 1.397 + return NS_OK; 1.398 +} 1.399 + 1.400 +NS_IMETHODIMP 1.401 +ExternalHelperAppParent::SetContentDispositionFilename(const nsAString& aContentDispositionFilename) 1.402 +{ 1.403 + mContentDispositionFilename = aContentDispositionFilename; 1.404 + return NS_OK; 1.405 +} 1.406 + 1.407 +NS_IMETHODIMP 1.408 +ExternalHelperAppParent::GetContentDispositionHeader(nsACString& aContentDispositionHeader) 1.409 +{ 1.410 + if (mContentDispositionHeader.IsEmpty()) 1.411 + return NS_ERROR_NOT_AVAILABLE; 1.412 + 1.413 + aContentDispositionHeader = mContentDispositionHeader; 1.414 + return NS_OK; 1.415 +} 1.416 + 1.417 +NS_IMETHODIMP 1.418 +ExternalHelperAppParent::GetContentLength(int64_t *aContentLength) 1.419 +{ 1.420 + if (mContentLength < 0) 1.421 + *aContentLength = -1; 1.422 + else 1.423 + *aContentLength = mContentLength; 1.424 + return NS_OK; 1.425 +} 1.426 + 1.427 +NS_IMETHODIMP 1.428 +ExternalHelperAppParent::SetContentLength(int64_t aContentLength) 1.429 +{ 1.430 + mContentLength = aContentLength; 1.431 + return NS_OK; 1.432 +} 1.433 + 1.434 +// 1.435 +// nsIResumableChannel implementation 1.436 +// 1.437 + 1.438 +NS_IMETHODIMP 1.439 +ExternalHelperAppParent::ResumeAt(uint64_t startPos, const nsACString& entityID) 1.440 +{ 1.441 + return NS_ERROR_NOT_IMPLEMENTED; 1.442 +} 1.443 + 1.444 +NS_IMETHODIMP 1.445 +ExternalHelperAppParent::GetEntityID(nsACString& aEntityID) 1.446 +{ 1.447 + aEntityID = mEntityID; 1.448 + return NS_OK; 1.449 +} 1.450 + 1.451 +// 1.452 +// nsIMultiPartChannel implementation 1.453 +// 1.454 + 1.455 +NS_IMETHODIMP 1.456 +ExternalHelperAppParent::GetBaseChannel(nsIChannel* *aChannel) 1.457 +{ 1.458 + return NS_ERROR_NOT_IMPLEMENTED; 1.459 +} 1.460 + 1.461 +NS_IMETHODIMP 1.462 +ExternalHelperAppParent::GetPartID(uint32_t* aPartID) 1.463 +{ 1.464 + return NS_ERROR_NOT_IMPLEMENTED; 1.465 +} 1.466 + 1.467 +NS_IMETHODIMP 1.468 +ExternalHelperAppParent::GetIsLastPart(bool* aIsLastPart) 1.469 +{ 1.470 + return NS_ERROR_NOT_IMPLEMENTED; 1.471 +} 1.472 + 1.473 +} // namespace dom 1.474 +} // namespace mozilla