note : make a class, use wininet api upload http file
2014-02-28 02:06
393 查看
今天工作中遇到了要向http上载服务器传文件的功能.
查到有2种方法做这事:
* 直接向http上载目录里用POST方法写文件.
* 假设有服务端的提交网页, 模拟网页提交文件.
我采用了最简单的第一种方法.
从网上找到一段代码, 整理了一个类, 参数变成活的了, 根据入参在类内部处理.
不记得从哪里找的了, 感谢~
整理后的类,用起来很简单。符合我的应用(给定一个本地文件全路径, 给定一个http远程文件夹全路径, 上传文件, 在远程存成一个随机的唯一文件名).
上载目录在服务器端用HFS搭建, 权限是任何人. 如果没有给定那个文件夹的上传权限,上传会失败.
上传中,没有使用用户名和口令.
类实现中,有一些工具函数(e.g. 取路径, 字符串格式化), 没有贴上。
调用端代码:
查到有2种方法做这事:
* 直接向http上载目录里用POST方法写文件.
* 假设有服务端的提交网页, 模拟网页提交文件.
我采用了最简单的第一种方法.
从网上找到一段代码, 整理了一个类, 参数变成活的了, 根据入参在类内部处理.
不记得从哪里找的了, 感谢~
整理后的类,用起来很简单。符合我的应用(给定一个本地文件全路径, 给定一个http远程文件夹全路径, 上传文件, 在远程存成一个随机的唯一文件名).
上载目录在服务器端用HFS搭建, 权限是任何人. 如果没有给定那个文件夹的上传权限,上传会失败.
上传中,没有使用用户名和口令.
类实现中,有一些工具函数(e.g. 取路径, 字符串格式化), 没有贴上。
调用端代码:
std::wstring strRemoteFilePathName = L""; CHttpUpLoader uploader; uploader.uploadHttpFile( pcZipPathName, ns_business::GetUrl_HttpUpload(), TRUE, strRemoteFilePathName);http文件上传类实现:
/// @file httpUploader.h /// @brief 向http上传服务器给定的文件夹上传文件 #ifndef __HTTP_UP_LOADER_H__ #define __HTTP_UP_LOADER_H__ class CHttpUpLoader { public: CHttpUpLoader(); ~CHttpUpLoader(); BOOL uploadHttpFile( IN const WCHAR * pcLocalFilePathName, ///< 本地文件全路径名称 IN const WCHAR * pcRemoteUploadDirPathName, ///< 远程http文件夹名称 IN BOOL bAutoRename, ///< 是否自动改名, 保证远程文件名唯一 OUT std::wstring & strRemoteFilePathName); ///< 保存后的远程文件全路径 private: void DataInit(); void SetLocalFilePathName(const WCHAR * pcLocalFilePathName); const WCHAR * GetLocalFilePathName(); void SetRemoteUploadDirPathName(const WCHAR * pcRemoteUploadDirPathName); const WCHAR * GetRemoteUploadDirPathName(); void SetRemoteFilePathName(const WCHAR * pcRemoteFilePathName); const WCHAR * GetRemoteFilePathName(); void SetAutoRename(BOOL bAutoRename); BOOL GetAutoRename(); const WCHAR * GetReferer(); void SetUrlSchema(const WCHAR * pcIn); const WCHAR * GetUrlSchema(); void SetIp(const WCHAR * pcIn); const WCHAR * GetIp(); void SetHttpPort(const WCHAR * pcIn); const WCHAR * GetHttpPort(); void SetSite(const WCHAR * pcIn); const WCHAR * GetSite(); void SetUrlPath(const WCHAR * pcIn); const WCHAR * GetUrlPath(); void SetRemoteFileName(const WCHAR * pcIn); const CHAR * GetRemoteFileNameA(); void GernerateRemoteFileName(); void SetFilePostfix(const WCHAR * pcFilePostfix); const WCHAR * GetFilePostfix(); const WCHAR * GetBoundaryW(); const char * GetBoundaryA(); private: std::wstring m_strLocalFilePathName; std::wstring m_strRemoteUploadDirPathName; std::wstring m_strRemoteFilePathName; BOOL m_bAutoRename; std::wstring m_strUrlSchema; // http std::wstring m_strIp; // 10.10.10.10 std::wstring m_strHttpPort; // 6666 需要自己去找, 分析不出来 std::wstring m_strSite; // http://10.10.10.10 std::wstring m_strUrlPath; // /upload/ std::wstring m_strRemoteFileName; std::string m_strRemoteFileNameA; std::wstring m_strFilePostfix; ///< 文件后缀 std::wstring m_strBoundaryW; std::string m_strBoundaryA; }; #endif
/// @file httpUploader.cpp #include "stdafx.h" #include "httpUploader.h" #include <WinInet.h> #pragma comment(lib, "Wininet.lib") #include <Urlmon.h> #pragma comment(lib, "Urlmon.lib") CHttpUpLoader::CHttpUpLoader() { DataInit(); } CHttpUpLoader::~CHttpUpLoader() { } void CHttpUpLoader::DataInit() { SetLocalFilePathName(L""); SetRemoteUploadDirPathName(L""); SetRemoteFilePathName(L""); SetAutoRename(TRUE); SetUrlSchema(L""); SetIp(L""); SetHttpPort(L""); SetSite(L""); SetUrlPath(L""); SetRemoteFileName(L""); SetFilePostfix(L""); } void CHttpUpLoader::SetLocalFilePathName(const WCHAR * pcLocalFilePathName) { size_t nPos = 0; m_strLocalFilePathName = (NULL != pcLocalFilePathName) ? pcLocalFilePathName : L""; nPos = m_strLocalFilePathName.rfind(L'.'); if (std::wstring::npos != nPos) { SetFilePostfix(m_strLocalFilePathName.substr(nPos + 1, -1).c_str()); } } void CHttpUpLoader::SetFilePostfix(const WCHAR * pcFilePostfix) { m_strFilePostfix = (NULL != pcFilePostfix) ? pcFilePostfix : L""; } const WCHAR * CHttpUpLoader::GetFilePostfix() { return m_strFilePostfix.c_str(); } const WCHAR * CHttpUpLoader::GetLocalFilePathName() { return m_strLocalFilePathName.c_str(); } void CHttpUpLoader::SetRemoteUploadDirPathName(const WCHAR * pcRemoteUploadDirPathName) { m_strRemoteUploadDirPathName = (NULL != pcRemoteUploadDirPathName) ? pcRemoteUploadDirPathName : L""; /// m_strRemoteUploadDirPathName like http://10.10.10.10:6666/upload/ size_t nPos = std::wstring::npos; size_t nPosTemp = std::wstring::npos; WCHAR szDecodedUrl[INTERNET_MAX_URL_LENGTH]; DWORD cchDecodedUrl = INTERNET_MAX_URL_LENGTH; WCHAR szOut[INTERNET_MAX_URL_LENGTH]; if (!m_strRemoteUploadDirPathName.empty()) { // m_strRemoteUploadDirPathName = http://10.10.10.10:6666/upload/ // szDecodedUrl = http://10.10.10.10:6666/upload/ HRESULT hr = CoInternetParseUrl(m_strRemoteUploadDirPathName.c_str(), PARSE_CANONICALIZE, URL_UNESCAPE, szDecodedUrl, INTERNET_MAX_URL_LENGTH, &cchDecodedUrl, 0); if (SUCCEEDED(hr)) { hr = CoInternetParseUrl(szDecodedUrl, PARSE_SCHEMA, 0, szOut, INTERNET_MAX_URL_LENGTH, &cchDecodedUrl, 0); if (SUCCEEDED(hr)) SetUrlSchema(szOut); // http hr = CoInternetParseUrl(szDecodedUrl, PARSE_DOMAIN, 0, szOut, INTERNET_MAX_URL_LENGTH, &cchDecodedUrl, 0); if (SUCCEEDED(hr)) SetIp(szOut); // 10.10.10.10 hr = CoInternetParseUrl(szDecodedUrl, PARSE_ROOTDOCUMENT, 0, szOut, INTERNET_MAX_URL_LENGTH, &cchDecodedUrl, 0); if (SUCCEEDED(hr)) SetSite(szOut); // http://10.10.10.10 nPos = m_strRemoteUploadDirPathName.find(m_strSite.c_str(), 0); if (std::wstring::npos != nPos) { SetHttpPort(L"80"); nPosTemp = nPos + _tcslen(m_strSite.c_str()); nPos = nPosTemp; if (L':' == m_strRemoteUploadDirPathName[nPosTemp]) { // port is given, not default port 80 nPos = m_strRemoteUploadDirPathName.find(L"/", ++nPosTemp); if (nPos != std::wstring::npos) SetHttpPort(m_strRemoteUploadDirPathName.substr(nPosTemp, nPos - nPosTemp).c_str()); nPos = nPosTemp + _tcslen(m_strHttpPort.c_str()); } SetUrlPath(m_strRemoteUploadDirPathName.substr(nPos, -1).c_str()); } } } } const WCHAR * CHttpUpLoader::GetRemoteUploadDirPathName() { return m_strRemoteUploadDirPathName.c_str(); } void CHttpUpLoader::SetRemoteFilePathName(const WCHAR * pcRemoteFilePathName) { m_strRemoteFilePathName = (NULL != pcRemoteFilePathName) ? pcRemoteFilePathName : L""; } const WCHAR * CHttpUpLoader::GetRemoteFilePathName() { return m_strRemoteFilePathName.c_str(); } void CHttpUpLoader::SetAutoRename(BOOL bAutoRename) { m_bAutoRename = bAutoRename; } BOOL CHttpUpLoader::GetAutoRename() { return m_bAutoRename; } const WCHAR * CHttpUpLoader::GetReferer() { return GetRemoteUploadDirPathName(); } const WCHAR * CHttpUpLoader::GetBoundaryW() { // L"-----------------------------67491722032265" // L"----------------------------06749,17220,32265" m_strBoundaryW = ns_base::StringFormatV(L"-----------------------------%5.5d%5.5d%5.5d", rand(), rand(), rand()); return m_strBoundaryW.c_str(); } const char * CHttpUpLoader::GetBoundaryA() { /// please call GetBoundaryW first, then call me USES_CONVERSION; m_strBoundaryA = W2A(m_strBoundaryW.c_str()); return m_strBoundaryA.c_str(); } BOOL CHttpUpLoader::uploadHttpFile( IN const WCHAR * pcLocalFilePathName, IN const WCHAR * pcRemoteUploadDirPathName, IN BOOL bAutoRename, OUT std::wstring & strRemoteFilePathName) { SetLocalFilePathName(pcLocalFilePathName); SetRemoteUploadDirPathName(pcRemoteUploadDirPathName); SetAutoRename(bAutoRename); GernerateRemoteFileName(); std::string strContentDispos = ""; HINTERNET hSession=0; HINTERNET hConnect=0; HINTERNET hRequest=0; DWORD dwNumberOfBytesWritten=0; DWORD dwBytesSend=0; INTERNET_BUFFERS BufferIn; DWORD dwFlag; LPCTSTR boundary = GetBoundaryW(); //随机字符串 LPCSTR aboundary = GetBoundaryA(); //ansi HANDLE hFile; hFile = CreateFile(pcLocalFilePathName, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); DWORD dwFileSize = GetFileSize(hFile, 0); TCHAR content_type[128]; _stprintf_s(content_type,TEXT("Content-Type: multipart/form-data; boundary=%s"),boundary); LPTSTR accept=TEXT("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"); LPTSTR accept_lan=TEXT("Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3"); LPTSTR accept_encoding=TEXT("Accept-Encoding: gzip, deflate"); LPTSTR user_agent=TEXT("User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0"); hSession=InternetOpen(_T("Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0"), INTERNET_OPEN_TYPE_PRECONFIG, 0, INTERNET_INVALID_PORT_NUMBER, 0); if (0==hSession) { return FALSE; } hConnect=InternetConnect(hSession, GetIp(), _ttoi(GetHttpPort()), _T(""), _T(""), INTERNET_SERVICE_HTTP, 0, 0); if (0==hConnect) { InternetCloseHandle(hSession); return FALSE; } dwFlag=INTERNET_FLAG_KEEP_CONNECTION; hRequest=HttpOpenRequest(hConnect, _T("POST"), GetUrlPath(), HTTP_VERSION, 0, //Referrer 0, //AcceptTypes dwFlag, 0); if (NULL == hRequest) { InternetCloseHandle(hConnect); InternetCloseHandle(hSession); return FALSE; } HttpAddRequestHeaders(hRequest,content_type,-1,HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE); HttpAddRequestHeaders(hRequest,GetReferer(),-1,HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE); HttpAddRequestHeaders(hRequest,accept,-1,HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE); HttpAddRequestHeaders(hRequest,accept_lan,-1,HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE); HttpAddRequestHeaders(hRequest,accept_encoding,-1,HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE); BYTE* lpBuffer=(BYTE*)VirtualAlloc(0,dwFileSize,MEM_COMMIT,PAGE_READWRITE); if (0==lpBuffer) { InternetCloseHandle(hRequest); InternetCloseHandle(hConnect); InternetCloseHandle(hSession); return FALSE; } DWORD dwRead; ReadFile(hFile,lpBuffer,dwFileSize,&dwRead,0); CloseHandle(hFile); char first_boundary[128]; char delimiter[128]; char end_boundary[128]; sprintf_s(first_boundary,"--%s\r\n",aboundary); sprintf_s(delimiter,"\r\n--%s\r\n",aboundary); sprintf_s(end_boundary,"\r\n--%s--\r\n",aboundary); strContentDispos = ns_base::StringFormatVA("Content-Disposition: form-data; name=\"file_upload\"; filename=\"%s\"\r\n", GetRemoteFileNameA()); LPCSTR content_dispos = strContentDispos.c_str(); LPSTR content_type2="Content-Type: application/octet-stream\r\n\r\n"; LPSTR rn="\r\n"; BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS ); BufferIn.Next = NULL; BufferIn.lpcszHeader = NULL; BufferIn.dwHeadersLength = 0; BufferIn.dwHeadersTotal = 0; BufferIn.lpvBuffer = NULL; BufferIn.dwBufferLength = 0; BufferIn.dwBufferTotal = dwFileSize +strlen(first_boundary) +strlen(content_dispos) +strlen(content_type2) +strlen(end_boundary); //Content-Length: BufferIn.dwOffsetLow = 0; BufferIn.dwOffsetHigh = 0; if (!HttpSendRequestEx(hRequest,&BufferIn,0,0,0)) { InternetCloseHandle(hRequest); InternetCloseHandle(hConnect); InternetCloseHandle(hSession); return FALSE; } InternetWriteFile(hRequest,(byte*)first_boundary,strlen(first_boundary),&dwNumberOfBytesWritten); //first boundary InternetWriteFile(hRequest,(byte*)content_dispos,strlen(content_dispos),&dwNumberOfBytesWritten); InternetWriteFile(hRequest,(byte*)content_type2,strlen(content_type2),&dwNumberOfBytesWritten); /// 分多次写远程文件, 就可以统计进度 InternetWriteFile(hRequest,lpBuffer,dwFileSize,&dwNumberOfBytesWritten); //如果还有其他文件 //InternetWriteFile(hRequest,(byte*)delimiter,strlen(delimiter),&dwNumberOfBytesWritten); //deimiter //InternetWriteFile(hRequest,(byte*)content_dispos,strlen(content_dispos),&dwNumberOfBytesWritten); //InternetWriteFile(hRequest,(byte*)content_type2,strlen(content_type2),&dwNumberOfBytesWritten); //... InternetWriteFile(hRequest,(byte*)end_boundary,strlen(end_boundary),&dwNumberOfBytesWritten);//last boundary HttpEndRequest(hRequest,0,0,0); InternetCloseHandle(hRequest); InternetCloseHandle(hConnect); InternetCloseHandle(hSession); VirtualFree(lpBuffer,0,MEM_RELEASE); return TRUE; } void CHttpUpLoader::SetUrlSchema(const WCHAR * pcIn) { m_strUrlSchema = (NULL != pcIn) ? pcIn : L""; } const WCHAR * CHttpUpLoader::GetUrlSchema() { return m_strUrlSchema.c_str(); } void CHttpUpLoader::SetIp(const WCHAR * pcIn) { m_strIp = (NULL != pcIn) ? pcIn : L""; } const WCHAR * CHttpUpLoader::GetIp() { return m_strIp.c_str(); } void CHttpUpLoader::SetHttpPort(const WCHAR * pcIn) { m_strHttpPort = (NULL != pcIn) ? pcIn : L""; } const WCHAR * CHttpUpLoader::GetHttpPort() { return m_strHttpPort.c_str(); } void CHttpUpLoader::SetSite(const WCHAR * pcIn) { m_strSite = (NULL != pcIn) ? pcIn : L""; } const WCHAR * CHttpUpLoader::GetSite() { return m_strSite.c_str(); } void CHttpUpLoader::SetUrlPath(const WCHAR * pcIn) { m_strUrlPath = (NULL != pcIn) ? pcIn : L""; } const WCHAR * CHttpUpLoader::GetUrlPath() { return m_strUrlPath.c_str(); } void CHttpUpLoader::SetRemoteFileName(const WCHAR * pcIn) { m_strRemoteFileName = (NULL != pcIn) ? pcIn : L""; } const CHAR * CHttpUpLoader::GetRemoteFileNameA() { USES_CONVERSION; m_strRemoteFileNameA = W2A(m_strRemoteFileName.c_str()); return m_strRemoteFileNameA.c_str(); } void CHttpUpLoader::GernerateRemoteFileName() { std::wstring strFileName = L""; SYSTEMTIME stLocal; GetLocalTime(&stLocal); strFileName = ns_base::StringFormatV(L"%s_%4.4d%2.2d%2.2d_%2.2d%2.2d%2.2d_%3.3d_%5.5d.%s", UPLOAD_FILE_TYPE, stLocal.wYear, stLocal.wMonth, stLocal.wDay, stLocal.wHour, stLocal.wMinute, stLocal.wSecond, stLocal.wMilliseconds, rand(), GetFilePostfix()); SetRemoteFileName(strFileName.c_str()); }
相关文章推荐
- 《UNIX网络编程》源码的使用
- 【Objective-C】Http常用API、同步请求与异步请求
- 简单配置HTTPS 认证访问
- Java网络编程入门
- windows7的internet协议(TCP/IP
- 习近平:把我国从网络大国建设成为网络强国
- 在Centos下安装httpd、php、Mysql并配置(转载)
- 【Python】设置网络中某设备的MAC地址会影响socket获取IP
- http://yui.github.io/yui2/docs/yui_2.9.0_full/reset/index.html#code
- 做网络推广必备九大查询工具
- 开源项目:LoopJ(Android Asynchronous Http Client - 开源http 多线程引擎)
- 服务器开发【三】----网络编程的基础SOCKET(3)
- TCP/IP详解
- Java网络编程从入门到精通(1):Internet地址概述
- 常见网络端口和网络协议
- HttpModule的认识
- 计算机网络基础_3_网络层的作用(下) --ICMP和ARP的工作原理
- HttpClient4.X 升级 入门 + http连接池使用-too many open files
- 解决google地图无法使用网络定位的问题
- Tomcat 中响应头信息(Http Response Header) Content-Length 和 Transfer-Encoding 之种种