LCOV - app.info - uriloader/exthandler/nsExternalHelperAppService.h

LCOV - code coverage report
| Current view: | directory - uriloader/exthandler - nsExternalHelperAppService.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 1 | 0 | 0.0 %
| Date: | 2012-07-07 | Functions: | 1 | 0 | 0.0 %

           1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
           2                 :  * ***** BEGIN LICENSE BLOCK *****
           3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           4                 :  *
           5                 :  * The contents of this file are subject to the Mozilla Public License Version
           6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           7                 :  * the License. You may obtain a copy of the License at
           8                 :  * http://www.mozilla.org/MPL/
           9                 :  *
          10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          12                 :  * for the specific language governing rights and limitations under the
          13                 :  * License.
          14                 :  *
          15                 :  * The Original Code is the Mozilla browser.
          16                 :  *
          17                 :  * The Initial Developer of the Original Code is
          18                 :  * Netscape Communications, Inc.
          19                 :  * Portions created by the Initial Developer are Copyright (C) 1999
          20                 :  * the Initial Developer. All Rights Reserved.
          21                 :  *
          22                 :  * Contributor(s):
          23                 :  *   Scott MacGregor <mscott@netscape.com>
          24                 :  *   Christian Biesinger <cbiesinger@web.de>
          25                 :  *   Dan Mosedale <dmose@mozilla.org>
          26                 :  *   Myk Melez <myk@mozilla.org>
          27                 :  *   Ehsan Akhgari <ehsan.akhgari@gmail.com>
          28                 :  *
          29                 :  * Alternatively, the contents of this file may be used under the terms of
          30                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
          31                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          32                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          33                 :  * of those above. If you wish to allow use of your version of this file only
          34                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          35                 :  * use your version of this file under the terms of the MPL, indicate your
          36                 :  * decision by deleting the provisions above and replace them with the notice
          37                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          38                 :  * the provisions above, a recipient may use your version of this file under
          39                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          40                 :  *
          41                 :  * ***** END LICENSE BLOCK ***** */
          42                 :
          43                 : #ifndef nsExternalHelperAppService_h__
          44                 : #define nsExternalHelperAppService_h__
          45                 :
          46                 : #ifdef MOZ_LOGGING
          47                 : #define FORCE_PR_LOG
          48                 : #endif
          49                 : #include "prlog.h"
          50                 : #include "prtime.h"
          51                 :
          52                 : #include "nsIExternalHelperAppService.h"
          53                 : #include "nsIExternalProtocolService.h"
          54                 : #include "nsIWebProgressListener2.h"
          55                 : #include "nsIHelperAppLauncherDialog.h"
          56                 :
          57                 : #include "nsIMIMEInfo.h"
          58                 : #include "nsIMIMEService.h"
          59                 : #include "nsIStreamListener.h"
          60                 : #include "nsIFile.h"
          61                 : #include "nsIFileStreams.h"
          62                 : #include "nsIOutputStream.h"
          63                 : #include "nsString.h"
          64                 : #include "nsIInterfaceRequestor.h"
          65                 : #include "nsIInterfaceRequestorUtils.h"
          66                 : #include "nsILocalFile.h"
          67                 : #include "nsIChannel.h"
          68                 : #include "nsITimer.h"
          69                 :
          70                 : #include "nsIHandlerService.h"
          71                 : #include "nsCOMPtr.h"
          72                 : #include "nsIObserver.h"
          73                 : #include "nsCOMArray.h"
          74                 : #include "nsWeakReference.h"
          75                 : #include "nsIPrompt.h"
          76                 : #include "nsAutoPtr.h"
          77                 :
          78                 : class nsExternalAppHandler;
          79                 : class nsIMIMEInfo;
          80                 : class nsITransfer;
          81                 : class nsIDOMWindow;
          82                 :
          83                 : /**
          84                 :  * The helper app service. Responsible for handling content that Mozilla
          85                 :  * itself can not handle
          86                 :  */
          87                 : class nsExternalHelperAppService
          88                 : : public nsIExternalHelperAppService,
          89                 :   public nsPIExternalAppLauncher,
          90                 :   public nsIExternalProtocolService,
          91                 :   public nsIMIMEService,
          92                 :   public nsIObserver,
          93                 :   public nsSupportsWeakReference
          94                 : {
          95                 : public:
          96                 :   NS_DECL_ISUPPORTS
          97                 :   NS_DECL_NSIEXTERNALHELPERAPPSERVICE
          98                 :   NS_DECL_NSPIEXTERNALAPPLAUNCHER
          99                 :   NS_DECL_NSIEXTERNALPROTOCOLSERVICE
         100                 :   NS_DECL_NSIMIMESERVICE
         101                 :   NS_DECL_NSIOBSERVER
         102                 :
         103                 :   nsExternalHelperAppService();
         104                 :   virtual ~nsExternalHelperAppService();
         105                 :
         106                 :   /**
         107                 :    * Initializes internal state. Will be called automatically when
         108                 :    * this service is first instantiated.
         109                 :    */
         110                 :   NS_HIDDEN_(nsresult) Init();
         111                 :
         112                 :   /**
         113                 :    * Given a mimetype and an extension, looks up a mime info from the OS.
         114                 :    * The mime type is given preference. This function follows the same rules
         115                 :    * as nsIMIMEService::GetFromTypeAndExtension.
         116                 :    * This is supposed to be overridden by the platform-specific
         117                 :    * nsOSHelperAppService!
         118                 :    * @param aFileExt The file extension; may be empty. UTF-8 encoded.
         119                 :    * @param [out] aFound
         120                 :    *        Should be set to true if the os has a mapping, to
         121                 :    *        false otherwise. Must not be null.
         122                 :    * @return A MIMEInfo. This function must return a MIMEInfo object if it
         123                 :    *         can allocate one.  The only justifiable reason for not
         124                 :    *         returning one is an out-of-memory error.
         125                 :    *         If null, the value of aFound is unspecified.
         126                 :    */
         127                 :   virtual already_AddRefed<nsIMIMEInfo> GetMIMEInfoFromOS(const nsACString& aMIMEType,
         128                 :                                                           const nsACString& aFileExt,
         129                 :                                                           bool       * aFound) = 0;
         130                 :
         131                 :   /**
         132                 :    * Given a string identifying an application, create an nsIFile representing
         133                 :    * it. This function should look in $PATH for the application.
         134                 :    * The base class implementation will first try to interpret platformAppPath
         135                 :    * as an absolute path, and if that fails it will look for a file next to the
         136                 :    * mozilla executable. Subclasses can override this method if they want a
         137                 :    * different behaviour.
         138                 :    * @param platformAppPath A platform specific path to an application that we
         139                 :    *                        got out of the rdf data source. This can be a mac
         140                 :    *                        file spec, a unix path or a windows path depending
         141                 :    *                        on the platform
         142                 :    * @param aFile           [out] An nsIFile representation of that platform
         143                 :    *                        application path.
         144                 :    */
         145                 :   virtual nsresult GetFileTokenForPath(const PRUnichar * platformAppPath,
         146                 :                                        nsIFile ** aFile);
         147                 :
         148                 :   virtual NS_HIDDEN_(nsresult) OSProtocolHandlerExists(const char *aScheme,
         149                 :                                                        bool *aExists) = 0;
         150                 :
         151                 :   /**
         152                 :    * Simple accessor to let nsExternalAppHandler know if we are currently
         153                 :    * inside the private browsing mode.
         154                 :    */
         155               0 :   bool InPrivateBrowsing() const { return mInPrivateBrowsing; }
         156                 :
         157                 : protected:
         158                 :   /**
         159                 :    * Searches the "extra" array of MIMEInfo objects for an object
         160                 :    * with a specific type. If found, it will modify the passed-in
         161                 :    * MIMEInfo. Otherwise, it will return an error and the MIMEInfo
         162                 :    * will be untouched.
         163                 :    * @param aContentType The type to search for.
         164                 :    * @param aMIMEInfo    [inout] The mime info, if found
         165                 :    */
         166                 :   NS_HIDDEN_(nsresult) FillMIMEInfoForMimeTypeFromExtras(
         167                 :     const nsACString& aContentType, nsIMIMEInfo * aMIMEInfo);
         168                 :   /**
         169                 :    * Searches the "extra" array of MIMEInfo objects for an object
         170                 :    * with a specific extension.
         171                 :    *
         172                 :    * Does not change the MIME Type of the MIME Info.
         173                 :    *
         174                 :    * @see FillMIMEInfoForMimeTypeFromExtras
         175                 :    */
         176                 :   NS_HIDDEN_(nsresult) FillMIMEInfoForExtensionFromExtras(
         177                 :     const nsACString& aExtension, nsIMIMEInfo * aMIMEInfo);
         178                 :
         179                 :   /**
         180                 :    * Searches the "extra" array for a MIME type, and gets its extension.
         181                 :    * @param aExtension The extension to search for
         182                 :    * @param aMIMEType [out] The found MIME type.
         183                 :    * @return true if the extension was found, false otherwise.
         184                 :    */
         185                 :   NS_HIDDEN_(bool) GetTypeFromExtras(const nsACString& aExtension,
         186                 :                                        nsACString& aMIMEType);
         187                 :
         188                 :   /**
         189                 :    * Fixes the file permissions to be correct. Base class has a no-op
         190                 :    * implementation, subclasses can use this to correctly inherit ACLs from the
         191                 :    * parent directory, to make the permissions obey the umask, etc.
         192                 :    */
         193                 :   virtual void FixFilePermissions(nsILocalFile* aFile);
         194                 :
         195                 : #ifdef PR_LOGGING
         196                 :   /**
         197                 :    * NSPR Logging Module. Usage: set NSPR_LOG_MODULES=HelperAppService:level,
         198                 :    * where level should be 2 for errors, 3 for debug messages from the cross-
         199                 :    * platform nsExternalHelperAppService, and 4 for os-specific debug messages.
         200                 :    */
         201                 :   static PRLogModuleInfo* mLog;
         202                 :
         203                 : #endif
         204                 :   // friend, so that it can access the nspr log module and FixFilePermissions
         205                 :   friend class nsExternalAppHandler;
         206                 :   friend class nsExternalLoadRequest;
         207                 :
         208                 :   /**
         209                 :    * Helper function for ExpungeTemporaryFiles and ExpungeTemporaryPrivateFiles
         210                 :    */
         211                 :   static void ExpungeTemporaryFilesHelper(nsCOMArray<nsILocalFile> &fileList);
         212                 :   /**
         213                 :    * Functions related to the tempory file cleanup service provided by
         214                 :    * nsExternalHelperAppService
         215                 :    */
         216                 :   void ExpungeTemporaryFiles();
         217                 :   /**
         218                 :    * Functions related to the tempory file cleanup service provided by
         219                 :    * nsExternalHelperAppService (for the temporary files added during
         220                 :    * the private browsing mode)
         221                 :    */
         222                 :   void ExpungeTemporaryPrivateFiles();
         223                 :   /**
         224                 :    * Array for the files that should be deleted
         225                 :    */
         226                 :   nsCOMArray<nsILocalFile> mTemporaryFilesList;
         227                 :   /**
         228                 :    * Array for the files that should be deleted (for the temporary files
         229                 :    * added during the private browsing mode)
         230                 :    */
         231                 :   nsCOMArray<nsILocalFile> mTemporaryPrivateFilesList;
         232                 :   /**
         233                 :    * Whether we are in private browsing mode
         234                 :    */
         235                 :   bool mInPrivateBrowsing;
         236                 : };
         237                 :
         238                 : /**
         239                 :  * An external app handler is just a small little class that presents itself as
         240                 :  * a nsIStreamListener. It saves the incoming data into a temp file. The handler
         241                 :  * is bound to an application when it is created. When it receives an
         242                 :  * OnStopRequest it launches the application using the temp file it has
         243                 :  * stored the data into.  We create a handler every time we have to process
         244                 :  * data using a helper app.
         245                 :  */
         246                 : class nsExternalAppHandler : public nsIStreamListener,
         247                 :                              public nsIHelperAppLauncher,
         248                 :                              public nsITimerCallback
         249                 : {
         250                 : public:
         251                 :   NS_DECL_ISUPPORTS
         252                 :   NS_DECL_NSISTREAMLISTENER
         253                 :   NS_DECL_NSIREQUESTOBSERVER
         254                 :   NS_DECL_NSIHELPERAPPLAUNCHER
         255                 :   NS_DECL_NSICANCELABLE
         256                 :   NS_DECL_NSITIMERCALLBACK
         257                 :
         258                 :   /**
         259                 :    * @param aMIMEInfo      MIMEInfo object, representing the type of the
         260                 :    *                       content that should be handled
         261                 :    * @param aFileExtension The extension we need to append to our temp file,
         262                 :    *                       INCLUDING the ".". e.g. .mp3
         263                 :    * @param aWindowContext Window context, as passed to DoContent
         264                 :    * @param mExtProtSvc    nsExternalHelperAppService on creation
         265                 :    * @param aFileName      The filename to use
         266                 :    * @param aReason        A constant from nsIHelperAppLauncherDialog indicating
         267                 :    *                       why the request is handled by a helper app.
         268                 :    */
         269                 :   nsExternalAppHandler(nsIMIMEInfo * aMIMEInfo, const nsCSubstring& aFileExtension,
         270                 :                        nsIInterfaceRequestor * aWindowContext,
         271                 :                        nsExternalHelperAppService * aExtProtSvc,
         272                 :                        const nsAString& aFilename,
         273                 :                        PRUint32 aReason, bool aForceSave);
         274                 :
         275                 :   ~nsExternalAppHandler();
         276                 :
         277                 : protected:
         278                 :   nsCOMPtr<nsIFile> mTempFile;
         279                 :   nsCOMPtr<nsIURI> mSourceUrl;
         280                 :   nsString mTempFileExtension;
         281                 :   /**
         282                 :    * The MIME Info for this load. Will never be null.
         283                 :    */
         284                 :   nsCOMPtr<nsIMIMEInfo> mMimeInfo;
         285                 :   nsCOMPtr<nsIOutputStream> mOutStream; /**< output stream to the temp file */
         286                 :   nsCOMPtr<nsIInterfaceRequestor> mWindowContext;
         287                 :
         288                 :   /**
         289                 :    * Used to close the window on a timer, to avoid any exceptions that are
         290                 :    * thrown if we try to close the window before it's fully loaded.
         291                 :    */
         292                 :   nsCOMPtr<nsIDOMWindow> mWindowToClose;
         293                 :   nsCOMPtr<nsITimer> mTimer;
         294                 :
         295                 :   /**
         296                 :    * The following field is set if we were processing an http channel that had
         297                 :    * a content disposition header which specified the SUGGESTED file name we
         298                 :    * should present to the user in the save to disk dialog.
         299                 :    */
         300                 :   nsString mSuggestedFileName;
         301                 :
         302                 :   /**
         303                 :    * If set, this handler should forcibly save the file to disk regardless of
         304                 :    * MIME info settings or anything else, without ever popping up the
         305                 :    * unknown content type handling dialog.
         306                 :    */
         307                 :   bool mForceSave;
         308                 :
         309                 :   /**
         310                 :    * The canceled flag is set if the user canceled the launching of this
         311                 :    * application before we finished saving the data to a temp file.
         312                 :    */
         313                 :   bool mCanceled;
         314                 :
         315                 :   /**
         316                 :    * This is set based on whether the channel indicates that a new window
         317                 :    * was opened specifically for this download.  If so, then we
         318                 :    * close it.
         319                 :    */
         320                 :   bool mShouldCloseWindow;
         321                 :
         322                 :   /**
         323                 :    * have we received information from the user about how they want to
         324                 :    * dispose of this content
         325                 :    */
         326                 :   bool mReceivedDispositionInfo;
         327                 :   bool mStopRequestIssued;
         328                 :   bool mProgressListenerInitialized;
         329                 :
         330                 :   bool mIsFileChannel;
         331                 :
         332                 :   /**
         333                 :    * One of the REASON_ constants from nsIHelperAppLauncherDialog. Indicates the
         334                 :    * reason the dialog was shown (unknown content type, server requested it,
         335                 :    * etc).
         336                 :    */
         337                 :   PRUint32 mReason;
         338                 :
         339                 :   /**
         340                 :    * Track the executable-ness of the temporary file.
         341                 :    */
         342                 :   bool mTempFileIsExecutable;
         343                 :
         344                 :   PRTime mTimeDownloadStarted;
         345                 :   PRInt64 mContentLength;
         346                 :   PRInt64 mProgress; /**< Number of bytes received (for sending progress notifications). */
         347                 :
         348                 :   /**
         349                 :    * When we are told to save the temp file to disk (in a more permament
         350                 :    * location) before we are done writing the content to a temp file, then
         351                 :    * we need to remember the final destination until we are ready to use it.
         352                 :    */
         353                 :   nsCOMPtr<nsIFile> mFinalFileDestination;
         354                 :
         355                 :   PRUint32 mBufferSize;
         356                 :   char    *mDataBuffer;
         357                 :
         358                 :   /**
         359                 :    * Creates the temporary file for the download and an output stream for it.
         360                 :    * Upon successful return, both mTempFile and mOutStream will be valid.
         361                 :    */
         362                 :   nsresult SetUpTempFile(nsIChannel * aChannel);
         363                 :   /**
         364                 :    * When we download a helper app, we are going to retarget all load
         365                 :    * notifications into our own docloader and load group instead of
         366                 :    * using the window which initiated the load....RetargetLoadNotifications
         367                 :    * contains that information...
         368                 :    */
         369                 :   void RetargetLoadNotifications(nsIRequest *request);
         370                 :   /**
         371                 :    * If the user tells us how they want to dispose of the content and
         372                 :    * we still haven't finished downloading while they were deciding,
         373                 :    * then create a progress listener of some kind so they know
         374                 :    * what's going on...
         375                 :    */
         376                 :   nsresult CreateProgressListener();
         377                 :   nsresult PromptForSaveToFile(nsILocalFile ** aNewFile,
         378                 :                                const nsAFlatString &aDefaultFile,
         379                 :                                const nsAFlatString &aDefaultFileExt);
         380                 :
         381                 :   /**
         382                 :    * After we're done prompting the user for any information, if the original
         383                 :    * channel had a refresh url associated with it (which might point to a
         384                 :    * "thank you for downloading" kind of page, then process that....It is safe
         385                 :    * to invoke this method multiple times. We'll clear mOriginalChannel after
         386                 :    * it's called and this ensures we won't call it again....
         387                 :    */
         388                 :   void ProcessAnyRefreshTags();
         389                 :
         390                 :   /**
         391                 :    * An internal method used to actually move the temp file to the final
         392                 :    * destination once we done receiving data AND have showed the progress dialog
         393                 :    */
         394                 :   nsresult MoveFile(nsIFile * aNewFileLocation);
         395                 :   /**
         396                 :    * An internal method used to actually launch a helper app given the temp file
         397                 :    * once we are done receiving data AND have showed the progress dialog.
         398                 :    * Uses the application specified in the mime info.
         399                 :    */
         400                 :   nsresult OpenWithApplication();
         401                 :
         402                 :   /**
         403                 :    * Helper routine which peaks at the mime action specified by mMimeInfo
         404                 :    * and calls either MoveFile or OpenWithApplication
         405                 :    */
         406                 :   nsresult ExecuteDesiredAction();
         407                 :   /**
         408                 :    * Helper routine that searches a pref string for a given mime type
         409                 :    */
         410                 :   bool GetNeverAskFlagFromPref(const char * prefName, const char * aContentType);
         411                 :
         412                 :   /**
         413                 :    * Initialize an nsITransfer object for use as a progress object
         414                 :    */
         415                 :   nsresult InitializeDownload(nsITransfer*);
         416                 :
         417                 :   /**
         418                 :    * Helper routine to ensure mSuggestedFileName is "correct";
         419                 :    * this ensures that mTempFileExtension only contains an extension when it
         420                 :    * is different from mSuggestedFileName's extension.
         421                 :    */
         422                 :   void EnsureSuggestedFileName();
         423                 :
         424                 :   typedef enum { kReadError, kWriteError, kLaunchError } ErrorType;
         425                 :   /**
         426                 :    * Utility function to send proper error notification to web progress listener
         427                 :    */
         428                 :   void SendStatusChange(ErrorType type, nsresult aStatus, nsIRequest *aRequest, const nsAFlatString &path);
         429                 :
         430                 :   /**
         431                 :    * Closes the window context if it does not have a refresh header
         432                 :    * and it never displayed content before the external helper app
         433                 :    * service was invoked.
         434                 :    */
         435                 :   nsresult MaybeCloseWindow();
         436                 :
         437                 :   nsCOMPtr<nsIWebProgressListener2> mWebProgressListener;
         438                 :   nsCOMPtr<nsIChannel> mOriginalChannel; /**< in the case of a redirect, this will be the pre-redirect channel. */
         439                 :   nsCOMPtr<nsIHelperAppLauncherDialog> mDialog;
         440                 :
         441                 :   /**
         442                 :    * Keep request alive in case when helper non-modal dialog shown.
         443                 :    * Thus in OnStopRequest the mRequest will not be set to null (it will be set to null further).
         444                 :    */
         445                 :   bool mKeepRequestAlive;
         446                 :
         447                 :   /**
         448                 :    * The request that's being loaded. Initialized in OnStartRequest.
         449                 :    * Nulled out in OnStopRequest or once we know what we're doing
         450                 :    * with the data, whichever happens later.
         451                 :    */
         452                 :   nsCOMPtr<nsIRequest> mRequest;
         453                 :
         454                 :   nsRefPtr<nsExternalHelperAppService> mExtProtSvc;
         455                 : };
         456                 :
         457                 : #endif // nsExternalHelperAppService_h__

Generated by: LCOV version 1.7