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");/* //原来$ ...
随机推荐
- 20145101《Java程序设计》第10周学习总结
20145101<Java程序设计>第10周学习总结 教材学习内容总结 网络编程 网络编程的实质就是两个(或多个)设备(例如计算机)之间的数据传输. 计算机网络 路由器和交换机组成了核心的 ...
- 20145328《网络对抗技术》Final
系内选拔赛write-up 1 信息隐藏 第一题图片藏东西,后缀名改txt,没有发现,改rar,发现压缩包内存在key.txt,解压提示存在密码,尝试使用修复,得到key.txt,打开获取flag,S ...
- 強化 Python 在 Vim 裡的顏色
我習慣用 putty 連 Unix server 開 screen,再用 vim 寫 Python.這篇記錄如何改善 Python 的顏色. 啟動 256 色 terminal 首先將可用的色彩數增加 ...
- 写Java代码的一些小技巧
写Java代码有三年多了,遇到过很多坑,也有一些小小的心得.特地分享出来供各位学习交流.这些技巧主要涉及谷歌Guava工具类的使用.Java 8新特性的使用.DSL风格开发.代码封装等技巧. 一.nu ...
- flash,sram
flash写入的内容不会因电源关闭而失去,读取速度慢,成本较低,一般用作程序存储器或者低速数据读取的情况. sram有最快的读写速度,但电源掉落后其内容也会失去,价格昂贵,一般用作cpu的二级缓存,内 ...
- UNIX网络编程--简介(一)【转】
本文转载自:http://blog.csdn.net/yusiguyuan/article/details/11760187 一.概述 a) 在编写与计算机通信的程序时,首先要确定的就是和计算机通信的 ...
- Linux内核同步机制--自旋锁【转】
本文转载自:http://www.cppblog.com/aaxron/archive/2013/04/12/199386.html 自旋锁与互斥锁有点类似,只是自旋锁不会引起调用者睡眠,如果自旋锁已 ...
- BZOJ3300: [USACO2011 Feb]Best Parenthesis 模拟
Description Recently, the cows have been competing with strings of balanced parentheses and compari ...
- Network Simulator for P4(NSP4) src内容介绍
Structure What's NSP4? src source code introduction What's NSP4? NSP4是一个用于P4的网络仿真工具,旨在简化P4的环境部署和运行,将 ...
- POJ 3667 Hotel(线段树+区间合并)
http://poj.org/problem?id=3667 题意: 有N个房间,M次操作.有两种操作(1)"1a",表示找到连续的长度为a的空房间,如果有多解,优先左边的,即表示 ...