HTTP使用 multipart/form-data 上传多个字段(包括文件字节流 octet-stream)
自己用到的一个向服务器上传多个字段的实例,代码不全,仅做参考。
用的是WinINet,上传的字段中包括文件字节流
/*
PHttpRequest中自行组装body之后,HttpSendRequest中自己判断body长度时,
由于文件内容中存在 \0,所以body长度计算错误,导致上传的文件内容不正确,直接指定body的长度也不行...
PHttpRequest中未使用InternetWriteFile,
*/ int UpdateToServer2(stResumeInfo st, int& candId, CString& szUpdateTime, int& nFileSize)
{
HINTERNET hSession=;
HINTERNET hConnect=;
HINTERNET hRequest=; DWORD dwNumberOfBytesWritten=;
DWORD dwBytesSend=;
DWORD dwFlag = ; candId = ;
szUpdateTime.Empty();
hSession=InternetOpen(_T("Mozilla/5.0 (Windows NT 6.1; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0"),
INTERNET_OPEN_TYPE_PRECONFIG, , INTERNET_INVALID_PORT_NUMBER, );
if (==hSession)
{
LOG_INFO(L"----- updateResume InternetOpen return 0 !!! GetLastError: %d------", GetLastError());
return ;
} unsigned short port_ = INTERNET_DEFAULT_HTTP_PORT;
if (CConfig::GetServerType() == ) //外网用HTTPS
{
port_ = INTERNET_DEFAULT_HTTPS_PORT;
}
hConnect=InternetConnect(hSession, CConfig::URL_HOST, port_, _T(""), _T(""), INTERNET_SERVICE_HTTP, , ); //URL_HOST不能带http://
if (==hConnect)
{
InternetCloseHandle(hSession);
LOG_INFO(L"----- updateResume InternetConnect return 0 !!! GetLastError: %d------", GetLastError());
return ;
} dwFlag=INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_AUTH | INTERNET_FLAG_NO_UI ;
if (CConfig::GetServerType() == ) //外网用HTTPS
dwFlag |= INTERNET_FLAG_SECURE|INTERNET_FLAG_IGNORE_CERT_CN_INVALID|INTERNET_FLAG_IGNORE_CERT_DATE_INVALID|INTERNET_FLAG_IGNORE_REDIRECT_TO_HTTP ;
#ifdef UP_FILE_TO_SEVER
hRequest=HttpOpenRequest(hConnect, _T("POST"), RESUME_UPLOAD_URL, HTTP_VERSION, , , dwFlag, );//old
#else
hRequest=HttpOpenRequest(hConnect, _T("POST"), RESUME_UPLOAD_URL_NEW, HTTP_VERSION, , , dwFlag, );
#endif
if (==hRequest)
{
InternetCloseHandle(hConnect);
InternetCloseHandle(hSession);
LOG_INFO(L"----- updateResume HttpOpenRequest return 0 !!! GetLastError: %d------", GetLastError());
return ;
} if (m_bCancel) return ; //设置Header
//TCHAR content_type[128]={0};
//_stprintf_s(content_type,TEXT("Content-Type: multipart/form-data; boundary=%s"), _T(ABOUNDARY));
CString content_type = TEXT("Content-Type: multipart/form-data; boundary=");
content_type.Append(_T(ABOUNDARY));
HttpAddRequestHeaders(hRequest,content_type,-,HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE); //验证cid和token
CString szAuthorization = TEXT("Authorization: ");
szAuthorization.Append(/*CA2T(s64, CP_UTF8)*/CBackstageManager::GetInstance().GetAuthorizationString());
HttpAddRequestHeaders(hRequest,szAuthorization, -,HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE);
szAuthorization = TEXT("Agent-Info: ");
szAuthorization.Append(CBackstageManager::GetInstance().GetAgentInfo());
HttpAddRequestHeaders(hRequest,szAuthorization, -,HTTP_ADDREQ_FLAG_ADD|HTTP_ADDREQ_FLAG_REPLACE); #ifdef UP_FILE_TO_SEVER
//读取文件内容和长度
HANDLE hFile;
hFile=CreateFile(st.strFilePath, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, ,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, );
DWORD dwFileSize=GetFileSize(hFile,);
BYTE* lpBuffer=(BYTE*)VirtualAlloc(,dwFileSize,MEM_COMMIT,PAGE_READWRITE);
if (==lpBuffer)
{
InternetCloseHandle(hRequest);
InternetCloseHandle(hConnect);
InternetCloseHandle(hSession);
LOG_INFO(L"----- updateResume VirtualAlloc return 0 !!! GetLastError: %d------", GetLastError());
return ;
}
DWORD dwRead;
ReadFile(hFile,lpBuffer,dwFileSize,&dwRead,);
CloseHandle(hFile);
#endif char first_boundary[]={};
char delimiter[]={};
char end_boundary[]={};
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); //LPSTR rn="\r\n"; //HTTP POST数据中的换行必须使用\r\n
std::map<std::string, std::string> ssmap;
GetResumeInfoMap(st, ssmap); ////上传给后台必须使用字符串,不能用整型 //计算body长度
char content_dispos[]={};
std::map<std::string, std::string>::iterator it = ssmap.begin();
int length = strlen(first_boundary);
for(; it != ssmap.end(); it++)
{
memset(content_dispos, , sizeof(content_dispos));
sprintf_s(content_dispos,"Content-Disposition: form-data; name=\"%s\"\r\n\r\n", it->first.c_str());
length += strlen(content_dispos);
length += it->second.length();
length += strlen(delimiter);
} #ifdef UP_FILE_TO_SEVER
char content_dispos2[]={};
CString stmName = st.file_name;
if(stmName.GetLength() > )
{
stmName = stmName.Left() + PathFindExtension(stmName); //防止content_dispos2越界
}
std::string name = CT2A(stmName, CP_UTF8);
sprintf_s(content_dispos2, "Content-Disposition: form-data; name=\"file\"; filename=\"%s\"\r\n", name.c_str());
LPSTR content_type2="Content-Type: application/octet-stream\r\n\r\n"; //加上File长度
length +=dwFileSize + strlen(content_dispos2) +strlen(content_type2);
#else
length -= strlen(delimiter);
#endif
length += strlen(end_boundary); if (m_bCancel) return FALSE;
INTERNET_BUFFERS BufferIn;
BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS );
BufferIn.Next = NULL;
BufferIn.lpcszHeader = NULL;
BufferIn.dwHeadersLength = ;
BufferIn.dwHeadersTotal = ;
BufferIn.lpvBuffer = NULL;
BufferIn.dwBufferLength = ;
BufferIn.dwBufferTotal = length;
BufferIn.dwOffsetLow = ;
BufferIn.dwOffsetHigh = ; if (!HttpSendRequestEx(hRequest,&BufferIn,,,))
{
InternetCloseHandle(hRequest);
InternetCloseHandle(hConnect);
InternetCloseHandle(hSession);
LOG_INFO(L"----- updateResume HttpSendRequestEx return 0 !!! GetLastError: %d------", GetLastError());
return ;
} //上传body
InternetWriteFile(hRequest,(byte*)first_boundary,strlen(first_boundary),&dwNumberOfBytesWritten); //first boundary
int count = ssmap.size();
std::map<std::string, std::string>::iterator iter = ssmap.begin();
for(int index = ; iter != ssmap.end(); iter++, index++)
{
memset(content_dispos, , sizeof(content_dispos));
sprintf_s(content_dispos,"Content-Disposition: form-data; name=\"%s\"\r\n\r\n", iter->first.c_str());
InternetWriteFile(hRequest,(byte*)content_dispos, strlen(content_dispos),&dwNumberOfBytesWritten); std::string value = iter->second;
InternetWriteFile(hRequest,(byte*)value.c_str(), value.length(), &dwNumberOfBytesWritten); #ifndef UP_FILE_TO_SEVER
if(index != (count-))
#endif
InternetWriteFile(hRequest,(byte*)delimiter,strlen(delimiter),&dwNumberOfBytesWritten);
} if (m_bCancel) return ; #ifdef UP_FILE_TO_SEVER
//上传文件
InternetWriteFile(hRequest,(byte*)content_dispos2,strlen(content_dispos2),&dwNumberOfBytesWritten);
InternetWriteFile(hRequest,(byte*)content_type2,strlen(content_type2),&dwNumberOfBytesWritten);
InternetWriteFile(hRequest,lpBuffer,dwFileSize,&dwNumberOfBytesWritten);
#endif //last boundary
InternetWriteFile(hRequest,(byte*)end_boundary,strlen(end_boundary),&dwNumberOfBytesWritten); if(!HttpEndRequest(hRequest,,,))
{
int a = GetLastError();
HttpEndRequest(hRequest,,,);
} #ifdef UP_FILE_TO_SEVER
VirtualFree(lpBuffer,,MEM_RELEASE);
#endif
if (m_bCancel) return ;
//获取返回数据
std::stringstream sstream;
GetResponse(&sstream, hRequest, );
Json::Value root;
Json::Reader reader;
reader.parse(sstream.str(), root);
int code = -;
if(!root["code"].isNull())
{
code = root["code"].asInt(); //0表示成功,
}if(!root["data"].isNull())
{
Json::Value data = root["data"];
int userId = data["userId"].asInt();
candId = data["candId"].asInt();
int resumeId = data["resId"].asInt();
nFileSize = data["resSize"].asInt();
} InternetCloseHandle(hRequest);
InternetCloseHandle(hConnect);
InternetCloseHandle(hSession);
return ;
}
HTTP使用 multipart/form-data 上传多个字段(包括文件字节流 octet-stream)的更多相关文章
- django Form组件 上传文件
上传文件 注意:FORM表单提交文件要有一个参数enctype="multipart/form-data" 普通上传: urls: url(r'^f1/',views.f1), u ...
- 前端 - jquery方式 / iframe +form 方式 上传文件
环境与上一章一样 jquery 方式上传文件: HTML代码 {#html代码开始#} <input type="file" id="img" > ...
- 笔谈HTTP Multipart POST请求上传文件
公司一做iOS开发的同事用HTTP Multipart POST请求上传语音数据,但是做了两天都没搞定,项目经理找到我去帮忙弄下.以前做项目只用过get.post,对于现在这个跟服务器交互的表单请求我 ...
- 解决python发送multipart/form-data请求上传文件的问题
服务器接收文件时,有时会使用表单接收的方式,这意味着我们需要使用Python的requests上传表单数据和文件. 常用的方式一般如下: data = { 'name': 'nginx' } file ...
- python中使用multipart/form-data请求上传文件
最近测试的接口是上传文件的接口,上传单个文件,我主要使用了2种方法~ 接口例如: URL: http://www.baidu.com/*** method:post 参数: { "salar ...
- Unable to find ‘struts.multipart.saveDir’ Struts2上传文件错误的解决方法
Unable to find ‘struts.multipart.saveDir’ Struts2上传文件错误的解决方法 在使用struts2的项目中上传文件的时候出现了一个这样的错误: 2011-7 ...
- 使用python或robotframework调multipart/form-data接口上传文件
这几天调一个multipart/form-data类型的接口,遇到点小阻碍.之前同事有使用urllib库写了个类似的方法实现,比较长,想要改的时候发现不太好使.在网上查找发现用requests库做这个 ...
- 表单多文件上传样式美化 && 支持选中文件后删除相关项
开发中会经常涉及到文件上传的需求,根据业务不同的需求,有不同的文件上传情况. 有简单的单文件上传,有多文件上传,因浏览器原生的文件上传样式及功能的支持度不算太高,很多时候我们会对样式进行美化,对功能进 ...
- PHP文件上传设置和处理(多文件)
<!--upload.php文件内容--><?phpheader("Content-Type:text/html;charset=utf-8");/* //原来$ ...
随机推荐
- 2018-2019-1 20189218《Linux内核原理与分析》第七周作业
task_struck数据结构 在Linux内核中,通过task_struct这个结构体对进程进行管理,我们可以叫他PCB或者进程描述符.这个结构体定义在include/linux/sched.h中. ...
- libcurl HTTP POST请求向服务器发送json数据
转载:http://blog.csdn.net/dgyanyong/article/details/14166217 转载:http://blog.csdn.net/th_gsb/article/de ...
- Problem F: 等式
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 104 Solved: 22[Submit][Status][Web Board] Descriptio ...
- C简介与环境配置
C 语言是一种通用的高级语言,最初是由丹尼斯·里奇在贝尔实验室为开发 UNIX 操作系统而设计的.C 语言最开始是于 1972 年在 DEC PDP-11 计算机上被首次实现. 在 1978 年,布莱 ...
- vim的加密和解密?
vim中出现的错误提示含义: 参考: http://blog.csdn.net/u014599371/article/details/43955169 E488: trailing character ...
- VS中自动选择x86或x64的dll
http://www.cnblogs.com/lzjsky/archive/2010/09/06/1819321.html 原来使用Win7的32位系统,进行C#工程的开发,后来重装系统,换成了win ...
- 51NOD 1027 大数乘法
1027 大数乘法 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 给出2个大整数A,B,计算A*B的结果. Input 第1行:大数A 第2行:大数B (A,B ...
- c++之数组形参
1.问题,最近看项目log模块,_log模板函数中的一个参数竟然看蒙x了.函数原形是这样: template<size_t size>void _Log(char (&strDes ...
- HDU 1711 Number Sequence(KMP模板)
http://acm.hdu.edu.cn/showproblem.php?pid=1711 这道题就是一个KMP模板. #include<iostream> #include<cs ...
- TDD、BDD、DDD
TDDTest-Driven DevelopmentTest-Driven Development (TDD) is a software development technique where au ...