note : make a class, use wininet api upload http file
来源:互联网 发布:创维电视怎么连接网络 编辑:程序博客网 时间:2024/05/16 18:57
今天工作中遇到了要向http上载服务器传文件的功能.
查到有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());}
0 0
- note : make a class, use wininet api upload http file
- c# how to make app use a specified configure file
- angular-file-upload 中文API
- angular-file-upload 中文API
- upload large file use html and servlet
- Use apache upload framework to manage to upload file
- Handling file upload using commons file upload API
- HTTP API选择WinInet or WinHttp?
- 基于WinInet API的HTTP编程
- use curl to upload file with remote php file
- Android系统编译错误Note: Some input files use or override a deprecated API. 解决办法
- using http upload file to web server
- How does HTTP file upload work?
- Trick:Make use of HAL class(Symbian)
- use plupload plugin to upload file in django
- Use DropzondJS and Spring to upload and download file
- WinInet API
- make a apache core file
- linux 端口映射
- java 基础4 特性 封装 继承 多态
- ANR
- C++变量对齐
- vsftp配置指南
- note : make a class, use wininet api upload http file
- Linux MBR
- MiniUI - 快速开发WebUI
- 【JS】angular和require的区别
- 黑马程序员 Java基础学习笔记5 类
- wget 1.13.4 移植到嵌入式ARM上的过程
- Linux 下载文件命令
- 如何获取并发请求的trace文件,并解析
- hive,show tables报错解决方案。