Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Functions | Variables
nsExternalHelperAppService.cpp File Reference
#include "nsExternalHelperAppService.h"
#include "nsIURI.h"
#include "nsIURL.h"
#include "nsIFile.h"
#include "nsIFileURL.h"
#include "nsIChannel.h"
#include "nsIDirectoryService.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsICategoryManager.h"
#include "nsXPIDLString.h"
#include "nsUnicharUtils.h"
#include "nsIStringEnumerator.h"
#include "nsMemory.h"
#include "nsIStreamListener.h"
#include "nsIMIMEService.h"
#include "nsILoadGroup.h"
#include "nsIWebProgressListener.h"
#include "nsITransfer.h"
#include "nsReadableUtils.h"
#include "nsIRequest.h"
#include "nsDirectoryServiceDefs.h"
#include "nsIInterfaceRequestor.h"
#include "nsAutoPtr.h"
#include "nsRDFCID.h"
#include "rdf.h"
#include "nsIRDFService.h"
#include "nsIRDFRemoteDataSource.h"
#include "nsHelperAppRDF.h"
#include "nsIMIMEInfo.h"
#include "nsIRefreshURI.h"
#include "nsIDocumentLoader.h"
#include "nsIHelperAppLauncherDialog.h"
#include "nsNetUtil.h"
#include "nsIIOService.h"
#include "nsNetCID.h"
#include "nsChannelProperties.h"
#include "nsMimeTypes.h"
#include "nsIHttpChannel.h"
#include "nsIEncodedChannel.h"
#include "nsIMultiPartChannel.h"
#include "nsIObserverService.h"
#include "nsIPropertyBag2.h"
#include "nsIPluginHost.h"
#include "nsEscape.h"
#include "nsIStringBundle.h"
#include "nsIPrompt.h"
#include "nsITextToSubURI.h"
#include "nsIMIMEHeaderParam.h"
#include "nsIPrefService.h"
#include "nsIWindowWatcher.h"
#include "nsIGlobalHistory.h"
#include "nsIGlobalHistory2.h"
#include "nsIDOMWindow.h"
#include "nsIDOMWindowInternal.h"
#include "nsIDocShell.h"
#include "nsCRT.h"

Go to the source code of this file.

Classes

struct  nsDefaultMimeTypeEntry
 Structure for storing extension->type mappings. More...
struct  nsExtraMimeTypeEntry
 This is a small private struct used to help us initialize some default mime types. More...
struct  extLoadRequest

Defines

#define LOG(args)   PR_LOG(mLog, 3, args)
#define LOG_ENABLED()   PR_LOG_TEST(mLog, 3)
#define MAC_TYPE(x)   0
#define SALT_SIZE   8
#define TABLE_SIZE   36

Functions

static NS_DEFINE_CID (kRDFServiceCID, NS_RDFSERVICE_CID)
static NS_DEFINE_CID (kPluginManagerCID, NS_PLUGINMANAGER_CID)
static nsresult UnescapeFragment (const nsACString &aFragment, nsIURI *aURI, nsAString &aResult)
 Given a URI fragment, unescape it.
static nsresult UnescapeFragment (const nsACString &aFragment, nsIURI *aURI, nsACString &aResult)
 UTF-8 version of UnescapeFragment.
static void ExtractDisposition (nsIChannel *aChannel, nsACString &aDisposition)
 Gets the content-disposition header from a channel, using nsIHttpChannel or nsIMultipartChannel if available.
static void GetFilenameFromDisposition (nsAString &aFilename, const nsACString &aDisposition, nsIURI *aURI=nsnull, nsIMIMEHeaderParam *aMIMEHeaderParam=nsnull)
 Extracts the filename out of a content-disposition header.
static PRBool GetFilenameAndExtensionFromChannel (nsIChannel *aChannel, nsString &aFileName, nsCString &aExtension, PRBool aAllowURLExtension=PR_TRUE)
 Given a channel, returns the filename and extension the channel has.
 NS_IMPL_ISUPPORTS6 (nsExternalHelperAppService, nsIExternalHelperAppService, nsPIExternalAppLauncher, nsIExternalProtocolService, nsIMIMEService, nsIObserver, nsISupportsWeakReference) nsExternalHelperAppService
static void PR_CALLBACK destroyExternalLoadEvent (PLEvent *event)

Variables

static const char NEVER_ASK_PREF_BRANCH [] = "browser.helperApps.neverAsk."
static const char NEVER_ASK_FOR_SAVE_TO_DISK_PREF [] = "saveToDisk"
static const char NEVER_ASK_FOR_OPEN_FILE_PREF [] = "openFile"
static nsExternalHelperAppServicesSrv
 Contains a pointer to the helper app service, set in its constructor.
static nsDefaultMimeTypeEntry defaultMimeEntries []
 Default extension->mimetype mappings.
static nsExtraMimeTypeEntry extraMimeEntries []
 This table lists all of the 'extra' content types that we can deduce from particular file extensions.
static nsDefaultMimeTypeEntry nonDecodableExtensions []
 File extensions for which decoding should be disabled.
static const char kExternalProtocolPrefPrefix [] = "network.protocol-handler.external."
static const char kExternalProtocolDefaultPref [] = "network.protocol-handler.external-default"
static const char kExternalWarningPrefPrefix [] = "network.protocol-handler.warn-external."
static const char kExternalWarningDefaultPref [] = "network.protocol-handler.warn-external-default"
const PRUnichar table []

Class Documentation

struct nsDefaultMimeTypeEntry

Structure for storing extension->type mappings.

See also:
defaultMimeEntries

Definition at line 376 of file nsExternalHelperAppService.cpp.

Class Members
const char * mFileExtension
const char * mMimeType
struct nsExtraMimeTypeEntry

This is a small private struct used to help us initialize some default mime types.

Definition at line 410 of file nsExternalHelperAppService.cpp.

Class Members
const char * mDescription
const char * mFileExtensions
PRUint32 mMacCreator
PRUint32 mMactype
const char * mMimeType

Define Documentation

#define LOG (   args)    PR_LOG(mLog, 3, args)

Definition at line 126 of file nsExternalHelperAppService.cpp.

#define LOG_ENABLED ( )    PR_LOG_TEST(mLog, 3)

Definition at line 127 of file nsExternalHelperAppService.cpp.

#define MAC_TYPE (   x)    0

Definition at line 421 of file nsExternalHelperAppService.cpp.

#define SALT_SIZE   8

Definition at line 1538 of file nsExternalHelperAppService.cpp.

#define TABLE_SIZE   36

Definition at line 1539 of file nsExternalHelperAppService.cpp.


Function Documentation

static void PR_CALLBACK destroyExternalLoadEvent ( PLEvent event) [static]

Definition at line 1104 of file nsExternalHelperAppService.cpp.

{
  delete NS_STATIC_CAST(extLoadRequest*, event);
}
static void ExtractDisposition ( nsIChannel aChannel,
nsACString &  aDisposition 
) [static]

Gets the content-disposition header from a channel, using nsIHttpChannel or nsIMultipartChannel if available.

Parameters:
aChannelThe channel to extract the disposition header from
aDispositionReference to a string where the header is to be stored

Definition at line 189 of file nsExternalHelperAppService.cpp.

{
  aDisposition.Truncate();
  // First see whether this is an http channel
  nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aChannel));
  if (httpChannel) 
  {
    httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("content-disposition"), aDisposition);
  }
  if (aDisposition.IsEmpty())
  {
    nsCOMPtr<nsIMultiPartChannel> multipartChannel(do_QueryInterface(aChannel));
    if (multipartChannel)
    {
      multipartChannel->GetContentDisposition(aDisposition);
    }
  }

}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRBool GetFilenameAndExtensionFromChannel ( nsIChannel aChannel,
nsString aFileName,
nsCString aExtension,
PRBool  aAllowURLExtension = PR_TRUE 
) [static]

Given a channel, returns the filename and extension the channel has.

This uses the URL and other sources (nsIMultiPartChannel). Also gives back whether the channel requested external handling (i.e. whether Content-Disposition: attachment was sent)

Parameters:
aChannelThe channel to extract the filename/extension from
aFileName[out] Reference to the string where the filename should be stored. Empty if it could not be retrieved. WARNING - this filename may contain characters which the OS does not allow as part of filenames!
aExtension[out] Reference to the string where the extension should be stored. Empty if it could not be retrieved. Stored in UTF-8.
aAllowURLExtension(optional) Get the extension from the URL if no Content-Disposition header is present. Default is true.
Return values:
trueThe server sent Content-Disposition:attachment or equivalent
falseContent-Disposition: inline or no content-disposition header was sent.

Definition at line 262 of file nsExternalHelperAppService.cpp.

{
  aExtension.Truncate();
  /*
   * If the channel is an http or part of a multipart channel and we
   * have a content disposition header set, then use the file name
   * suggested there as the preferred file name to SUGGEST to the
   * user.  we shouldn't actually use that without their
   * permission... otherwise just use our temp file
   */
  nsCAutoString disp;
  ExtractDisposition(aChannel, disp);
  PRBool handleExternally = PR_FALSE;
  nsCOMPtr<nsIURI> uri;
  nsresult rv;
  aChannel->GetURI(getter_AddRefs(uri));
  // content-disposition: has format:
  // disposition-type < ; name=value >* < ; filename=value > < ; name=value >*
  if (!disp.IsEmpty()) 
  {
    nsCOMPtr<nsIMIMEHeaderParam> mimehdrpar = do_GetService(NS_MIMEHEADERPARAM_CONTRACTID, &rv);
    if (NS_FAILED(rv))
      return PR_FALSE;

    nsCAutoString fallbackCharset;
    uri->GetOriginCharset(fallbackCharset);
    // Get the disposition type
    nsAutoString dispToken;
    rv = mimehdrpar->GetParameter(disp, "", fallbackCharset, PR_TRUE, 
                                  nsnull, dispToken);
    // RFC 2183, section 2.8 says that an unknown disposition
    // value should be treated as "attachment"
    // XXXbz this code is duplicated in nsDocumentOpenInfo::DispatchContent.
    // Factor it out!  Maybe store it in the nsDocumentOpenInfo?
    if (NS_FAILED(rv) || 
        (// Some broken sites just send
         // Content-Disposition: ; filename="file"
         // screen those out here.
         !dispToken.IsEmpty() &&
         !dispToken.LowerCaseEqualsLiteral("inline") &&
        // Broken sites just send
        // Content-Disposition: filename="file"
        // without a disposition token... screen those out.
        !dispToken.EqualsIgnoreCase("filename", 8)) &&
        // Also in use is Content-Disposition: name="file"
        !dispToken.EqualsIgnoreCase("name", 4)) 
    {
      // We have a content-disposition of "attachment" or unknown
      handleExternally = PR_TRUE;
    }

    // We may not have a disposition type listed; some servers suck.
    // But they could have listed a filename anyway.
    GetFilenameFromDisposition(aFileName, disp, uri, mimehdrpar);

  } // we had a disp header 

  // If the disposition header didn't work, try the filename from nsIURL
  nsCOMPtr<nsIURL> url(do_QueryInterface(uri));
  if (url && aFileName.IsEmpty())
  {
    if (aAllowURLExtension) {
      url->GetFileExtension(aExtension);
      UnescapeFragment(aExtension, url, aExtension);

      // Windows ignores terminating dots. So we have to as well, so
      // that our security checks do "the right thing"
      // In case the aExtension consisted only of the dot, the code below will
      // extract an aExtension from the filename
      aExtension.Trim(".", PR_FALSE);
    }

    // try to extract the file name from the url and use that as a first pass as the
    // leaf name of our temp file...
    nsCAutoString leafName;
    url->GetFileName(leafName);
    if (!leafName.IsEmpty())
    {
      rv = UnescapeFragment(leafName, url, aFileName);
      if (NS_FAILED(rv))
      {
        CopyUTF8toUTF16(leafName, aFileName); // use escaped name
      }
    }
  }

  // Extract Extension, if we have a filename; otherwise,
  // truncate the string
  if (aExtension.IsEmpty()) {
    if (!aFileName.IsEmpty())
    {
      // Windows ignores terminating dots. So we have to as well, so
      // that our security checks do "the right thing"
      aFileName.Trim(".", PR_FALSE);

      // XXX RFindCharInReadable!!
      nsAutoString fileNameStr(aFileName);
      PRInt32 idx = fileNameStr.RFindChar(PRUnichar('.'));
      if (idx != kNotFound)
        CopyUTF16toUTF8(StringTail(fileNameStr, fileNameStr.Length() - idx - 1), aExtension);
    }
  }


  return handleExternally;
}

Here is the call graph for this function:

static void GetFilenameFromDisposition ( nsAString &  aFilename,
const nsACString &  aDisposition,
nsIURI aURI = nsnull,
nsIMIMEHeaderParam aMIMEHeaderParam = nsnull 
) [static]

Extracts the filename out of a content-disposition header.

Parameters:
aFilename[out] The filename. Can be empty on error.
aDispositionValue of a Content-Disposition header
aURIOptional. Will be used to get a fallback charset for the filename, if it is QI'able to nsIURL
aMIMEHeaderParamOptional. Pointer to a nsIMIMEHeaderParam class, so that it doesn't need to be fetched by this function.

Definition at line 217 of file nsExternalHelperAppService.cpp.

{
  aFilename.Truncate();
  nsCOMPtr<nsIMIMEHeaderParam> mimehdrpar(aMIMEHeaderParam);
  if (!mimehdrpar) {
    mimehdrpar = do_GetService(NS_MIMEHEADERPARAM_CONTRACTID);
    if (!mimehdrpar)
      return;
  }

  nsCOMPtr<nsIURL> url = do_QueryInterface(aURI);

  nsCAutoString fallbackCharset;
  if (url)
    url->GetOriginCharset(fallbackCharset);
  // Get the value of 'filename' parameter
  nsresult rv = mimehdrpar->GetParameter(aDisposition, "filename", fallbackCharset, 
                                         PR_TRUE, nsnull, aFilename);
  if (NS_FAILED(rv) || aFilename.IsEmpty())
    // Try 'name' parameter, instead.
    rv = mimehdrpar->GetParameter(aDisposition, "name", fallbackCharset, PR_TRUE, 
                                  nsnull, aFilename);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static NS_DEFINE_CID ( kRDFServiceCID  ,
NS_RDFSERVICE_CID   
) [static]
static NS_DEFINE_CID ( kPluginManagerCID  ,
NS_PLUGINMANAGER_CID   
) [static]

Definition at line 478 of file nsExternalHelperAppService.cpp.

: mDataSourceInitialized(PR_FALSE)
{
  sSrv = this;
}
static nsresult UnescapeFragment ( const nsACString &  aFragment,
nsIURI aURI,
nsAString &  aResult 
) [static]

Given a URI fragment, unescape it.

Parameters:
aFragmentThe string to unescape
aURIThe URI from which this fragment is taken. Only its character set will be used.
aResult[out] Unescaped string.

Definition at line 150 of file nsExternalHelperAppService.cpp.

{
  // First, we need a charset
  nsCAutoString originCharset;
  nsresult rv = aURI->GetOriginCharset(originCharset);
  NS_ENSURE_SUCCESS(rv, rv);

  // Now, we need the unescaper
  nsCOMPtr<nsITextToSubURI> textToSubURI = do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  return textToSubURI->UnEscapeURIForUI(originCharset, aFragment, aResult);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static nsresult UnescapeFragment ( const nsACString &  aFragment,
nsIURI aURI,
nsACString &  aResult 
) [static]

UTF-8 version of UnescapeFragment.

Parameters:
aFragmentThe string to unescape
aURIThe URI from which this fragment is taken. Only its character set will be used.
aResult[out] Unescaped string, UTF-8 encoded.
Note:
It is safe to pass the same string for aFragment and aResult.
When this function fails, aResult will not be modified.

Definition at line 174 of file nsExternalHelperAppService.cpp.

{
  nsAutoString result;
  nsresult rv = UnescapeFragment(aFragment, aURI, result);
  if (NS_SUCCEEDED(rv))
    CopyUTF16toUTF8(result, aResult);
  return rv;
}

Here is the call graph for this function:


Variable Documentation

Initial value:
 
{
  
  
  { IMAGE_GIF, "gif" },
  { TEXT_XML, "xml" },
  { APPLICATION_RDF, "rdf" },
  { TEXT_XUL, "xul" },
  { IMAGE_PNG, "png" },
  
  { TEXT_CSS, "css" },
  { IMAGE_JPG, "jpeg" },
  { IMAGE_JPG, "jpg" },
  { TEXT_HTML, "html" },
  { TEXT_HTML, "htm" },
  { APPLICATION_XPINSTALL, "xpi" },
  { "application/xhtml+xml", "xhtml" },
  { "application/xhtml+xml", "xht" },
  { TEXT_PLAIN, "txt" }
}

Default extension->mimetype mappings.

These are not overridable. If you add types here, make sure they are lowercase, or you'll regret it.

Definition at line 385 of file nsExternalHelperAppService.cpp.

This table lists all of the 'extra' content types that we can deduce from particular file extensions.

These entries also ensure that we provide a good descriptive name when we encounter files with these content types and/or extensions. These can be overridden by user helper app prefs. If you add types here, make sure they are lowercase, or you'll regret it.

Definition at line 431 of file nsExternalHelperAppService.cpp.

const char kExternalProtocolDefaultPref[] = "network.protocol-handler.external-default" [static]

Definition at line 1148 of file nsExternalHelperAppService.cpp.

const char kExternalProtocolPrefPrefix[] = "network.protocol-handler.external." [static]

Definition at line 1147 of file nsExternalHelperAppService.cpp.

const char kExternalWarningDefaultPref[] = "network.protocol-handler.warn-external-default" [static]

Definition at line 1150 of file nsExternalHelperAppService.cpp.

const char kExternalWarningPrefPrefix[] = "network.protocol-handler.warn-external." [static]

Definition at line 1149 of file nsExternalHelperAppService.cpp.

const char NEVER_ASK_FOR_OPEN_FILE_PREF[] = "openFile" [static]

Definition at line 131 of file nsExternalHelperAppService.cpp.

const char NEVER_ASK_FOR_SAVE_TO_DISK_PREF[] = "saveToDisk" [static]

Definition at line 130 of file nsExternalHelperAppService.cpp.

const char NEVER_ASK_PREF_BRANCH[] = "browser.helperApps.neverAsk." [static]

Definition at line 129 of file nsExternalHelperAppService.cpp.

Initial value:
 {
  { APPLICATION_GZIP, "gz" }, 
  { APPLICATION_GZIP, "tgz" },
  { APPLICATION_ZIP, "zip" },
  { APPLICATION_COMPRESS, "z" },
  { APPLICATION_GZIP, "svgz" }
}

File extensions for which decoding should be disabled.

NOTE: These MUST be lower-case and ASCII.

Definition at line 470 of file nsExternalHelperAppService.cpp.

Contains a pointer to the helper app service, set in its constructor.

Definition at line 139 of file nsExternalHelperAppService.cpp.

Initial value:
 
  { 'a','b','c','d','e','f','g','h','i','j',
    'k','l','m','n','o','p','q','r','s','t',
    'u','v','w','x','y','z','0','1','2','3',
    '4','5','6','7','8','9'}

Definition at line 1540 of file nsExternalHelperAppService.cpp.