LCOV - app.info - content/base/src/nsBlobProtocolHandler.cpp

LCOV - code coverage report
| Current view: | directory - content/base/src - nsBlobProtocolHandler.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 165 | 118 | 71.5 %
| Date: | 2012-04-21 | Functions: | 37 | 25 | 67.6 %

           1                 : /* ***** BEGIN LICENSE BLOCK *****
           2                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           3                 :  *
           4                 :  * The contents of this file are subject to the Mozilla Public License Version
           5                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           6                 :  * the License. You may obtain a copy of the License at
           7                 :  * http://www.mozilla.org/MPL/
           8                 :  *
           9                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          10                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          11                 :  * for the specific language governing rights and limitations under the
          12                 :  * License.
          13                 :  *
          14                 :  * The Original Code is mozilla.org code.
          15                 :  *
          16                 :  * The Initial Developer of the Original Code is
          17                 :  * Mozilla Foundation.
          18                 :  * Portions created by the Initial Developer are Copyright (C) 2010
          19                 :  * the Initial Developer. All Rights Reserved.
          20                 :  *
          21                 :  * Contributor(s):
          22                 :  *
          23                 :  * Alternatively, the contents of this file may be used under the terms of
          24                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
          25                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          26                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          27                 :  * of those above. If you wish to allow use of your version of this file only
          28                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          29                 :  * use your version of this file under the terms of the MPL, indicate your
          30                 :  * decision by deleting the provisions above and replace them with the notice
          31                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          32                 :  * the provisions above, a recipient may use your version of this file under
          33                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          34                 :  *
          35                 :  * ***** END LICENSE BLOCK ***** */
          36                 :
          37                 : #include "nsBlobProtocolHandler.h"
          38                 : #include "nsSimpleURI.h"
          39                 : #include "nsDOMError.h"
          40                 : #include "nsCOMPtr.h"
          41                 : #include "nsClassHashtable.h"
          42                 : #include "nsNetUtil.h"
          43                 : #include "nsIURIWithPrincipal.h"
          44                 : #include "nsIPrincipal.h"
          45                 : #include "nsIDOMFile.h"
          46                 : #include "nsISerializable.h"
          47                 : #include "nsIClassInfo.h"
          48                 : #include "nsIObjectInputStream.h"
          49                 : #include "nsIObjectOutputStream.h"
          50                 : #include "nsIProgrammingLanguage.h"
          51                 :
          52                 : // -----------------------------------------------------------------------
          53                 : // Hash table
          54                 : struct FileDataInfo
          55               4 : {
          56                 :   nsCOMPtr<nsIDOMBlob> mFile;
          57                 :   nsCOMPtr<nsIPrincipal> mPrincipal;
          58                 : };
          59                 :
          60                 : static nsClassHashtable<nsCStringHashKey, FileDataInfo>* gFileDataTable;
          61                 :
          62                 : void
          63               2 : nsBlobProtocolHandler::AddFileDataEntry(nsACString& aUri,
          64                 :                                             nsIDOMBlob* aFile,
          65                 :                                             nsIPrincipal* aPrincipal)
          66                 : {
          67               2 :   if (!gFileDataTable) {
          68               2 :     gFileDataTable = new nsClassHashtable<nsCStringHashKey, FileDataInfo>;
          69               2 :     gFileDataTable->Init();
          70                 :   }
          71                 :
          72               2 :   FileDataInfo* info = new FileDataInfo;
          73                 :
          74               2 :   info->mFile = aFile;
          75               2 :   info->mPrincipal = aPrincipal;
          76                 :
          77               2 :   gFileDataTable->Put(aUri, info);
          78               2 : }
          79                 :
          80                 : void
          81               2 : nsBlobProtocolHandler::RemoveFileDataEntry(nsACString& aUri)
          82                 : {
          83               2 :   if (gFileDataTable) {
          84               2 :     gFileDataTable->Remove(aUri);
          85               2 :     if (gFileDataTable->Count() == 0) {
          86               2 :       delete gFileDataTable;
          87               2 :       gFileDataTable = nsnull;
          88                 :     }
          89                 :   }
          90               2 : }
          91                 :
          92                 : nsIPrincipal*
          93               0 : nsBlobProtocolHandler::GetFileDataEntryPrincipal(nsACString& aUri)
          94                 : {
          95               0 :   if (!gFileDataTable) {
          96               0 :     return nsnull;
          97                 :   }
          98                 :
          99                 :   FileDataInfo* res;
         100               0 :   gFileDataTable->Get(aUri, &res);
         101               0 :   if (!res) {
         102               0 :     return nsnull;
         103                 :   }
         104                 :
         105               0 :   return res->mPrincipal;
         106                 : }
         107                 :
         108                 : static FileDataInfo*
         109              17 : GetFileDataInfo(const nsACString& aUri)
         110                 : {
         111              17 :   NS_ASSERTION(StringBeginsWith(aUri,
         112                 :                                 NS_LITERAL_CSTRING(BLOBURI_SCHEME ":")),
         113                 :                "Bad URI");
         114                 :
         115              17 :   if (!gFileDataTable) {
         116              13 :     return nsnull;
         117                 :   }
         118                 :
         119                 :   FileDataInfo* res;
         120               4 :   gFileDataTable->Get(aUri, &res);
         121               4 :   return res;
         122                 : }
         123                 :
         124                 : // -----------------------------------------------------------------------
         125                 : // Uri
         126                 :
         127                 : #define NS_BLOBURI_CID \
         128                 : { 0xf5475c51, 0x59a7, 0x4757, \
         129                 :   { 0xb3, 0xd9, 0xe2, 0x11, 0xa9, 0x41, 0x08, 0x72 } }
         130                 :
         131                 : static NS_DEFINE_CID(kBLOBURICID, NS_BLOBURI_CID);
         132                 :
         133                 : class nsBlobURI : public nsSimpleURI,
         134                 :                       public nsIURIWithPrincipal
         135                 : {
         136                 : public:
         137              15 :   nsBlobURI(nsIPrincipal* aPrincipal) :
         138              15 :       nsSimpleURI(), mPrincipal(aPrincipal)
         139              15 :   {}
         140             108 :   virtual ~nsBlobURI() {}
         141                 :
         142                 :   // For use only from deserialization
         143              12 :   nsBlobURI() : nsSimpleURI() {}
         144                 :
         145                 :   NS_DECL_ISUPPORTS_INHERITED
         146                 :   NS_DECL_NSIURIWITHPRINCIPAL
         147                 :   NS_DECL_NSISERIALIZABLE
         148                 :   NS_DECL_NSICLASSINFO
         149                 :
         150                 :   // Override CloneInternal() and EqualsInternal()
         151                 :   virtual nsresult CloneInternal(RefHandlingEnum aRefHandlingMode,
         152                 :                                  nsIURI** aClone);
         153                 :   virtual nsresult EqualsInternal(nsIURI* aOther,
         154                 :                                   RefHandlingEnum aRefHandlingMode,
         155                 :                                   bool* aResult);
         156                 :
         157                 :   // Override StartClone to hand back a nsBlobURI
         158              12 :   virtual nsSimpleURI* StartClone(RefHandlingEnum /* unused */)
         159              12 :   { return new nsBlobURI(); }
         160                 :
         161                 :   nsCOMPtr<nsIPrincipal> mPrincipal;
         162                 : };
         163                 :
         164                 : static NS_DEFINE_CID(kThisSimpleURIImplementationCID,
         165                 :                      NS_THIS_SIMPLEURI_IMPLEMENTATION_CID);
         166                 :
         167             347 : NS_IMPL_ADDREF_INHERITED(nsBlobURI, nsSimpleURI)
         168             347 : NS_IMPL_RELEASE_INHERITED(nsBlobURI, nsSimpleURI)
         169                 :
         170             447 : NS_INTERFACE_MAP_BEGIN(nsBlobURI)
         171             447 :   NS_INTERFACE_MAP_ENTRY(nsIURIWithPrincipal)
         172             445 :   if (aIID.Equals(kBLOBURICID))
         173              78 :     foundInterface = static_cast<nsIURI*>(this);
         174             367 :   else if (aIID.Equals(kThisSimpleURIImplementationCID)) {
         175                 :     // Need to return explicitly here, because if we just set foundInterface
         176                 :     // to null the NS_INTERFACE_MAP_END_INHERITING will end up calling into
         177                 :     // nsSimplURI::QueryInterface and finding something for this CID.
         178               4 :     *aInstancePtr = nsnull;
         179               4 :     return NS_NOINTERFACE;
         180                 :   }
         181                 :   else
         182             363 : NS_INTERFACE_MAP_END_INHERITING(nsSimpleURI)
         183                 :
         184                 : // nsIURIWithPrincipal methods:
         185                 :
         186                 : NS_IMETHODIMP
         187               2 : nsBlobURI::GetPrincipal(nsIPrincipal** aPrincipal)
         188                 : {
         189               2 :   NS_IF_ADDREF(*aPrincipal = mPrincipal);
         190                 :
         191               2 :   return NS_OK;
         192                 : }
         193                 :
         194                 : NS_IMETHODIMP
         195               0 : nsBlobURI::GetPrincipalUri(nsIURI** aUri)
         196                 : {
         197               0 :   if (mPrincipal) {
         198               0 :     mPrincipal->GetURI(aUri);
         199                 :   }
         200                 :   else {
         201               0 :     *aUri = nsnull;
         202                 :   }
         203                 :
         204               0 :   return NS_OK;
         205                 : }
         206                 :
         207                 : // nsISerializable methods:
         208                 :
         209                 : NS_IMETHODIMP
         210               0 : nsBlobURI::Read(nsIObjectInputStream* aStream)
         211                 : {
         212               0 :   nsresult rv = nsSimpleURI::Read(aStream);
         213               0 :   NS_ENSURE_SUCCESS(rv, rv);
         214                 :
         215               0 :   return NS_ReadOptionalObject(aStream, true, getter_AddRefs(mPrincipal));
         216                 : }
         217                 :
         218                 : NS_IMETHODIMP
         219               0 : nsBlobURI::Write(nsIObjectOutputStream* aStream)
         220                 : {
         221               0 :   nsresult rv = nsSimpleURI::Write(aStream);
         222               0 :   NS_ENSURE_SUCCESS(rv, rv);
         223                 :
         224                 :   return NS_WriteOptionalCompoundObject(aStream, mPrincipal,
         225                 :                                         NS_GET_IID(nsIPrincipal),
         226               0 :                                         true);
         227                 : }
         228                 :
         229                 : // nsIURI methods:
         230                 : nsresult
         231              12 : nsBlobURI::CloneInternal(nsSimpleURI::RefHandlingEnum aRefHandlingMode,
         232                 :                              nsIURI** aClone)
         233                 : {
         234              24 :   nsCOMPtr<nsIURI> simpleClone;
         235                 :   nsresult rv =
         236              12 :     nsSimpleURI::CloneInternal(aRefHandlingMode, getter_AddRefs(simpleClone));
         237              12 :   NS_ENSURE_SUCCESS(rv, rv);
         238                 :
         239                 : #ifdef DEBUG
         240              24 :   nsRefPtr<nsBlobURI> uriCheck;
         241              12 :   rv = simpleClone->QueryInterface(kBLOBURICID, getter_AddRefs(uriCheck));
         242              12 :   NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv) && uriCheck,
         243                 :                     "Unexpected!");
         244                 : #endif
         245                 :
         246              12 :   nsBlobURI* blobURI = static_cast<nsBlobURI*>(simpleClone.get());
         247                 :
         248              12 :   blobURI->mPrincipal = mPrincipal;
         249                 :
         250              12 :   simpleClone.forget(aClone);
         251              12 :   return NS_OK;
         252                 : }
         253                 :
         254                 : /* virtual */ nsresult
         255              71 : nsBlobURI::EqualsInternal(nsIURI* aOther,
         256                 :                               nsSimpleURI::RefHandlingEnum aRefHandlingMode,
         257                 :                               bool* aResult)
         258                 : {
         259              71 :   if (!aOther) {
         260               1 :     *aResult = false;
         261               1 :     return NS_OK;
         262                 :   }
         263                 :
         264             140 :   nsRefPtr<nsBlobURI> otherBlobUri;
         265              70 :   aOther->QueryInterface(kBLOBURICID, getter_AddRefs(otherBlobUri));
         266              70 :   if (!otherBlobUri) {
         267               4 :     *aResult = false;
         268               4 :     return NS_OK;
         269                 :   }
         270                 :
         271                 :   // Compare the member data that our base class knows about.
         272              66 :   if (!nsSimpleURI::EqualsInternal(otherBlobUri, aRefHandlingMode)) {
         273              10 :     *aResult = false;
         274              10 :     return NS_OK;
         275                 :    }
         276                 :
         277                 :   // Compare the piece of additional member data that we add to base class.
         278              56 :   if (mPrincipal && otherBlobUri->mPrincipal) {
         279                 :     // Both of us have mPrincipals. Compare them.
         280               0 :     return mPrincipal->Equals(otherBlobUri->mPrincipal, aResult);
         281                 :   }
         282                 :   // else, at least one of us lacks a principal; only equal if *both* lack it.
         283              56 :   *aResult = (!mPrincipal && !otherBlobUri->mPrincipal);
         284              56 :   return NS_OK;
         285                 : }
         286                 :
         287                 : // nsIClassInfo methods:
         288                 : NS_IMETHODIMP
         289              25 : nsBlobURI::GetInterfaces(PRUint32 *count, nsIID * **array)
         290                 : {
         291              25 :   *count = 0;
         292              25 :   *array = nsnull;
         293              25 :   return NS_OK;
         294                 : }
         295                 :
         296                 : NS_IMETHODIMP
         297              25 : nsBlobURI::GetHelperForLanguage(PRUint32 language, nsISupports **_retval)
         298                 : {
         299              25 :   *_retval = nsnull;
         300              25 :   return NS_OK;
         301                 : }
         302                 :
         303                 : NS_IMETHODIMP
         304               0 : nsBlobURI::GetContractID(char * *aContractID)
         305                 : {
         306                 :   // Make sure to modify any subclasses as needed if this ever
         307                 :   // changes.
         308               0 :   *aContractID = nsnull;
         309               0 :   return NS_OK;
         310                 : }
         311                 :
         312                 : NS_IMETHODIMP
         313               0 : nsBlobURI::GetClassDescription(char * *aClassDescription)
         314                 : {
         315               0 :   *aClassDescription = nsnull;
         316               0 :   return NS_OK;
         317                 : }
         318                 :
         319                 : NS_IMETHODIMP
         320               0 : nsBlobURI::GetClassID(nsCID * *aClassID)
         321                 : {
         322                 :   // Make sure to modify any subclasses as needed if this ever
         323                 :   // changes to not call the virtual GetClassIDNoAlloc.
         324               0 :   *aClassID = (nsCID*) nsMemory::Alloc(sizeof(nsCID));
         325               0 :   NS_ENSURE_TRUE(*aClassID, NS_ERROR_OUT_OF_MEMORY);
         326                 :
         327               0 :   return GetClassIDNoAlloc(*aClassID);
         328                 : }
         329                 :
         330                 : NS_IMETHODIMP
         331               0 : nsBlobURI::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
         332                 : {
         333               0 :   *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
         334               0 :   return NS_OK;
         335                 : }
         336                 :
         337                 : NS_IMETHODIMP
         338              25 : nsBlobURI::GetFlags(PRUint32 *aFlags)
         339                 : {
         340              25 :   *aFlags = nsIClassInfo::MAIN_THREAD_ONLY;
         341              25 :   return NS_OK;
         342                 : }
         343                 :
         344                 : NS_IMETHODIMP
         345               0 : nsBlobURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
         346                 : {
         347               0 :   *aClassIDNoAlloc = kBLOBURICID;
         348               0 :   return NS_OK;
         349                 : }
         350                 :
         351                 : // -----------------------------------------------------------------------
         352                 : // Protocol handler
         353                 :
         354             148 : NS_IMPL_ISUPPORTS1(nsBlobProtocolHandler, nsIProtocolHandler)
         355                 :
         356                 : NS_IMETHODIMP
         357               0 : nsBlobProtocolHandler::GetScheme(nsACString &result)
         358                 : {
         359               0 :   result.AssignLiteral(BLOBURI_SCHEME);
         360               0 :   return NS_OK;
         361                 : }
         362                 :
         363                 : NS_IMETHODIMP
         364               0 : nsBlobProtocolHandler::GetDefaultPort(PRInt32 *result)
         365                 : {
         366               0 :   *result = -1;
         367               0 :   return NS_OK;
         368                 : }
         369                 :
         370                 : NS_IMETHODIMP
         371               2 : nsBlobProtocolHandler::GetProtocolFlags(PRUint32 *result)
         372                 : {
         373                 :   *result = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_SUBSUMERS |
         374               2 :             URI_IS_LOCAL_RESOURCE | URI_NON_PERSISTABLE;
         375               2 :   return NS_OK;
         376                 : }
         377                 :
         378                 : NS_IMETHODIMP
         379              15 : nsBlobProtocolHandler::NewURI(const nsACString& aSpec,
         380                 :                                   const char *aCharset,
         381                 :                                   nsIURI *aBaseURI,
         382                 :                                   nsIURI **aResult)
         383                 : {
         384              15 :   *aResult = nsnull;
         385                 :   nsresult rv;
         386                 :
         387                 :   FileDataInfo* info =
         388              15 :     GetFileDataInfo(aSpec);
         389                 :
         390                 :   nsRefPtr<nsBlobURI> uri =
         391              45 :     new nsBlobURI(info ? info->mPrincipal.get() : nsnull);
         392                 :
         393              15 :   rv = uri->SetSpec(aSpec);
         394              15 :   NS_ENSURE_SUCCESS(rv, rv);
         395                 :
         396              15 :   NS_TryToSetImmutable(uri);
         397              15 :   uri.forget(aResult);
         398                 :
         399              15 :   return NS_OK;
         400                 : }
         401                 :
         402                 : NS_IMETHODIMP
         403               2 : nsBlobProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
         404                 : {
         405               2 :   *result = nsnull;
         406                 :
         407               4 :   nsCString spec;
         408               2 :   uri->GetSpec(spec);
         409                 :
         410                 :   FileDataInfo* info =
         411               2 :     GetFileDataInfo(spec);
         412                 :
         413               2 :   if (!info) {
         414               0 :     return NS_ERROR_DOM_BAD_URI;
         415                 :   }
         416                 :
         417                 : #ifdef DEBUG
         418                 :   {
         419               4 :     nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(uri);
         420               4 :     nsCOMPtr<nsIPrincipal> principal;
         421               2 :     uriPrinc->GetPrincipal(getter_AddRefs(principal));
         422               2 :     NS_ASSERTION(info->mPrincipal == principal, "Wrong principal!");
         423                 :   }
         424                 : #endif
         425                 :
         426               4 :   nsCOMPtr<nsIInputStream> stream;
         427               2 :   nsresult rv = info->mFile->GetInternalStream(getter_AddRefs(stream));
         428               2 :   NS_ENSURE_SUCCESS(rv, rv);
         429                 :
         430               4 :   nsCOMPtr<nsIChannel> channel;
         431               2 :   rv = NS_NewInputStreamChannel(getter_AddRefs(channel),
         432                 :                                 uri,
         433               2 :                                 stream);
         434               2 :   NS_ENSURE_SUCCESS(rv, rv);
         435                 :
         436               4 :   nsCOMPtr<nsISupports> owner = do_QueryInterface(info->mPrincipal);
         437                 :
         438               4 :   nsAutoString type;
         439               2 :   rv = info->mFile->GetType(type);
         440               2 :   NS_ENSURE_SUCCESS(rv, rv);
         441                 :
         442               2 :   channel->SetOwner(owner);
         443               2 :   channel->SetOriginalURI(uri);
         444               2 :   channel->SetContentType(NS_ConvertUTF16toUTF8(type));
         445               2 :   channel.forget(result);
         446                 :
         447               2 :   return NS_OK;
         448                 : }
         449                 :
         450                 : NS_IMETHODIMP
         451               0 : nsBlobProtocolHandler::AllowPort(PRInt32 port, const char *scheme,
         452                 :                                      bool *_retval)
         453                 : {
         454                 :     // don't override anything.
         455               0 :     *_retval = false;
         456               0 :     return NS_OK;
         457                 : }

Generated by: LCOV version 1.7