Merge pull request #9 from saghul/download_filename

Get update filename from Content-Disposition header if available
This commit is contained in:
Václav Slavík
2013-06-30 02:02:50 -07:00
3 changed files with 71 additions and 9 deletions

View File

@@ -154,6 +154,47 @@ void DownloadFile(const std::string& url, IDownloadSink *sink, int flags)
if ( GetHttpHeader(conn, HTTP_QUERY_CONTENT_LENGTH, contentLength) )
sink->SetLength(contentLength);
// Get filename fron Content-Disposition, if available
char contentDisposition[512];
DWORD cdSize = 512;
bool filename_set = false;
if ( HttpQueryInfoA(conn, HTTP_QUERY_CONTENT_DISPOSITION, contentDisposition, &cdSize, NULL) )
{
char *ptr = strstr(contentDisposition, "filename=");
if ( ptr )
{
char c_filename[512];
ptr += 9;
while ( *ptr == ' ' )
ptr++;
bool quoted = false;
if ( *ptr == '"' || *ptr == '\'')
{
quoted = true;
ptr++;
}
char *ptr2 = c_filename;
while ( *ptr != ';' && *ptr != 0)
*ptr2++ = *ptr++;
if ( quoted )
*(ptr2 - 1) = 0;
else
*ptr2 = 0;
std::string filename( c_filename );
sink->SetFilename(filename);
filename_set = true;
}
}
if ( !filename_set )
{
sink->SetFilename(GetURLFileName(url));
}
// Download the data:
for ( ;; )
{

View File

@@ -43,6 +43,11 @@ struct IDownloadSink
*/
virtual void SetLength(size_t len) = 0;
/**
Inform the sink of detected filename
*/
virtual void SetFilename(const std::string& filename) = 0;
/// Add chunk of downloaded data
virtual void Add(const void *data, size_t len) = 0;
};
@@ -54,6 +59,8 @@ struct StringDownloadSink : public IDownloadSink
{
virtual void SetLength(size_t) {}
virtual void SetFilename(const std::string& filename) {}
virtual void Add(const void *data, size_t len)
{
this->data.append(reinterpret_cast<const char*>(data), len);

View File

@@ -80,14 +80,11 @@ std::string CreateUniqueTempDirectory()
struct UpdateDownloadSink : public IDownloadSink
{
UpdateDownloadSink(Thread& thread, const std::string& filename)
UpdateDownloadSink(Thread& thread, const std::string& dir)
: m_thread(thread),
m_dir(dir), m_path(""), m_file(NULL),
m_downloaded(0), m_total(0), m_lastUpdate(-1)
{
m_file = fopen(filename.c_str(), "wb");
if ( !m_file )
throw std::runtime_error("Cannot save update file");
}
{}
~UpdateDownloadSink() { Close(); }
@@ -100,10 +97,26 @@ struct UpdateDownloadSink : public IDownloadSink
}
}
std::string GetFilePath(void) { return m_path; }
virtual void SetLength(size_t l) { m_total = l; }
virtual void SetFilename(const std::string& filename)
{
if ( m_file )
throw std::runtime_error("Update file already set");
m_path = m_dir + "\\" + filename;
m_file = fopen(m_path.c_str(), "wb");
if ( !m_file )
throw std::runtime_error("Cannot save update file");
}
virtual void Add(const void *data, size_t len)
{
if ( !m_file )
throw std::runtime_error("Filename is not net");
m_thread.CheckShouldTerminate();
if ( fwrite(data, len, 1, m_file) != 1 )
@@ -123,6 +136,8 @@ struct UpdateDownloadSink : public IDownloadSink
Thread& m_thread;
size_t m_downloaded, m_total;
FILE *m_file;
std::string m_dir;
std::string m_path;
clock_t m_lastUpdate;
};
@@ -154,11 +169,10 @@ void UpdateDownloader::Run()
const std::string tmpdir = CreateUniqueTempDirectory();
Settings::WriteConfigValue("UpdateTempDir", tmpdir);
std::string filename = tmpdir + "\\" + GetURLFileName(m_appcast.DownloadURL);
UpdateDownloadSink sink(*this, filename);
UpdateDownloadSink sink(*this, tmpdir);
DownloadFile(m_appcast.DownloadURL, &sink);
sink.Close();
UI::NotifyUpdateDownloaded(filename);
UI::NotifyUpdateDownloaded(sink.GetFilePath());
}
catch ( ... )
{