Bug 468916 - make modifyLogin() smarter than just remove+add. r=zpao, r=gavin
[wine-gecko.git] / uriloader / exthandler / nsExternalHelperAppService.h
blobc00db4f40338b9783960590e68b07ad1f65d04e6
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
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/
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.
15 * The Original Code is the Mozilla browser.
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.
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>
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.
41 * ***** END LICENSE BLOCK ***** */
43 #ifndef nsExternalHelperAppService_h__
44 #define nsExternalHelperAppService_h__
46 #ifdef MOZ_LOGGING
47 #define FORCE_PR_LOG
48 #endif
49 #include "prlog.h"
50 #include "prtime.h"
52 #include "nsInt64.h"
54 #include "nsIExternalHelperAppService.h"
55 #include "nsIExternalProtocolService.h"
56 #include "nsIWebProgressListener2.h"
57 #include "nsIHelperAppLauncherDialog.h"
59 #include "nsIMIMEInfo.h"
60 #include "nsMIMEInfoImpl.h"
61 #include "nsIMIMEService.h"
62 #include "nsIStreamListener.h"
63 #include "nsIFile.h"
64 #include "nsIFileStreams.h"
65 #include "nsIOutputStream.h"
66 #include "nsString.h"
67 #include "nsIInterfaceRequestor.h"
68 #include "nsIInterfaceRequestorUtils.h"
69 #include "nsILocalFile.h"
70 #include "nsIChannel.h"
71 #include "nsITimer.h"
73 #include "nsIHandlerService.h"
74 #include "nsCOMPtr.h"
75 #include "nsIObserver.h"
76 #include "nsCOMArray.h"
77 #include "nsWeakReference.h"
78 #include "nsIPrompt.h"
80 class nsExternalAppHandler;
81 class nsIMIMEInfo;
82 class nsITransfer;
83 class nsIDOMWindowInternal;
85 /**
86 * The helper app service. Responsible for handling content that Mozilla
87 * itself can not handle
89 class nsExternalHelperAppService
90 : public nsIExternalHelperAppService,
91 public nsPIExternalAppLauncher,
92 public nsIExternalProtocolService,
93 public nsIMIMEService,
94 public nsIObserver,
95 public nsSupportsWeakReference
97 public:
98 NS_DECL_ISUPPORTS
99 NS_DECL_NSIEXTERNALHELPERAPPSERVICE
100 NS_DECL_NSPIEXTERNALAPPLAUNCHER
101 NS_DECL_NSIEXTERNALPROTOCOLSERVICE
102 NS_DECL_NSIMIMESERVICE
103 NS_DECL_NSIOBSERVER
105 nsExternalHelperAppService();
106 virtual ~nsExternalHelperAppService();
109 * Initializes internal state. Will be called automatically when
110 * this service is first instantiated.
112 NS_HIDDEN_(nsresult) Init();
115 * Given a mimetype and an extension, looks up a mime info from the OS.
116 * The mime type is given preference. This function follows the same rules
117 * as nsIMIMEService::GetFromTypeAndExtension.
118 * This is supposed to be overridden by the platform-specific
119 * nsOSHelperAppService!
120 * @param aFileExt The file extension; may be empty. UTF-8 encoded.
121 * @param [out] aFound
122 * Should be set to PR_TRUE if the os has a mapping, to
123 * PR_FALSE otherwise. Must not be null.
124 * @return A MIMEInfo. This function must return a MIMEInfo object if it
125 * can allocate one. The only justifiable reason for not
126 * returning one is an out-of-memory error.
127 * If null, the value of aFound is unspecified.
129 virtual already_AddRefed<nsIMIMEInfo> GetMIMEInfoFromOS(const nsACString& aMIMEType,
130 const nsACString& aFileExt,
131 PRBool * aFound) = 0;
134 * Given a string identifying an application, create an nsIFile representing
135 * it. This function should look in $PATH for the application.
136 * The base class implementation will first try to interpret platformAppPath
137 * as an absolute path, and if that fails it will look for a file next to the
138 * mozilla executable. Subclasses can override this method if they want a
139 * different behaviour.
140 * @param platformAppPath A platform specific path to an application that we
141 * got out of the rdf data source. This can be a mac
142 * file spec, a unix path or a windows path depending
143 * on the platform
144 * @param aFile [out] An nsIFile representation of that platform
145 * application path.
147 virtual nsresult GetFileTokenForPath(const PRUnichar * platformAppPath,
148 nsIFile ** aFile);
150 virtual NS_HIDDEN_(nsresult) OSProtocolHandlerExists(const char *aScheme,
151 PRBool *aExists) = 0;
154 * Simple accessor to let nsExternalAppHandler know if we are currently
155 * inside the private browsing mode.
157 PRBool InPrivateBrowsing() const { return mInPrivateBrowsing; }
159 protected:
161 * Searches the "extra" array of MIMEInfo objects for an object
162 * with a specific type. If found, it will modify the passed-in
163 * MIMEInfo. Otherwise, it will return an error and the MIMEInfo
164 * will be untouched.
165 * @param aContentType The type to search for.
166 * @param aMIMEInfo [inout] The mime info, if found
168 NS_HIDDEN_(nsresult) FillMIMEInfoForMimeTypeFromExtras(
169 const nsACString& aContentType, nsIMIMEInfo * aMIMEInfo);
171 * Searches the "extra" array of MIMEInfo objects for an object
172 * with a specific extension.
174 * Does not change the MIME Type of the MIME Info.
176 * @see FillMIMEInfoForMimeTypeFromExtras
178 NS_HIDDEN_(nsresult) FillMIMEInfoForExtensionFromExtras(
179 const nsACString& aExtension, nsIMIMEInfo * aMIMEInfo);
182 * Searches the "extra" array for a MIME type, and gets its extension.
183 * @param aExtension The extension to search for
184 * @param aMIMEType [out] The found MIME type.
185 * @return PR_TRUE if the extension was found, PR_FALSE otherwise.
187 NS_HIDDEN_(PRBool) GetTypeFromExtras(const nsACString& aExtension,
188 nsACString& aMIMEType);
191 * Fixes the file permissions to be correct. Base class has a no-op
192 * implementation, subclasses can use this to correctly inherit ACLs from the
193 * parent directory, to make the permissions obey the umask, etc.
195 virtual void FixFilePermissions(nsILocalFile* aFile);
197 #ifdef PR_LOGGING
199 * NSPR Logging Module. Usage: set NSPR_LOG_MODULES=HelperAppService:level,
200 * where level should be 2 for errors, 3 for debug messages from the cross-
201 * platform nsExternalHelperAppService, and 4 for os-specific debug messages.
203 static PRLogModuleInfo* mLog;
205 #endif
206 // friend, so that it can access the nspr log module and FixFilePermissions
207 friend class nsExternalAppHandler;
208 friend class nsExternalLoadRequest;
211 * Helper function for ExpungeTemporaryFiles and ExpungeTemporaryPrivateFiles
213 static void ExpungeTemporaryFilesHelper(nsCOMArray<nsILocalFile> &fileList);
215 * Functions related to the tempory file cleanup service provided by
216 * nsExternalHelperAppService
218 void ExpungeTemporaryFiles();
220 * Functions related to the tempory file cleanup service provided by
221 * nsExternalHelperAppService (for the temporary files added during
222 * the private browsing mode)
224 void ExpungeTemporaryPrivateFiles();
226 * Array for the files that should be deleted
228 nsCOMArray<nsILocalFile> mTemporaryFilesList;
230 * Array for the files that should be deleted (for the temporary files
231 * added during the private browsing mode)
233 nsCOMArray<nsILocalFile> mTemporaryPrivateFilesList;
235 * Whether we are in private browsing mode
237 PRBool mInPrivateBrowsing;
241 * We need to read the data out of the incoming stream into a buffer which we
242 * can then use to write the data into the output stream representing the
243 * temp file.
245 #define DATA_BUFFER_SIZE (4096*2)
248 * An external app handler is just a small little class that presents itself as
249 * a nsIStreamListener. It saves the incoming data into a temp file. The handler
250 * is bound to an application when it is created. When it receives an
251 * OnStopRequest it launches the application using the temp file it has
252 * stored the data into. We create a handler every time we have to process
253 * data using a helper app.
255 class nsExternalAppHandler : public nsIStreamListener,
256 public nsIHelperAppLauncher,
257 public nsITimerCallback
259 public:
260 NS_DECL_ISUPPORTS
261 NS_DECL_NSISTREAMLISTENER
262 NS_DECL_NSIREQUESTOBSERVER
263 NS_DECL_NSIHELPERAPPLAUNCHER
264 NS_DECL_NSICANCELABLE
265 NS_DECL_NSITIMERCALLBACK
268 * @param aMIMEInfo MIMEInfo object, representing the type of the
269 * content that should be handled
270 * @param aFileExtension The extension we need to append to our temp file,
271 * INCLUDING the ".". e.g. .mp3
272 * @param aWindowContext Window context, as passed to DoContent
273 * @param aFileName The filename to use
274 * @param aReason A constant from nsIHelperAppLauncherDialog indicating
275 * why the request is handled by a helper app.
277 nsExternalAppHandler(nsIMIMEInfo * aMIMEInfo, const nsCSubstring& aFileExtension,
278 nsIInterfaceRequestor * aWindowContext,
279 const nsAString& aFilename,
280 PRUint32 aReason, PRBool aForceSave);
282 ~nsExternalAppHandler();
284 protected:
285 nsCOMPtr<nsIFile> mTempFile;
286 nsCOMPtr<nsIURI> mSourceUrl;
287 nsString mTempFileExtension;
289 * The MIME Info for this load. Will never be null.
291 nsCOMPtr<nsIMIMEInfo> mMimeInfo;
292 nsCOMPtr<nsIOutputStream> mOutStream; /**< output stream to the temp file */
293 nsCOMPtr<nsIInterfaceRequestor> mWindowContext;
296 * Used to close the window on a timer, to avoid any exceptions that are
297 * thrown if we try to close the window before it's fully loaded.
299 nsCOMPtr<nsIDOMWindowInternal> mWindowToClose;
300 nsCOMPtr<nsITimer> mTimer;
303 * The following field is set if we were processing an http channel that had
304 * a content disposition header which specified the SUGGESTED file name we
305 * should present to the user in the save to disk dialog.
307 nsString mSuggestedFileName;
310 * If set, this handler should forcibly save the file to disk regardless of
311 * MIME info settings or anything else, without ever popping up the
312 * unknown content type handling dialog.
314 PRPackedBool mForceSave;
317 * The canceled flag is set if the user canceled the launching of this
318 * application before we finished saving the data to a temp file.
320 PRPackedBool mCanceled;
323 * This is set based on whether the channel indicates that a new window
324 * was opened specifically for this download. If so, then we
325 * close it.
327 PRPackedBool mShouldCloseWindow;
330 * have we received information from the user about how they want to
331 * dispose of this content
333 PRPackedBool mReceivedDispositionInfo;
334 PRPackedBool mStopRequestIssued;
335 PRPackedBool mProgressListenerInitialized;
337 PRPackedBool mIsFileChannel;
340 * One of the REASON_ constants from nsIHelperAppLauncherDialog. Indicates the
341 * reason the dialog was shown (unknown content type, server requested it,
342 * etc).
344 PRUint32 mReason;
347 * Track the executable-ness of the temporary file.
349 PRBool mTempFileIsExecutable;
351 PRTime mTimeDownloadStarted;
352 nsInt64 mContentLength;
353 nsInt64 mProgress; /**< Number of bytes received (for sending progress notifications). */
356 * When we are told to save the temp file to disk (in a more permament
357 * location) before we are done writing the content to a temp file, then
358 * we need to remember the final destination until we are ready to use it.
360 nsCOMPtr<nsIFile> mFinalFileDestination;
362 char mDataBuffer[DATA_BUFFER_SIZE];
365 * Creates the temporary file for the download and an output stream for it.
366 * Upon successful return, both mTempFile and mOutStream will be valid.
368 nsresult SetUpTempFile(nsIChannel * aChannel);
370 * When we download a helper app, we are going to retarget all load
371 * notifications into our own docloader and load group instead of
372 * using the window which initiated the load....RetargetLoadNotifications
373 * contains that information...
375 void RetargetLoadNotifications(nsIRequest *request);
377 * If the user tells us how they want to dispose of the content and
378 * we still haven't finished downloading while they were deciding,
379 * then create a progress listener of some kind so they know
380 * what's going on...
382 nsresult CreateProgressListener();
383 nsresult PromptForSaveToFile(nsILocalFile ** aNewFile,
384 const nsAFlatString &aDefaultFile,
385 const nsAFlatString &aDefaultFileExt);
388 * After we're done prompting the user for any information, if the original
389 * channel had a refresh url associated with it (which might point to a
390 * "thank you for downloading" kind of page, then process that....It is safe
391 * to invoke this method multiple times. We'll clear mOriginalChannel after
392 * it's called and this ensures we won't call it again....
394 void ProcessAnyRefreshTags();
396 /**
397 * An internal method used to actually move the temp file to the final
398 * destination once we done receiving data AND have showed the progress dialog
400 nsresult MoveFile(nsIFile * aNewFileLocation);
402 * An internal method used to actually launch a helper app given the temp file
403 * once we are done receiving data AND have showed the progress dialog.
404 * Uses the application specified in the mime info.
406 nsresult OpenWithApplication();
409 * Helper routine which peaks at the mime action specified by mMimeInfo
410 * and calls either MoveFile or OpenWithApplication
412 nsresult ExecuteDesiredAction();
414 * Helper routine that searches a pref string for a given mime type
416 PRBool GetNeverAskFlagFromPref(const char * prefName, const char * aContentType);
419 * Initialize an nsITransfer object for use as a progress object
421 nsresult InitializeDownload(nsITransfer*);
424 * Helper routine to ensure mSuggestedFileName is "correct";
425 * this ensures that mTempFileExtension only contains an extension when it
426 * is different from mSuggestedFileName's extension.
428 void EnsureSuggestedFileName();
430 typedef enum { kReadError, kWriteError, kLaunchError } ErrorType;
432 * Utility function to send proper error notification to web progress listener
434 void SendStatusChange(ErrorType type, nsresult aStatus, nsIRequest *aRequest, const nsAFlatString &path);
437 * Closes the window context if it does not have a refresh header
438 * and it never displayed content before the external helper app
439 * service was invoked.
441 nsresult MaybeCloseWindow();
443 nsCOMPtr<nsIWebProgressListener2> mWebProgressListener;
444 nsCOMPtr<nsIChannel> mOriginalChannel; /**< in the case of a redirect, this will be the pre-redirect channel. */
445 nsCOMPtr<nsIHelperAppLauncherDialog> mDialog;
448 * The request that's being loaded. Not used after OnStopRequest, so a weak
449 * reference suffices. Initialized in OnStartRequest.
451 nsIRequest* mRequest;
454 extern NS_HIDDEN_(nsExternalHelperAppService*) gExtProtSvc;
456 #endif // nsExternalHelperAppService_h__