Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

313 lines
7.1 KiB

  1. //+-----------------------------------------------------------------------
  2. //
  3. // Microsoft Network
  4. // Copyright (C) Microsoft Corporation, 1998
  5. //
  6. // File: HttpFilePost.h
  7. //
  8. // Contents:
  9. // CHttpFilePoster
  10. // RFC 1867 file uploader
  11. //
  12. // Posts files to an http server using HTTP POST
  13. //
  14. // Links:
  15. // RFC 1867 - Form-based File Upload in HTML : http://www.ietf.org/rfc/rfc1867.txt
  16. // RFC 1521 - MIME (Multipurpose Internet Mail Extensions) : http://www.ietf.org/rfc/rfc1521.txt
  17. //
  18. //
  19. // Author: Noah Booth ([email protected])
  20. //
  21. // Revision History:
  22. //
  23. // 2/5/99 noahb created
  24. // 4/25/99 noahb integration with MSN communities
  25. //------------------------------------------------------------------------
  26. #ifndef __HttpFilePost_h__
  27. #define __HttpFilePost_h__
  28. //#define _USE_INTERNAL_UTF8_ALWAYS_
  29. #include "stdstring.h"
  30. #include "utf8str.h"
  31. #include <list>
  32. #include <map>
  33. class CUploaderException
  34. {
  35. public:
  36. DWORD m_dwError;
  37. CUploaderException(DWORD dwError = 0) : m_dwError(dwError) { }
  38. ~CUploaderException() { }
  39. };
  40. void ThrowUploaderException(DWORD dwError = -1);
  41. #define UPLOAD_BUFFSIZE 4096
  42. #define DELAY_TIME 0
  43. #define UPLOAD_WM_THREAD_DONE WM_USER + 0x10
  44. //forward decl
  45. class CHFPInternetSession;
  46. class CProgressInfo;
  47. #define DEFAULT_DESCRIPTION ""
  48. class CHttpFilePoster
  49. {
  50. public:
  51. static bool Mbcs2UTF8(CStdString& strOut, const CStdString& strIn)
  52. {
  53. USES_CONVERSION;
  54. bool bResult = false;
  55. #ifdef _USE_INTERNAL_UTF8_ALWAYS_
  56. CUTF8String strUTF8(A2W(strIn.c_str()));
  57. strOut = (LPSTR) strUTF8;
  58. bResult = SUCCEEDED(strUTF8.GetError());
  59. #else
  60. DWORD cbLength = 0;
  61. CHAR* psz = NULL;
  62. WCHAR* pwsz = A2W(strIn.c_str());
  63. cbLength = WideCharToMultiByte(CP_UTF8, 0, pwsz, -1, NULL, 0, NULL, NULL);
  64. if(cbLength)
  65. {
  66. psz = (CHAR*) _alloca(cbLength);
  67. cbLength = WideCharToMultiByte(CP_UTF8, 0, pwsz, -1, psz, cbLength, NULL, NULL);
  68. if(cbLength)
  69. {
  70. strOut = psz;
  71. bResult = true;
  72. }
  73. else
  74. {
  75. strOut = "";
  76. }
  77. }
  78. if(!bResult) // only use CUTF8String if WideCharToMultiByte fails..
  79. {
  80. CUTF8String strUTF8(A2W(strIn.c_str()));
  81. strOut = (LPSTR) strUTF8;
  82. bResult = SUCCEEDED(strUTF8.GetError());
  83. }
  84. #endif
  85. return bResult;
  86. }
  87. protected:
  88. class CUploaderFile
  89. {
  90. public:
  91. CStdString strName; //UTF8 filename
  92. CStdString strNameMBCS; //MBCS Filename
  93. DWORD dwSize;
  94. CStdString strMime; //UTF8
  95. CStdString strTitle; //UTF8
  96. CStdString strDescription; //UTF8
  97. BOOL bDelete;
  98. CUploaderFile(
  99. const CStdString& n,
  100. DWORD s,
  101. BOOL b,
  102. const CStdString& m,
  103. const CStdString& t,
  104. const CStdString& d = DEFAULT_DESCRIPTION) :
  105. strNameMBCS(n),
  106. bDelete(b),
  107. dwSize(s)
  108. {
  109. Mbcs2UTF8(strName, n);
  110. Mbcs2UTF8(strMime, m);
  111. Mbcs2UTF8(strTitle, t);
  112. Mbcs2UTF8(strDescription, d);
  113. }
  114. CUploaderFile(const CUploaderFile& o)
  115. {
  116. *this = o;
  117. }
  118. CUploaderFile& operator=(const CUploaderFile& o)
  119. {
  120. strName = o.strName;
  121. strNameMBCS = o.strNameMBCS;
  122. dwSize = o.dwSize;
  123. bDelete = o.bDelete;
  124. strMime = o.strMime;
  125. strTitle = o.strTitle;
  126. strDescription = o.strDescription;
  127. return *this;
  128. }
  129. ~CUploaderFile()
  130. {
  131. if(bDelete)
  132. {
  133. DeleteFileA(strName.c_str());
  134. }
  135. }
  136. };
  137. typedef std::list<CUploaderFile*> TFileList;
  138. typedef std::map<CStdString, CStdString> TFormMap;
  139. typedef TFileList::iterator TFileListIterator;
  140. typedef TFormMap::iterator TFormMapIterator;
  141. HWND m_hWndParent;
  142. INTERNET_BUFFERS m_internetBuffers;
  143. CStdString m_strHttpServer;
  144. CStdString m_strHttpObject;
  145. INTERNET_PORT m_nPort;
  146. DWORD m_dwService;
  147. bool m_bSinglePost;
  148. CUploaderFile* m_pCurrentFile;
  149. DWORD m_dwFileCount; //total number of files to be posted
  150. DWORD m_dwTotalFileBytes; //total bumber of bytes to be posted from files, filenames, and mimetype strings
  151. TFileList m_listFiles;
  152. TFormMap m_mapFormData;
  153. DWORD_PTR m_dwContext;
  154. HINTERNET m_hSession;
  155. HINTERNET m_hConnection;
  156. HINTERNET m_hFile;
  157. int m_iStatus;
  158. CStdString m_strLoginName;
  159. CStdString m_strPassword;
  160. CStdString m_strSitePostingURL;
  161. CStdString m_strBoundary;
  162. CStdString m_strFileHeader;
  163. CStdString m_strFilePost;
  164. CStdString m_strCommonPost;
  165. protected:
  166. void DrainSocket();
  167. bool QueryStatusCode(DWORD& dwStatus);
  168. bool CleanupUpload();
  169. bool BeginUpload(CProgressInfo* pProgressInfo);
  170. bool FinishUpload();
  171. bool CancelUpload();
  172. bool Connect();
  173. bool Disconnect();
  174. bool Startup();
  175. bool Shutdown();
  176. bool IsConnected();
  177. bool RequestHead();
  178. CStdString GetMimeType(const CHAR* szFilename);
  179. DWORD CalculateContentLength(CUploaderFile* pFile);
  180. bool SendString(const CStdString& str);
  181. bool SendHeader();
  182. bool SendFile(CProgressInfo* pProgressInfo);
  183. static UINT UploadThreadProc(LPVOID pThis);
  184. static void CALLBACK InternetStatusCallback(
  185. HINTERNET hInternet,
  186. DWORD_PTR dwContext,
  187. DWORD dwInternetStatus,
  188. LPVOID lpvStatusInformation,
  189. DWORD dwStatusInformationLength
  190. );
  191. bool FindTempDirectory();
  192. void GenBoundaryString();
  193. void BuildFilePostHeader(CUploaderFile* pFile);
  194. void BuildFilePost(CUploaderFile* pFile);
  195. void BuildCommonPost();
  196. void CrackPostingURL();
  197. public:
  198. enum
  199. {
  200. HFP_UNINITIALIZED,
  201. HFP_INITIALIZED,
  202. HFP_TRANSFERING,
  203. HFP_TRANSFERCOMPLETE
  204. };
  205. CHttpFilePoster();
  206. ~CHttpFilePoster();
  207. int GetStatus() { return m_iStatus; }
  208. bool DoUpload(CProgressInfo* pProgress);
  209. HRESULT ForegroundUpload( CProgressInfo *pProgressInfo );
  210. DWORD AddFile(const CStdString& strFileName, const CStdString& strTitle, DWORD dwFileSize, BOOL bDelete);
  211. DWORD RemoveFile(DWORD dwIndex);
  212. void AddFormData(const CStdString& strName, const CStdString& strValue);
  213. DWORD GetFileCount();
  214. void Reset();
  215. void Initialize(const CStdString& strPostingURL, HWND hWndParent)
  216. { SetPostingURL(strPostingURL); SetParentWnd(hWndParent); }
  217. inline DWORD GetTotalSize() { return m_dwTotalFileBytes; }
  218. void SetPostingURL(const CStdString& strURL) {
  219. m_strSitePostingURL = strURL;
  220. if(strURL != "") CrackPostingURL();
  221. }
  222. CStdString GetPostingURL(void) { return m_strSitePostingURL; }
  223. void SetParentWnd(HWND hWnd) { m_hWndParent = hWnd; }
  224. HWND GetParentWnd(void) { return m_hWndParent; }
  225. };
  226. #endif //__HttpFilePost_h__