aboutsummaryrefslogtreecommitdiffstats
path: root/embed/mozilla
diff options
context:
space:
mode:
Diffstat (limited to 'embed/mozilla')
-rw-r--r--embed/mozilla/EphyHeaderSniffer.cpp167
-rw-r--r--embed/mozilla/EphyHeaderSniffer.h5
-rw-r--r--embed/mozilla/MozDownload.cpp96
-rw-r--r--embed/mozilla/MozDownload.h7
-rw-r--r--embed/mozilla/mozilla-embed-persist.cpp48
5 files changed, 205 insertions, 118 deletions
diff --git a/embed/mozilla/EphyHeaderSniffer.cpp b/embed/mozilla/EphyHeaderSniffer.cpp
index efeb90e4a..8fbf2220b 100644
--- a/embed/mozilla/EphyHeaderSniffer.cpp
+++ b/embed/mozilla/EphyHeaderSniffer.cpp
@@ -36,6 +36,8 @@
*
* ***** END LICENSE BLOCK ***** */
+#include "MozillaPrivate.h"
+
#include "MozDownload.h"
#include "EphyHeaderSniffer.h"
#include "netCore.h"
@@ -51,19 +53,15 @@
#include "nsIDOMHTMLDocument.h"
#include "nsIDownload.h"
-const char* const persistContractID = "@mozilla.org/embedding/browser/nsWebBrowserPersist;1";
-
EphyHeaderSniffer::EphyHeaderSniffer (nsIWebBrowserPersist* aPersist, MozillaEmbedPersist *aEmbedPersist,
nsIFile* aFile, nsIURI* aURL, nsIDOMDocument* aDocument, nsIInputStream* aPostData,
- const nsAString& aSuggestedFilename, PRBool aBypassCache)
+ PRBool aBypassCache)
: mPersist(aPersist)
, mEmbedPersist(aEmbedPersist)
, mTmpFile(aFile)
, mURL(aURL)
, mDocument(aDocument)
, mPostData(aPostData)
-, mDefaultFilename(aSuggestedFilename)
-, mBypassCache(aBypassCache)
{
mPrompt = do_GetService("@mozilla.org/embedcomp/prompt-service;1");
}
@@ -157,116 +155,91 @@ EphyHeaderSniffer::OnSecurityChange (nsIWebProgress *aWebProgress, nsIRequest *a
nsresult EphyHeaderSniffer::PerformSave (nsIURI* inOriginalURI)
{
nsresult rv;
+ EmbedPersistFlags flags;
+ PRBool askDownloadDest;
- PRBool isHTML = (mDocument && mContentType.Equals("text/html") ||
- mContentType.Equals("text/xml") ||
- mContentType.Equals("application/xhtml+xml"));
+ ephy_embed_persist_get_flags (EPHY_EMBED_PERSIST (mEmbedPersist), &flags);
+ askDownloadDest = flags & EMBED_PERSIST_ASK_DESTINATION;
- nsCOMPtr<nsILocalFile> file;
- rv = NS_NewLocalFile(mDefaultFilename, PR_TRUE, getter_AddRefs(file));
- if (NS_FAILED(rv) || !file) return G_FAILED;
-
- nsCOMPtr<nsISupports> sourceData;
- if (isHTML)
+ nsAutoString defaultFileName;
+
+ if (defaultFileName.IsEmpty() && !mContentDisposition.IsEmpty())
{
- sourceData = do_QueryInterface(mDocument);
+ /* 1 Use the HTTP header suggestion. */
+ PRInt32 index = mContentDisposition.Find("filename=");
+ if (index >= 0)
+ {
+ /* Take the substring following the prefix. */
+ index += 9;
+ nsCAutoString filename;
+ mContentDisposition.Right(filename, mContentDisposition.Length() - index);
+ defaultFileName = NS_ConvertUTF8toUCS2(filename);
+ }
}
- else
+
+ if (defaultFileName.IsEmpty())
{
- sourceData = do_QueryInterface(mURL);
- }
-
- return InitiateDownload(sourceData, file, inOriginalURI);
-}
+ /* 2 For file URLs, use the file name. */
-nsresult EphyHeaderSniffer::InitiateDownload (nsISupports* inSourceData, nsILocalFile* inDestFile,
- nsIURI* inOriginalURI)
-{
- nsresult rv = NS_OK;
-
- nsCOMPtr<nsIWebBrowserPersist> webPersist = do_CreateInstance(persistContractID, &rv);
- if (NS_FAILED(rv)) return rv;
-
- nsCOMPtr<nsIURI> sourceURI = do_QueryInterface(inSourceData);
-
- PRInt64 timeNow = PR_Now();
-
- nsAutoString fileDisplayName;
- inDestFile->GetLeafName(fileDisplayName);
-
- MozDownload *downloader = new MozDownload ();
- /* dlListener attaches to its progress dialog here, which gains ownership */
- rv = downloader->InitForEmbed (inOriginalURI, inDestFile, fileDisplayName.get(),
- nsnull, timeNow, webPersist, mEmbedPersist);
- if (NS_FAILED(rv)) return rv;
-
- PRInt32 flags = nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION |
- nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES;
- if (mBypassCache)
+ nsCOMPtr<nsIURL> url(do_QueryInterface(mURL));
+ if (url)
+ {
+ nsCAutoString fileNameCString;
+ url->GetFileName(fileNameCString);
+ defaultFileName = NS_ConvertUTF8toUCS2(fileNameCString);
+ }
+ }
+
+ if (defaultFileName.IsEmpty() && mDocument)
{
- flags |= nsIWebBrowserPersist::PERSIST_FLAGS_BYPASS_CACHE;
+ /* 3 Use the title of the document. */
+
+ nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(mDocument));
+ if (htmlDoc)
+ {
+ htmlDoc->GetTitle(defaultFileName);
+ }
}
- else
+
+ if (defaultFileName.IsEmpty() && mURL)
{
- flags |= nsIWebBrowserPersist::PERSIST_FLAGS_FROM_CACHE;
+ /* 4 Use the host. */
+ nsCAutoString hostName;
+ mURL->GetHost(hostName);
+ defaultFileName = NS_ConvertUTF8toUCS2(hostName);
}
-
- webPersist->SetPersistFlags(flags);
- if (sourceURI)
+ /* 5 One last case to handle about:blank and other fruity untitled pages. */
+ if (defaultFileName.IsEmpty())
{
- rv = webPersist->SaveURI (sourceURI, nsnull, nsnull,
- mPostData, nsnull, inDestFile);
+ defaultFileName.AssignWithConversion("untitled");
}
- else
+
+ /* Validate the file name to ensure legality. */
+ for (PRUint32 i = 0; i < defaultFileName.Length(); i++)
{
- nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(inSourceData, &rv);
- if (!domDoc) return rv; /* should never happen */
-
- PRInt32 encodingFlags = 0;
- nsCOMPtr<nsILocalFile> filesFolder;
-
- if (!mContentType.Equals("text/plain"))
+ if (defaultFileName[i] == ':' || defaultFileName[i] == '/')
{
- /* Create a local directory in the same dir as our file. It
- will hold our associated files. */
-
- filesFolder = do_CreateInstance("@mozilla.org/file/local;1");
- nsAutoString unicodePath;
- inDestFile->GetPath(unicodePath);
- filesFolder->InitWithPath(unicodePath);
-
- nsAutoString leafName;
- filesFolder->GetLeafName(leafName);
- nsAutoString nameMinusExt(leafName);
- PRInt32 index = nameMinusExt.RFind(".");
- if (index >= 0)
- {
- nameMinusExt.Left(nameMinusExt, index);
- }
-
- nameMinusExt += NS_LITERAL_STRING(" Files");
- filesFolder->SetLeafName(nameMinusExt);
- PRBool exists = PR_FALSE;
- filesFolder->Exists(&exists);
- if (!exists)
- {
- rv = filesFolder->Create(nsILocalFile::DIRECTORY_TYPE, 0755);
- if (NS_FAILED(rv)) return rv;
- }
- }
- else
- {
- encodingFlags |= nsIWebBrowserPersist::ENCODE_FLAGS_FORMATTED |
- nsIWebBrowserPersist::ENCODE_FLAGS_ABSOLUTE_LINKS |
- nsIWebBrowserPersist::ENCODE_FLAGS_NOFRAMES_CONTENT;
+ defaultFileName.SetCharAt(i, PRUnichar(' '));
}
+ }
- rv = webPersist->SaveDocument (domDoc, inDestFile, filesFolder,
- mContentType.get(), encodingFlags, 80);
+ if (askDownloadDest)
+ {
+ /* FIXME show the file selector here */
+ }
+ else
+ {
+ /* FIXME build path from download dir */
}
-
- return rv;
+
+ nsCOMPtr<nsILocalFile> destFile;
+ rv = NS_NewLocalFile(defaultFileName, PR_TRUE, getter_AddRefs(destFile));
+ if (NS_FAILED(rv) || !destFile) return G_FAILED;
+
+ return InitiateMozillaDownload (mDocument, mURL, destFile,
+ mContentType.get(), inOriginalURI, mEmbedPersist,
+ mBypassCache, mPostData);
}
NS_IMETHODIMP EphyHeaderSniffer::Prompt (const PRUnichar *dialogTitle, const PRUnichar *text,
diff --git a/embed/mozilla/EphyHeaderSniffer.h b/embed/mozilla/EphyHeaderSniffer.h
index b8d56281d..3635593e8 100644
--- a/embed/mozilla/EphyHeaderSniffer.h
+++ b/embed/mozilla/EphyHeaderSniffer.h
@@ -54,8 +54,7 @@ class EphyHeaderSniffer : public nsIWebProgressListener,
public:
EphyHeaderSniffer (nsIWebBrowserPersist* aPersist, MozillaEmbedPersist *aEmbedPersist,
nsIFile* aFile, nsIURI* aURL,
- nsIDOMDocument* aDocument, nsIInputStream* aPostData,
- const nsAString& aSuggestedFilename, PRBool aBypassCache);
+ nsIDOMDocument* aDocument, nsIInputStream* aPostData, PRBool aBypassCache);
virtual ~EphyHeaderSniffer ();
NS_DECL_ISUPPORTS
@@ -64,7 +63,6 @@ public:
protected:
nsresult PerformSave (nsIURI* inOriginalURI);
- nsresult InitiateDownload (nsISupports* inSourceData, nsILocalFile* inDestFile, nsIURI* inOriginalURI);
private:
nsIWebBrowserPersist* mPersist; /* Weak. It owns us as a listener. */
@@ -73,7 +71,6 @@ private:
nsCOMPtr<nsIURI> mURL;
nsCOMPtr<nsIDOMDocument> mDocument;
nsCOMPtr<nsIInputStream> mPostData;
- nsString mDefaultFilename;
PRBool mBypassCache;
nsCString mContentType;
nsCString mContentDisposition;
diff --git a/embed/mozilla/MozDownload.cpp b/embed/mozilla/MozDownload.cpp
index 2c7be9a07..e6ee3d0eb 100644
--- a/embed/mozilla/MozDownload.cpp
+++ b/embed/mozilla/MozDownload.cpp
@@ -48,6 +48,8 @@
#include "netCore.h"
#include "nsIObserver.h"
+const char* const persistContractID = "@mozilla.org/embedding/browser/nsWebBrowserPersist;1";
+
MozDownload::MozDownload() :
mGotFirstStateChange(false), mIsNetworkTransfer(false),
mUserCanceled(false),
@@ -376,3 +378,97 @@ void
MozDownload::Resume()
{
}
+
+nsresult InitiateMozillaDownload (nsIDOMDocument *domDocument, nsIURI *sourceURI,
+ nsILocalFile* inDestFile, const char *contentType,
+ nsIURI* inOriginalURI, MozillaEmbedPersist *embedPersist,
+ PRBool bypassCache, nsIInputStream *postData)
+{
+ nsresult rv = NS_OK;
+
+ PRBool isHTML = (domDocument && contentType &&
+ (strcmp (contentType, "text/html") == 0 ||
+ strcmp (contentType, "text/xml") == 0 ||
+ strcmp (contentType, "application/xhtml+xml") == 0));
+
+ nsCOMPtr<nsIWebBrowserPersist> webPersist = do_CreateInstance(persistContractID, &rv);
+ if (NS_FAILED(rv)) return rv;
+
+ PRInt64 timeNow = PR_Now();
+
+ nsAutoString fileDisplayName;
+ inDestFile->GetLeafName(fileDisplayName);
+
+ MozDownload *downloader = new MozDownload ();
+ /* dlListener attaches to its progress dialog here, which gains ownership */
+ rv = downloader->InitForEmbed (inOriginalURI, inDestFile, fileDisplayName.get(),
+ nsnull, timeNow, webPersist, embedPersist);
+ if (NS_FAILED(rv)) return rv;
+
+ PRInt32 flags = nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION |
+ nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES;
+ if (bypassCache)
+ {
+ flags |= nsIWebBrowserPersist::PERSIST_FLAGS_BYPASS_CACHE;
+ }
+ else
+ {
+ flags |= nsIWebBrowserPersist::PERSIST_FLAGS_FROM_CACHE;
+ }
+
+ webPersist->SetPersistFlags(flags);
+
+ if (!isHTML)
+ {
+ rv = webPersist->SaveURI (sourceURI, nsnull, nsnull,
+ postData, nsnull, inDestFile);
+ }
+ else
+ {
+ if (!domDocument) return rv; /* should never happen */
+
+ PRInt32 encodingFlags = 0;
+ nsCOMPtr<nsILocalFile> filesFolder;
+
+ if (contentType && strcmp (contentType, "text/plain") == 0)
+ {
+ /* Create a local directory in the same dir as our file. It
+ will hold our associated files. */
+
+ filesFolder = do_CreateInstance("@mozilla.org/file/local;1");
+ nsAutoString unicodePath;
+ inDestFile->GetPath(unicodePath);
+ filesFolder->InitWithPath(unicodePath);
+
+ nsAutoString leafName;
+ filesFolder->GetLeafName(leafName);
+ nsAutoString nameMinusExt(leafName);
+ PRInt32 index = nameMinusExt.RFind(".");
+ if (index >= 0)
+ {
+ nameMinusExt.Left(nameMinusExt, index);
+ }
+
+ nameMinusExt += NS_LITERAL_STRING(" Files");
+ filesFolder->SetLeafName(nameMinusExt);
+ PRBool exists = PR_FALSE;
+ filesFolder->Exists(&exists);
+ if (!exists)
+ {
+ rv = filesFolder->Create(nsILocalFile::DIRECTORY_TYPE, 0755);
+ if (NS_FAILED(rv)) return rv;
+ }
+ }
+ else
+ {
+ encodingFlags |= nsIWebBrowserPersist::ENCODE_FLAGS_FORMATTED |
+ nsIWebBrowserPersist::ENCODE_FLAGS_ABSOLUTE_LINKS |
+ nsIWebBrowserPersist::ENCODE_FLAGS_NOFRAMES_CONTENT;
+ }
+
+ rv = webPersist->SaveDocument (domDocument, inDestFile, filesFolder,
+ contentType, encodingFlags, 80);
+ }
+
+ return rv;
+}
diff --git a/embed/mozilla/MozDownload.h b/embed/mozilla/MozDownload.h
index 56b8e16e1..49f0e6cc9 100644
--- a/embed/mozilla/MozDownload.h
+++ b/embed/mozilla/MozDownload.h
@@ -44,7 +44,9 @@
#include "nsIWebProgressListener.h"
#include "nsIHelperAppLauncherDialog.h"
#include "nsIExternalHelperAppService.h"
+#include "nsIDOMDocument.h"
+#include "nsString.h"
#include "nsIURI.h"
#include "nsILocalFile.h"
#include "nsIWebBrowserPersist.h"
@@ -74,6 +76,11 @@
#define MOZ_DOWNLOAD_CLASSNAME "Ephy's Download Progress Dialog"
+nsresult InitiateMozillaDownload (nsIDOMDocument *domDocument, nsIURI *sourceUri,
+ nsILocalFile* inDestFile, const char *contentType,
+ nsIURI* inOriginalURI, MozillaEmbedPersist *embedPersist,
+ PRBool bypassCache, nsIInputStream *postData);
+
class MozDownload : public nsIDownload,
public nsIWebProgressListener
{
diff --git a/embed/mozilla/mozilla-embed-persist.cpp b/embed/mozilla/mozilla-embed-persist.cpp
index 846b63c8d..8ba3596e8 100644
--- a/embed/mozilla/mozilla-embed-persist.cpp
+++ b/embed/mozilla/mozilla-embed-persist.cpp
@@ -20,6 +20,7 @@
#include "EphyWrapper.h"
#include "EphyHeaderSniffer.h"
+#include "MozDownload.h"
#include "mozilla-embed.h"
#include "mozilla-embed-persist.h"
@@ -206,10 +207,6 @@ impl_save (EphyEmbedPersist *persist)
rv = NS_NewURI(getter_AddRefs(inURI), sURI);
if (NS_FAILED(rv) || !inURI) return G_FAILED;
- /* Filename to save to */
- nsAutoString inFilename;
- inFilename.AssignWithConversion (filename);
-
/* Get post data */
nsCOMPtr<nsIInputStream> postData;
if (wrapper)
@@ -244,20 +241,37 @@ impl_save (EphyEmbedPersist *persist)
if (NS_FAILED(rv) || !DOMDocument) return G_FAILED;
}
- /* Create an header sniffer and do the save */
- nsCOMPtr<nsIWebBrowserPersist> webPersist =
- MOZILLA_EMBED_PERSIST (persist)->priv->mPersist;
- if (!webPersist) return G_FAILED;
-
- EphyHeaderSniffer* sniffer = new EphyHeaderSniffer
- (webPersist, MOZILLA_EMBED_PERSIST (persist),
- tmpFile, inURI, DOMDocument, postData,
- inFilename, flags & EMBED_PERSIST_BYPASSCACHE);
- if (!sniffer) return G_FAILED;
+ if (filename == NULL)
+ {
+ /* Create an header sniffer and do the save */
+ nsCOMPtr<nsIWebBrowserPersist> webPersist =
+ MOZILLA_EMBED_PERSIST (persist)->priv->mPersist;
+ if (!webPersist) return G_FAILED;
+
+ EphyHeaderSniffer* sniffer = new EphyHeaderSniffer
+ (webPersist, MOZILLA_EMBED_PERSIST (persist),
+ tmpFile, inURI, DOMDocument, postData,
+ flags & EMBED_PERSIST_BYPASSCACHE);
+ if (!sniffer) return G_FAILED;
- webPersist->SetProgressListener(sniffer);
- rv = webPersist->SaveURI(inURI, nsnull, nsnull, nsnull, nsnull, tmpFile);
- if (NS_FAILED (rv)) return G_FAILED;
+ webPersist->SetProgressListener(sniffer);
+ rv = webPersist->SaveURI(inURI, nsnull, nsnull, nsnull, nsnull, tmpFile);
+ if (NS_FAILED (rv)) return G_FAILED;
+ }
+ else
+ {
+ /* Filename to save to */
+ nsCOMPtr<nsILocalFile> destFile;
+ rv = NS_NewNativeLocalFile (nsDependentCString(filename),
+ PR_TRUE, getter_AddRefs(destFile));
+ if (NS_FAILED(rv) || !destFile) return G_FAILED;
+
+ rv = InitiateMozillaDownload (DOMDocument, inURI, destFile,
+ nsnull, inURI, MOZILLA_EMBED_PERSIST (persist),
+ flags & EMBED_PERSIST_BYPASSCACHE,
+ postData);
+ if (NS_FAILED (rv)) return G_FAILED;
+ }
return G_OK;
}