314 lines
7.1 KiB
C++
314 lines
7.1 KiB
C++
//+-----------------------------------------------------------------------
|
|
//
|
|
// Microsoft Network
|
|
// Copyright (C) Microsoft Corporation, 1998
|
|
//
|
|
// File: HttpFilePost.h
|
|
//
|
|
// Contents:
|
|
// CHttpFilePoster
|
|
// RFC 1867 file uploader
|
|
//
|
|
// Posts files to an http server using HTTP POST
|
|
//
|
|
// Links:
|
|
// RFC 1867 - Form-based File Upload in HTML : http://www.ietf.org/rfc/rfc1867.txt
|
|
// RFC 1521 - MIME (Multipurpose Internet Mail Extensions) : http://www.ietf.org/rfc/rfc1521.txt
|
|
//
|
|
//
|
|
// Author: Noah Booth (noahb@microsoft.com)
|
|
//
|
|
// Revision History:
|
|
//
|
|
// 2/5/99 noahb created
|
|
// 4/25/99 noahb integration with MSN communities
|
|
//------------------------------------------------------------------------
|
|
|
|
#ifndef __HttpFilePost_h__
|
|
#define __HttpFilePost_h__
|
|
|
|
|
|
//#define _USE_INTERNAL_UTF8_ALWAYS_
|
|
|
|
|
|
#include "stdstring.h"
|
|
#include "utf8str.h"
|
|
#include <list>
|
|
#include <map>
|
|
|
|
class CUploaderException
|
|
{
|
|
public:
|
|
DWORD m_dwError;
|
|
|
|
CUploaderException(DWORD dwError = 0) : m_dwError(dwError) { }
|
|
~CUploaderException() { }
|
|
};
|
|
|
|
void ThrowUploaderException(DWORD dwError = -1);
|
|
|
|
#define UPLOAD_BUFFSIZE 4096
|
|
#define DELAY_TIME 0
|
|
|
|
#define UPLOAD_WM_THREAD_DONE WM_USER + 0x10
|
|
|
|
|
|
//forward decl
|
|
class CHFPInternetSession;
|
|
class CProgressInfo;
|
|
|
|
|
|
#define DEFAULT_DESCRIPTION ""
|
|
|
|
class CHttpFilePoster
|
|
{
|
|
public:
|
|
static bool Mbcs2UTF8(CStdString& strOut, const CStdString& strIn)
|
|
{
|
|
USES_CONVERSION;
|
|
bool bResult = false;
|
|
|
|
#ifdef _USE_INTERNAL_UTF8_ALWAYS_
|
|
|
|
CUTF8String strUTF8(A2W(strIn.c_str()));
|
|
strOut = (LPSTR) strUTF8;
|
|
|
|
bResult = SUCCEEDED(strUTF8.GetError());
|
|
#else
|
|
DWORD cbLength = 0;
|
|
CHAR* psz = NULL;
|
|
WCHAR* pwsz = A2W(strIn.c_str());
|
|
|
|
cbLength = WideCharToMultiByte(CP_UTF8, 0, pwsz, -1, NULL, 0, NULL, NULL);
|
|
if(cbLength)
|
|
{
|
|
psz = (CHAR*) _alloca(cbLength);
|
|
cbLength = WideCharToMultiByte(CP_UTF8, 0, pwsz, -1, psz, cbLength, NULL, NULL);
|
|
if(cbLength)
|
|
{
|
|
strOut = psz;
|
|
bResult = true;
|
|
}
|
|
else
|
|
{
|
|
strOut = "";
|
|
}
|
|
}
|
|
|
|
if(!bResult) // only use CUTF8String if WideCharToMultiByte fails..
|
|
{
|
|
CUTF8String strUTF8(A2W(strIn.c_str()));
|
|
strOut = (LPSTR) strUTF8;
|
|
|
|
bResult = SUCCEEDED(strUTF8.GetError());
|
|
|
|
}
|
|
#endif
|
|
return bResult;
|
|
}
|
|
|
|
|
|
protected:
|
|
|
|
class CUploaderFile
|
|
{
|
|
public:
|
|
CStdString strName; //UTF8 filename
|
|
CStdString strNameMBCS; //MBCS Filename
|
|
DWORD dwSize;
|
|
CStdString strMime; //UTF8
|
|
CStdString strTitle; //UTF8
|
|
CStdString strDescription; //UTF8
|
|
BOOL bDelete;
|
|
|
|
CUploaderFile(
|
|
const CStdString& n,
|
|
DWORD s,
|
|
BOOL b,
|
|
const CStdString& m,
|
|
const CStdString& t,
|
|
const CStdString& d = DEFAULT_DESCRIPTION) :
|
|
strNameMBCS(n),
|
|
bDelete(b),
|
|
dwSize(s)
|
|
{
|
|
Mbcs2UTF8(strName, n);
|
|
Mbcs2UTF8(strMime, m);
|
|
Mbcs2UTF8(strTitle, t);
|
|
Mbcs2UTF8(strDescription, d);
|
|
}
|
|
|
|
CUploaderFile(const CUploaderFile& o)
|
|
{
|
|
*this = o;
|
|
}
|
|
|
|
CUploaderFile& operator=(const CUploaderFile& o)
|
|
{
|
|
strName = o.strName;
|
|
strNameMBCS = o.strNameMBCS;
|
|
dwSize = o.dwSize;
|
|
bDelete = o.bDelete;
|
|
strMime = o.strMime;
|
|
strTitle = o.strTitle;
|
|
strDescription = o.strDescription;
|
|
return *this;
|
|
}
|
|
|
|
~CUploaderFile()
|
|
{
|
|
if(bDelete)
|
|
{
|
|
DeleteFileA(strName.c_str());
|
|
}
|
|
}
|
|
};
|
|
|
|
typedef std::list<CUploaderFile*> TFileList;
|
|
typedef std::map<CStdString, CStdString> TFormMap;
|
|
typedef TFileList::iterator TFileListIterator;
|
|
typedef TFormMap::iterator TFormMapIterator;
|
|
|
|
|
|
HWND m_hWndParent;
|
|
|
|
INTERNET_BUFFERS m_internetBuffers;
|
|
|
|
|
|
|
|
CStdString m_strHttpServer;
|
|
CStdString m_strHttpObject;
|
|
|
|
INTERNET_PORT m_nPort;
|
|
DWORD m_dwService;
|
|
bool m_bSinglePost;
|
|
|
|
CUploaderFile* m_pCurrentFile;
|
|
|
|
|
|
|
|
DWORD m_dwFileCount; //total number of files to be posted
|
|
DWORD m_dwTotalFileBytes; //total bumber of bytes to be posted from files, filenames, and mimetype strings
|
|
|
|
TFileList m_listFiles;
|
|
TFormMap m_mapFormData;
|
|
|
|
DWORD_PTR m_dwContext;
|
|
|
|
|
|
HINTERNET m_hSession;
|
|
HINTERNET m_hConnection;
|
|
HINTERNET m_hFile;
|
|
|
|
|
|
int m_iStatus;
|
|
|
|
CStdString m_strLoginName;
|
|
CStdString m_strPassword;
|
|
|
|
CStdString m_strSitePostingURL;
|
|
|
|
CStdString m_strBoundary;
|
|
|
|
CStdString m_strFileHeader;
|
|
CStdString m_strFilePost;
|
|
CStdString m_strCommonPost;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void DrainSocket();
|
|
bool QueryStatusCode(DWORD& dwStatus);
|
|
|
|
|
|
bool CleanupUpload();
|
|
bool BeginUpload(CProgressInfo* pProgressInfo);
|
|
bool FinishUpload();
|
|
bool CancelUpload();
|
|
|
|
|
|
bool Connect();
|
|
bool Disconnect();
|
|
|
|
bool Startup();
|
|
bool Shutdown();
|
|
|
|
bool IsConnected();
|
|
|
|
bool RequestHead();
|
|
|
|
|
|
CStdString GetMimeType(const CHAR* szFilename);
|
|
|
|
DWORD CalculateContentLength(CUploaderFile* pFile);
|
|
|
|
bool SendString(const CStdString& str);
|
|
|
|
bool SendHeader();
|
|
bool SendFile(CProgressInfo* pProgressInfo);
|
|
|
|
static UINT UploadThreadProc(LPVOID pThis);
|
|
|
|
static void CALLBACK InternetStatusCallback(
|
|
HINTERNET hInternet,
|
|
DWORD_PTR dwContext,
|
|
DWORD dwInternetStatus,
|
|
LPVOID lpvStatusInformation,
|
|
DWORD dwStatusInformationLength
|
|
);
|
|
|
|
bool FindTempDirectory();
|
|
|
|
void GenBoundaryString();
|
|
|
|
void BuildFilePostHeader(CUploaderFile* pFile);
|
|
void BuildFilePost(CUploaderFile* pFile);
|
|
void BuildCommonPost();
|
|
|
|
void CrackPostingURL();
|
|
|
|
public:
|
|
|
|
enum
|
|
{
|
|
HFP_UNINITIALIZED,
|
|
HFP_INITIALIZED,
|
|
HFP_TRANSFERING,
|
|
HFP_TRANSFERCOMPLETE
|
|
};
|
|
|
|
|
|
CHttpFilePoster();
|
|
~CHttpFilePoster();
|
|
|
|
|
|
int GetStatus() { return m_iStatus; }
|
|
|
|
bool DoUpload(CProgressInfo* pProgress);
|
|
HRESULT ForegroundUpload( CProgressInfo *pProgressInfo );
|
|
|
|
DWORD AddFile(const CStdString& strFileName, const CStdString& strTitle, DWORD dwFileSize, BOOL bDelete);
|
|
DWORD RemoveFile(DWORD dwIndex);
|
|
void AddFormData(const CStdString& strName, const CStdString& strValue);
|
|
DWORD GetFileCount();
|
|
void Reset();
|
|
|
|
|
|
void Initialize(const CStdString& strPostingURL, HWND hWndParent)
|
|
{ SetPostingURL(strPostingURL); SetParentWnd(hWndParent); }
|
|
|
|
inline DWORD GetTotalSize() { return m_dwTotalFileBytes; }
|
|
|
|
void SetPostingURL(const CStdString& strURL) {
|
|
m_strSitePostingURL = strURL;
|
|
if(strURL != "") CrackPostingURL();
|
|
}
|
|
CStdString GetPostingURL(void) { return m_strSitePostingURL; }
|
|
|
|
void SetParentWnd(HWND hWnd) { m_hWndParent = hWnd; }
|
|
HWND GetParentWnd(void) { return m_hWndParent; }
|
|
|
|
};
|
|
|
|
#endif //__HttpFilePost_h__
|