update FileDownload
This commit is contained in:
+94
-41
@@ -6,8 +6,10 @@
|
|||||||
#include "RageFileManager.h"
|
#include "RageFileManager.h"
|
||||||
#include "SpecialFiles.h"
|
#include "SpecialFiles.h"
|
||||||
#include "RageLog.h"
|
#include "RageLog.h"
|
||||||
|
#include "Preference.h"
|
||||||
|
#include "Foreach.h"
|
||||||
|
|
||||||
FileDownload::FileDownload()
|
FileTransfer::FileTransfer()
|
||||||
{
|
{
|
||||||
m_iPackagesPos = 0;
|
m_iPackagesPos = 0;
|
||||||
m_iLinksPos = 0;
|
m_iLinksPos = 0;
|
||||||
@@ -23,21 +25,18 @@ FileDownload::FileDownload()
|
|||||||
// Workaround: For some reason, the first download sometimes corrupts;
|
// Workaround: For some reason, the first download sometimes corrupts;
|
||||||
// by opening and closing the RageFile, this problem does not occur.
|
// by opening and closing the RageFile, this problem does not occur.
|
||||||
// Go figure?
|
// Go figure?
|
||||||
|
|
||||||
// XXX: This is a really dirty work around! Why does RageFile do this?
|
// XXX: This is a really dirty work around! Why does RageFile do this?
|
||||||
|
// It's always some strange number of bytes at the end of the file when it corrupts.
|
||||||
// It's always some strange number of bytes at the end of the
|
|
||||||
// file when it corrupts.
|
|
||||||
m_fOutputFile.Open("Packages/dummy.txt", RageFile::WRITE);
|
m_fOutputFile.Open("Packages/dummy.txt", RageFile::WRITE);
|
||||||
m_fOutputFile.Close();
|
m_fOutputFile.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
FileDownload::~FileDownload()
|
FileTransfer::~FileTransfer()
|
||||||
{
|
{
|
||||||
m_fOutputFile.Close();
|
m_fOutputFile.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
RString FileDownload::Update( float fDeltaTime )
|
RString FileTransfer::Update( float fDeltaTime )
|
||||||
{
|
{
|
||||||
HTTPUpdate();
|
HTTPUpdate();
|
||||||
|
|
||||||
@@ -55,7 +54,7 @@ RString FileDownload::Update( float fDeltaTime )
|
|||||||
return m_sStatus;
|
return m_sStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileDownload::UpdateProgress()
|
void FileTransfer::UpdateProgress()
|
||||||
{
|
{
|
||||||
float DownloadedRatio;
|
float DownloadedRatio;
|
||||||
|
|
||||||
@@ -65,7 +64,7 @@ void FileDownload::UpdateProgress()
|
|||||||
DownloadedRatio = float(m_iDownloaded) / float(m_iTotalBytes);
|
DownloadedRatio = float(m_iDownloaded) / float(m_iTotalBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileDownload::CancelDownload( )
|
void FileTransfer::Cancel()
|
||||||
{
|
{
|
||||||
m_wSocket.close();
|
m_wSocket.close();
|
||||||
m_bIsDownloading = false;
|
m_bIsDownloading = false;
|
||||||
@@ -77,7 +76,19 @@ void FileDownload::CancelDownload( )
|
|||||||
FILEMAN->Remove("Packages/" + m_sEndName);
|
FILEMAN->Remove("Packages/" + m_sEndName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileDownload::StartDownload( const RString &sURL, const RString &sDestFile )
|
void FileTransfer::StartDownload( const RString &sURL, const RString &sDestFile )
|
||||||
|
{
|
||||||
|
StartTransfer( download, sURL, "", sDestFile );
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileTransfer::StartUpload( const RString &sURL, const RString &sSrcFile, const RString &sDestFile )
|
||||||
|
{
|
||||||
|
StartTransfer( upload, sURL, sSrcFile, sDestFile );
|
||||||
|
}
|
||||||
|
|
||||||
|
extern Preference<RString> g_sCookie;
|
||||||
|
|
||||||
|
void FileTransfer::StartTransfer( TransferType type, const RString &sURL, const RString &sSrcFile, const RString &sDestFile )
|
||||||
{
|
{
|
||||||
RString Proto;
|
RString Proto;
|
||||||
RString Server;
|
RString Server;
|
||||||
@@ -87,16 +98,12 @@ void FileDownload::StartDownload( const RString &sURL, const RString &sDestFile
|
|||||||
if( !ParseHTTPAddress( sURL, Proto, Server, Port, sAddress ) )
|
if( !ParseHTTPAddress( sURL, Proto, Server, Port, sAddress ) )
|
||||||
{
|
{
|
||||||
m_sStatus = "Invalid URL.";
|
m_sStatus = "Invalid URL.";
|
||||||
|
m_bFinished = true;
|
||||||
UpdateProgress();
|
UpdateProgress();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Determine if this is a website, or a package?
|
m_bSavingFile = sDestFile != "";
|
||||||
//Criteria: does it end with *zip?
|
|
||||||
if( sAddress.Right(3).CompareNoCase("zip") == 0 )
|
|
||||||
m_bIsPackage=true;
|
|
||||||
else
|
|
||||||
m_bIsPackage = false;
|
|
||||||
|
|
||||||
m_sBaseAddress = "http://" + Server;
|
m_sBaseAddress = "http://" + Server;
|
||||||
if( Port != 80 )
|
if( Port != 80 )
|
||||||
@@ -115,22 +122,13 @@ void FileDownload::StartDownload( const RString &sURL, const RString &sDestFile
|
|||||||
|
|
||||||
// Open the file...
|
// Open the file...
|
||||||
|
|
||||||
//First find out if a file by this name already exists
|
// First find out if a file by this name already exists if so, then we gotta
|
||||||
//if so, then we gotta ditch out.
|
// ditch out.
|
||||||
// XXX: This should be fixed by a prompt or something?
|
// XXX: This should be fixed by a prompt or something?
|
||||||
|
|
||||||
// if we are not talking about a file, let's not worry
|
// if we are not talking about a file, let's not worry
|
||||||
if( m_sEndName != "" && m_bIsPackage )
|
if( m_sEndName != "" && m_bSavingFile )
|
||||||
{
|
{
|
||||||
vector<RString> AddTo;
|
|
||||||
GetDirListing( "Packages/"+m_sEndName, AddTo, false, false );
|
|
||||||
if ( AddTo.size() > 0 )
|
|
||||||
{
|
|
||||||
m_sStatus = "File Already Exists";
|
|
||||||
UpdateProgress();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !m_fOutputFile.Open( sDestFile, RageFile::WRITE | RageFile::STREAMED ) )
|
if( !m_fOutputFile.Open( sDestFile, RageFile::WRITE | RageFile::STREAMED ) )
|
||||||
{
|
{
|
||||||
m_sStatus = m_fOutputFile.GetError();
|
m_sStatus = m_fOutputFile.GetError();
|
||||||
@@ -158,14 +156,63 @@ void FileDownload::StartDownload( const RString &sURL, const RString &sDestFile
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Produce HTTP header
|
// Produce HTTP header
|
||||||
|
RString sAction;
|
||||||
|
switch( type )
|
||||||
|
{
|
||||||
|
case upload: sAction = "POST"; break;
|
||||||
|
case download: sAction = "GET"; break;
|
||||||
|
}
|
||||||
|
|
||||||
RString Header="";
|
vector<RString> vsHeaders;
|
||||||
|
vsHeaders.push_back( sAction+" "+sAddress+" HTTP/1.0" );
|
||||||
|
vsHeaders.push_back( "Host: " + Server );
|
||||||
|
vsHeaders.push_back( "Cookie: " + g_sCookie.Get() );
|
||||||
|
vsHeaders.push_back( "Connection: closed" );
|
||||||
|
string sBoundary = "--ZzAaB03x";
|
||||||
|
vsHeaders.push_back( "Content-Type: multipart/form-data; boundary=" + sBoundary );
|
||||||
|
RString sRequestPayload;
|
||||||
|
if( type == upload )
|
||||||
|
{
|
||||||
|
RageFile f;
|
||||||
|
if( !f.Open( sSrcFile ) )
|
||||||
|
FAIL_M( f.GetError() );
|
||||||
|
sRequestPayload.reserve( f.GetFileSize() );
|
||||||
|
int iBytesRead = f.Read( sRequestPayload );
|
||||||
|
if( iBytesRead == -1 )
|
||||||
|
FAIL_M( f.GetError() );
|
||||||
|
|
||||||
Header = "GET "+sAddress+" HTTP/1.0\r\n";
|
sRequestPayload = "--" + sBoundary + "\r\n" +
|
||||||
Header+= "Host: " + Server + "\r\n";
|
"Content-Disposition: form-data; name=\"name\"\r\n" +
|
||||||
Header+= "Connection: closed\r\n\r\n";
|
"\r\n" +
|
||||||
|
"Chris\r\n" +
|
||||||
|
"--" + sBoundary + "\r\n" +
|
||||||
|
"Content-Disposition: form-data; name=\"userfile\"; filename=\"" + Basename(sSrcFile) + "\"\r\n" +
|
||||||
|
"Content-Type: application/zip\r\n" +
|
||||||
|
"\r\n" +
|
||||||
|
sRequestPayload + "\r\n" +
|
||||||
|
"--" + sBoundary + "--";
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if( sRequestPayload.size() > 0 )
|
||||||
|
{
|
||||||
|
sHeader += "Content-Type: application/octet-stream\r\n";
|
||||||
|
sHeader += "Content-Length: multipart/form-data; boundary=" + sBoundary + "\r\n";
|
||||||
|
//sHeader += "Content-Length: " + ssprintf("%d",sRequestPayload.size()) + "\r\n";
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
vsHeaders.push_back( "Content-Length: " + ssprintf("%d",sRequestPayload.size()) );
|
||||||
|
|
||||||
|
RString sHeader;
|
||||||
|
FOREACH_CONST( RString, vsHeaders, h )
|
||||||
|
sHeader += *h + "\r\n";
|
||||||
|
sHeader += "\r\n";
|
||||||
|
|
||||||
|
m_wSocket.SendData( sHeader.c_str(), sHeader.length() );
|
||||||
|
m_wSocket.SendData( "\r\n" );
|
||||||
|
|
||||||
|
m_wSocket.SendData( sRequestPayload.GetBuffer(), sRequestPayload.size() );
|
||||||
|
|
||||||
m_wSocket.SendData( Header.c_str(), Header.length() );
|
|
||||||
m_sStatus = "Header Sent.";
|
m_sStatus = "Header Sent.";
|
||||||
m_wSocket.blocking = false;
|
m_wSocket.blocking = false;
|
||||||
m_bIsDownloading = true;
|
m_bIsDownloading = true;
|
||||||
@@ -187,14 +234,13 @@ static size_t FindEndOfHeaders( const RString &buf )
|
|||||||
return string::npos;
|
return string::npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileDownload::HTTPUpdate()
|
void FileTransfer::HTTPUpdate()
|
||||||
{
|
{
|
||||||
if( !m_bIsDownloading )
|
if( !m_bIsDownloading )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int BytesGot=0;
|
int BytesGot=0;
|
||||||
//Keep this as a code block
|
// Keep this as a code block, as there may be need to "if" it out some time.
|
||||||
//as there may be need to "if" it out some time.
|
|
||||||
/* If you need a conditional for a large block of code, stick it in
|
/* If you need a conditional for a large block of code, stick it in
|
||||||
* a function and return. */
|
* a function and return. */
|
||||||
while(1)
|
while(1)
|
||||||
@@ -241,7 +287,7 @@ void FileDownload::HTTPUpdate()
|
|||||||
m_sBUFFER.erase( 0, iHeaderEnd );
|
m_sBUFFER.erase( 0, iHeaderEnd );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_bIsPackage )
|
if( m_bSavingFile )
|
||||||
{
|
{
|
||||||
m_iDownloaded += m_sBUFFER.length();
|
m_iDownloaded += m_sBUFFER.length();
|
||||||
m_fOutputFile.Write( m_sBUFFER );
|
m_fOutputFile.Write( m_sBUFFER );
|
||||||
@@ -275,7 +321,7 @@ void FileDownload::HTTPUpdate()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( m_bIsPackage && m_iResponseCode < 300 )
|
if( m_bSavingFile && m_iResponseCode < 300 )
|
||||||
{
|
{
|
||||||
RString sZipFile = m_fOutputFile.GetRealPath();
|
RString sZipFile = m_fOutputFile.GetRealPath();
|
||||||
m_fOutputFile.Close();
|
m_fOutputFile.Close();
|
||||||
@@ -286,7 +332,7 @@ void FileDownload::HTTPUpdate()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileDownload::ParseHTTPAddress( const RString &URL, RString &sProto, RString &sServer, int &iPort, RString &sAddress )
|
bool FileTransfer::ParseHTTPAddress( const RString &URL, RString &sProto, RString &sServer, int &iPort, RString &sAddress )
|
||||||
{
|
{
|
||||||
// [PROTO://]SERVER[:PORT][/URL]
|
// [PROTO://]SERVER[:PORT][/URL]
|
||||||
|
|
||||||
@@ -316,9 +362,16 @@ bool FileDownload::ParseHTTPAddress( const RString &URL, RString &sProto, RStrin
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileDownload::IsFinished()
|
void FileTransfer::Finish()
|
||||||
{
|
{
|
||||||
return m_bFinished;
|
while( true )
|
||||||
|
{
|
||||||
|
float fSleepSeconds = 0.1f;
|
||||||
|
this->Update( fSleepSeconds );
|
||||||
|
usleep( int( fSleepSeconds * 1000000.0 ) );
|
||||||
|
if( this->IsFinished() )
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+18
-11
@@ -1,23 +1,30 @@
|
|||||||
/* FileDownload - Downloads a file from the Internet. */
|
#ifndef FileTransfer_H
|
||||||
#ifndef ScreenPackages_H
|
#define FileTransfer_H
|
||||||
#define ScreenPackages_H
|
|
||||||
|
|
||||||
#if !defined(WITHOUT_NETWORKING)
|
#if !defined(WITHOUT_NETWORKING)
|
||||||
|
|
||||||
#include "EzSockets.h"
|
#include "ezsockets.h"
|
||||||
#include "RageFile.h"
|
#include "RageFile.h"
|
||||||
|
|
||||||
class FileDownload
|
class FileTransfer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FileDownload();
|
FileTransfer();
|
||||||
~FileDownload();
|
~FileTransfer();
|
||||||
|
|
||||||
void StartDownload(const RString &sURL, const RString &sDestFile);
|
void StartDownload(const RString &sURL, const RString &sDestFile);
|
||||||
void CancelDownload( );
|
void StartUpload(const RString &sURL, const RString &sSrcFile, const RString &sDestFile);
|
||||||
|
|
||||||
|
void Cancel();
|
||||||
RString Update(float fDeltaTime);
|
RString Update(float fDeltaTime);
|
||||||
bool IsFinished();
|
bool IsFinished() const { return m_bFinished; }
|
||||||
|
void Finish();
|
||||||
|
int GetResponseCode() const { return m_iResponseCode; }
|
||||||
|
RString GetResponse() const { return m_sBUFFER; }
|
||||||
|
RString GetStatus() const { return m_sStatus; }
|
||||||
private:
|
private:
|
||||||
|
enum TransferType { download, upload };
|
||||||
|
void StartTransfer(TransferType type, const RString &sURL, const RString &sSrcFile, const RString &sDestFile);
|
||||||
int m_iPackagesPos;
|
int m_iPackagesPos;
|
||||||
int m_iLinksPos;
|
int m_iLinksPos;
|
||||||
|
|
||||||
@@ -43,10 +50,10 @@ private:
|
|||||||
|
|
||||||
RageFile m_fOutputFile;
|
RageFile m_fOutputFile;
|
||||||
RString m_sEndName;
|
RString m_sEndName;
|
||||||
bool m_bIsPackage;
|
bool m_bSavingFile;
|
||||||
|
|
||||||
RString m_sBaseAddress;
|
RString m_sBaseAddress;
|
||||||
// HTTP Header information response
|
// HTTP Header information responce
|
||||||
long m_iTotalBytes;
|
long m_iTotalBytes;
|
||||||
long m_iDownloaded;
|
long m_iDownloaded;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user