mirror of
https://github.com/HackPlan/winsparkle.git
synced 2026-04-29 18:45:06 +08:00
Merge pull request #9 from saghul/download_filename
Get update filename from Content-Disposition header if available
This commit is contained in:
@@ -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 ( ;; )
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 ( ... )
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user