uriloader/exthandler/ExternalHelperAppParent.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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/TabParent.h"
    16 #include "nsIBrowserDOMWindow.h"
    17 #include "nsStringStream.h"
    18 #include "mozilla/ipc/URIUtils.h"
    19 #include "nsNetUtil.h"
    20 #include "nsIDocument.h"
    21 #include "mozilla/net/ChannelDiverterParent.h"
    23 #include "mozilla/unused.h"
    25 using namespace mozilla::ipc;
    27 namespace mozilla {
    28 namespace dom {
    30 NS_IMPL_ISUPPORTS_INHERITED(ExternalHelperAppParent,
    31                             nsHashPropertyBag,
    32                             nsIRequest,
    33                             nsIChannel,
    34                             nsIMultiPartChannel,
    35                             nsIResumableChannel,
    36                             nsIStreamListener)
    38 ExternalHelperAppParent::ExternalHelperAppParent(
    39     const OptionalURIParams& uri,
    40     const int64_t& aContentLength)
    41   : mURI(DeserializeURI(uri))
    42   , mPending(false)
    43   , mDiverted(false)
    44   , mIPCClosed(false)
    45   , mLoadFlags(0)
    46   , mStatus(NS_OK)
    47   , mContentLength(aContentLength)
    48 {
    49 }
    51 void
    52 ExternalHelperAppParent::Init(ContentParent *parent,
    53                               const nsCString& aMimeContentType,
    54                               const nsCString& aContentDispositionHeader,
    55                               const uint32_t& aContentDispositionHint,
    56                               const nsString& aContentDispositionFilename,
    57                               const bool& aForceSave,
    58                               const OptionalURIParams& aReferrer,
    59                               PBrowserParent* aBrowser)
    60 {
    61   nsCOMPtr<nsIExternalHelperAppService> helperAppService =
    62     do_GetService(NS_EXTERNALHELPERAPPSERVICE_CONTRACTID);
    63   NS_ASSERTION(helperAppService, "No Helper App Service!");
    65   nsCOMPtr<nsIURI> referrer = DeserializeURI(aReferrer);
    66   if (referrer)
    67     SetPropertyAsInterface(NS_LITERAL_STRING("docshell.internalReferrer"), referrer);
    69   mContentDispositionHeader = aContentDispositionHeader;
    70   if (!mContentDispositionHeader.IsEmpty()) {  
    71     NS_GetFilenameFromDisposition(mContentDispositionFilename, 
    72                                   mContentDispositionHeader, 
    73                                   mURI);
    74     mContentDisposition = 
    75       NS_GetContentDispositionFromHeader(mContentDispositionHeader, this);
    76   }
    77   else {
    78     mContentDisposition = aContentDispositionHint;
    79     mContentDispositionFilename = aContentDispositionFilename;
    80   }
    82   nsCOMPtr<nsIInterfaceRequestor> window;
    83   if (aBrowser) {
    84     TabParent* tabParent = static_cast<TabParent*>(aBrowser);
    85     if (tabParent->GetOwnerElement())
    86       window = do_QueryInterface(tabParent->GetOwnerElement()->OwnerDoc()->GetWindow());
    87   }
    89   helperAppService->DoContent(aMimeContentType, this, window,
    90                               aForceSave, getter_AddRefs(mListener));
    91 }
    93 void
    94 ExternalHelperAppParent::ActorDestroy(ActorDestroyReason why)
    95 {
    96   mIPCClosed = true;
    97 }
    99 void
   100 ExternalHelperAppParent::Delete()
   101 {
   102   if (!mIPCClosed) {
   103     unused << Send__delete__(this);
   104   }
   105 }
   107 bool
   108 ExternalHelperAppParent::RecvOnStartRequest(const nsCString& entityID)
   109 {
   110   MOZ_ASSERT(!mDiverted, "child forwarding callbacks after request was diverted");
   112   mEntityID = entityID;
   113   mPending = true;
   114   mStatus = mListener->OnStartRequest(this, nullptr);
   115   return true;
   116 }
   118 bool
   119 ExternalHelperAppParent::RecvOnDataAvailable(const nsCString& data,
   120                                              const uint64_t& offset,
   121                                              const uint32_t& count)
   122 {
   123   if (NS_FAILED(mStatus))
   124     return true;
   126   MOZ_ASSERT(!mDiverted, "child forwarding callbacks after request was diverted");
   127   MOZ_ASSERT(mPending, "must be pending!");
   129   nsCOMPtr<nsIInputStream> stringStream;
   130   DebugOnly<nsresult> rv = NS_NewByteInputStream(getter_AddRefs(stringStream), data.get(), count, NS_ASSIGNMENT_DEPEND);
   131   NS_ASSERTION(NS_SUCCEEDED(rv), "failed to create dependent string!");
   132   mStatus = mListener->OnDataAvailable(this, nullptr, stringStream, offset, count);
   134   return true;
   135 }
   137 bool
   138 ExternalHelperAppParent::RecvOnStopRequest(const nsresult& code)
   139 {
   140   MOZ_ASSERT(!mDiverted, "child forwarding callbacks after request was diverted");
   142   mPending = false;
   143   mListener->OnStopRequest(this, nullptr,
   144                            (NS_SUCCEEDED(code) && NS_FAILED(mStatus)) ? mStatus : code);
   145   Delete();
   146   return true;
   147 }
   149 bool
   150 ExternalHelperAppParent::RecvDivertToParentUsing(PChannelDiverterParent* diverter)
   151 {
   152   MOZ_ASSERT(diverter);
   153   auto p = static_cast<mozilla::net::ChannelDiverterParent*>(diverter);
   154   p->DivertTo(this);
   155   mDiverted = true;
   156   unused << p->Send__delete__(p);
   157   return true;
   158 }
   160 //
   161 // nsIStreamListener
   162 //
   164 NS_IMETHODIMP
   165 ExternalHelperAppParent::OnDataAvailable(nsIRequest *request,
   166                                          nsISupports *ctx,
   167                                          nsIInputStream *input,
   168                                          uint64_t offset,
   169                                          uint32_t count)
   170 {
   171   MOZ_ASSERT(mDiverted);
   172   return mListener->OnDataAvailable(request, ctx, input, offset, count);
   173 }
   175 NS_IMETHODIMP
   176 ExternalHelperAppParent::OnStartRequest(nsIRequest *request, nsISupports *ctx)
   177 {
   178   MOZ_ASSERT(mDiverted);
   179   return mListener->OnStartRequest(request, ctx);
   180 }
   182 NS_IMETHODIMP
   183 ExternalHelperAppParent::OnStopRequest(nsIRequest *request,
   184                                        nsISupports *ctx,
   185                                        nsresult status)
   186 {
   187   MOZ_ASSERT(mDiverted);
   188   nsresult rv = mListener->OnStopRequest(request, ctx, status);
   189   Delete();
   190   return rv;
   191 }
   193 ExternalHelperAppParent::~ExternalHelperAppParent()
   194 {
   195 }
   197 //
   198 // nsIRequest implementation...
   199 //
   201 NS_IMETHODIMP
   202 ExternalHelperAppParent::GetName(nsACString& aResult)
   203 {
   204   if (!mURI) {
   205     aResult.Truncate();
   206     return NS_ERROR_NOT_AVAILABLE;
   207   }
   208   mURI->GetAsciiSpec(aResult);
   209   return NS_OK;
   210 }
   212 NS_IMETHODIMP
   213 ExternalHelperAppParent::IsPending(bool *aResult)
   214 {
   215   *aResult = mPending;
   216   return NS_OK;
   217 }
   219 NS_IMETHODIMP
   220 ExternalHelperAppParent::GetStatus(nsresult *aResult)
   221 {
   222   *aResult = mStatus;
   223   return NS_OK;
   224 }
   226 NS_IMETHODIMP
   227 ExternalHelperAppParent::Cancel(nsresult aStatus)
   228 {
   229   mStatus = aStatus;
   230   unused << SendCancel(aStatus);
   231   return NS_OK;
   232 }
   234 NS_IMETHODIMP
   235 ExternalHelperAppParent::Suspend()
   236 {
   237   return NS_ERROR_NOT_IMPLEMENTED;
   238 }
   240 NS_IMETHODIMP
   241 ExternalHelperAppParent::Resume()
   242 {
   243   return NS_ERROR_NOT_IMPLEMENTED;
   244 }
   246 //
   247 // nsIChannel implementation
   248 //
   250 NS_IMETHODIMP
   251 ExternalHelperAppParent::GetOriginalURI(nsIURI * *aURI)
   252 {
   253   NS_IF_ADDREF(*aURI = mURI);
   254   return NS_OK;
   255 }
   257 NS_IMETHODIMP
   258 ExternalHelperAppParent::SetOriginalURI(nsIURI *aURI)
   259 {
   260   return NS_ERROR_NOT_IMPLEMENTED;
   261 }
   263 NS_IMETHODIMP
   264 ExternalHelperAppParent::GetURI(nsIURI **aURI)
   265 {
   266   NS_IF_ADDREF(*aURI = mURI);
   267   return NS_OK;
   268 }
   270 NS_IMETHODIMP
   271 ExternalHelperAppParent::Open(nsIInputStream **aResult)
   272 {
   273   return NS_ERROR_NOT_IMPLEMENTED;
   274 }
   276 NS_IMETHODIMP
   277 ExternalHelperAppParent::AsyncOpen(nsIStreamListener *aListener,
   278                                    nsISupports *aContext)
   279 {
   280   return NS_ERROR_NOT_IMPLEMENTED;
   281 }
   284 NS_IMETHODIMP
   285 ExternalHelperAppParent::GetLoadFlags(nsLoadFlags *aLoadFlags)
   286 {
   287   *aLoadFlags = mLoadFlags;
   288   return NS_OK;
   289 }
   291 NS_IMETHODIMP
   292 ExternalHelperAppParent::SetLoadFlags(nsLoadFlags aLoadFlags)
   293 {
   294   mLoadFlags = aLoadFlags;
   295   return NS_OK;
   296 }
   298 NS_IMETHODIMP
   299 ExternalHelperAppParent::GetLoadGroup(nsILoadGroup* *aLoadGroup)
   300 {
   301   *aLoadGroup = nullptr;
   302   return NS_OK;
   303 }
   305 NS_IMETHODIMP
   306 ExternalHelperAppParent::SetLoadGroup(nsILoadGroup* aLoadGroup)
   307 {
   308   return NS_ERROR_NOT_IMPLEMENTED;
   309 }
   311 NS_IMETHODIMP
   312 ExternalHelperAppParent::GetOwner(nsISupports* *aOwner)
   313 {
   314   *aOwner = nullptr;
   315   return NS_OK;
   316 }
   318 NS_IMETHODIMP
   319 ExternalHelperAppParent::SetOwner(nsISupports* aOwner)
   320 {
   321   return NS_ERROR_NOT_IMPLEMENTED;
   322 }
   324 NS_IMETHODIMP
   325 ExternalHelperAppParent::GetNotificationCallbacks(nsIInterfaceRequestor* *aCallbacks)
   326 {
   327   *aCallbacks = nullptr;
   328   return NS_OK;
   329 }
   331 NS_IMETHODIMP
   332 ExternalHelperAppParent::SetNotificationCallbacks(nsIInterfaceRequestor* aCallbacks)
   333 {
   334   return NS_ERROR_NOT_IMPLEMENTED;
   335 }
   337 NS_IMETHODIMP
   338 ExternalHelperAppParent::GetSecurityInfo(nsISupports * *aSecurityInfo)
   339 {
   340   *aSecurityInfo = nullptr;
   341   return NS_OK;
   342 }
   344 NS_IMETHODIMP
   345 ExternalHelperAppParent::GetContentType(nsACString& aContentType)
   346 {
   347   aContentType.Truncate();
   348   return NS_OK;
   349 }
   351 NS_IMETHODIMP
   352 ExternalHelperAppParent::SetContentType(const nsACString& aContentType)
   353 {
   354   return NS_ERROR_NOT_IMPLEMENTED;
   355 }
   357 NS_IMETHODIMP
   358 ExternalHelperAppParent::GetContentCharset(nsACString& aContentCharset)
   359 {
   360   aContentCharset.Truncate();
   361   return NS_OK;
   362 }
   364 NS_IMETHODIMP
   365 ExternalHelperAppParent::SetContentCharset(const nsACString& aContentCharset)
   366 {
   367   return NS_ERROR_NOT_IMPLEMENTED;
   368 }
   370 NS_IMETHODIMP
   371 ExternalHelperAppParent::GetContentDisposition(uint32_t *aContentDisposition)
   372 {
   373   if (mContentDispositionHeader.IsEmpty())
   374     return NS_ERROR_NOT_AVAILABLE;
   376   *aContentDisposition = mContentDisposition;
   377   return NS_OK;
   378 }
   380 NS_IMETHODIMP
   381 ExternalHelperAppParent::SetContentDisposition(uint32_t aContentDisposition)
   382 {
   383   mContentDisposition = aContentDisposition;
   384   return NS_OK;
   385 }
   387 NS_IMETHODIMP
   388 ExternalHelperAppParent::GetContentDispositionFilename(nsAString& aContentDispositionFilename)
   389 {
   390   if (mContentDispositionFilename.IsEmpty())
   391     return NS_ERROR_NOT_AVAILABLE;
   393   aContentDispositionFilename = mContentDispositionFilename;
   394   return NS_OK;
   395 }
   397 NS_IMETHODIMP
   398 ExternalHelperAppParent::SetContentDispositionFilename(const nsAString& aContentDispositionFilename)
   399 {
   400   mContentDispositionFilename = aContentDispositionFilename;
   401   return NS_OK;
   402 }
   404 NS_IMETHODIMP
   405 ExternalHelperAppParent::GetContentDispositionHeader(nsACString& aContentDispositionHeader)
   406 {
   407   if (mContentDispositionHeader.IsEmpty())
   408     return NS_ERROR_NOT_AVAILABLE;
   410   aContentDispositionHeader = mContentDispositionHeader;
   411   return NS_OK;
   412 }
   414 NS_IMETHODIMP
   415 ExternalHelperAppParent::GetContentLength(int64_t *aContentLength)
   416 {
   417   if (mContentLength < 0)
   418     *aContentLength = -1;
   419   else
   420     *aContentLength = mContentLength;
   421   return NS_OK;
   422 }
   424 NS_IMETHODIMP
   425 ExternalHelperAppParent::SetContentLength(int64_t aContentLength)
   426 {
   427   mContentLength = aContentLength;
   428   return NS_OK;
   429 }
   431 //
   432 // nsIResumableChannel implementation
   433 //
   435 NS_IMETHODIMP
   436 ExternalHelperAppParent::ResumeAt(uint64_t startPos, const nsACString& entityID)
   437 {
   438   return NS_ERROR_NOT_IMPLEMENTED;
   439 }
   441 NS_IMETHODIMP
   442 ExternalHelperAppParent::GetEntityID(nsACString& aEntityID)
   443 {
   444   aEntityID = mEntityID;
   445   return NS_OK;
   446 }
   448 //
   449 // nsIMultiPartChannel implementation
   450 //
   452 NS_IMETHODIMP
   453 ExternalHelperAppParent::GetBaseChannel(nsIChannel* *aChannel)
   454 {
   455   return NS_ERROR_NOT_IMPLEMENTED;
   456 }
   458 NS_IMETHODIMP
   459 ExternalHelperAppParent::GetPartID(uint32_t* aPartID)
   460 {
   461   return NS_ERROR_NOT_IMPLEMENTED;
   462 }
   464 NS_IMETHODIMP
   465 ExternalHelperAppParent::GetIsLastPart(bool* aIsLastPart)
   466 {
   467   return NS_ERROR_NOT_IMPLEMENTED;
   468 }
   470 } // namespace dom
   471 } // namespace mozilla

mercurial