模拟postman上传数据,主要是json数据和文件数据
bool PostJsonFile(char*& pData, UINT& dataLen, CString& szError, const CString& szObject ,const CString& szServer, int nPort, LPVOID lpOptional /*= NULL*/, DWORD dwOptionalLen /*= 0*/, PCTSTR szToken)
{
CInternetSession session(_T("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36"), 0);
CHttpConnection* pConnection = NULL;
CHttpFile* pFile = NULL;
try
{
DWORD ServerType = 0;
CString StrServer;
CString StrObj;
INTERNET_PORT ServerPort = 0;
if (AfxParseURL(Url, ServerType, StrServer, StrObj, ServerPort))
{
if (AFX_INET_SERVICE_HTTP != ServerType && AFX_INET_SERVICE_HTTPS != ServerType)
{
return false;
}
if (ServerType == AFX_INET_SERVICE_HTTPS)
{
pConnection = session.GetHttpConnection(StrServer, INTERNET_FLAG_SECURE, ServerPort,NULL,NULL);//取得一个Https连接
}
if (ServerType == AFX_INET_SERVICE_HTTP)
{
pConnection = session.GetHttpConnection(StrServer, ServerPort);//取得一个Https连接
}
}
CHCHttpFile* pFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST, szObject,
NULL, 1, NULL, NULL, INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE);
/*设置请求相关参数*/
//pFile->AddRequestHeaders(_T("Accept: */*,application/json"));//accept请求报头域,表示客户端接受哪些类型的信息
//pFile->AddRequestHeaders(_T("Accept-Charset:UTF8"));
//pFile->AddRequestHeaders(_T("Accept-Language: zh-CN,zh;q=0.9"));
//pFile->AddRequestHeaders(_T("X-Requested-With:XMLHttpRequest"));
pFile->AddRequestHeaders(_T("Accept:*/*"));
pFile->AddRequestHeaders(_T("Accept-Charset:UTF8"));
if (szToken != nullptr && _tcslen(szToken) > 0)
{
CString strAccesstoken = _T("access_token: ");
strAccesstoken += szToken;
pFile->AddRequestHeaders(strAccesstoken);
}
pFile->AddRequestHeaders(_T("Content-Type:application/json"));
pFile->SendRequest(NULL, 0, lpOptional, dwOptionalLen);
DWORD dwRet;
pFile->QueryInfoStatusCode(dwRet);//查询执行状态
if(dwRet != 200)
{
szError.Format(_T("请求失败,HTTP错误码: %d"), dwRet);
delete pFile;
return false;
}
UINT nBufferPhysicalLen = 16 * 1024;
pData = new char[nBufferPhysicalLen];
char* pBuffer = pData;
UINT nBufferLen = nBufferPhysicalLen - 1;
UINT nTotalReaded = 0;
UINT nReaded = 0;
while ((nReaded = pFile->Read((void*)pBuffer, nBufferLen)) > 0)
{
nTotalReaded += nReaded;
pBuffer += nReaded;
if (nBufferPhysicalLen - nTotalReaded < 512)
{ //buffer长度在2M以下时,每次重新申请时长度翻倍;超过2M时,每次加2M
if (nBufferPhysicalLen < 2 * 1024 * 1024)
{
nBufferPhysicalLen *= 2;
}
else
{
nBufferPhysicalLen += 2 * 1024 * 1024;
}
char* pNewData = new char[nBufferPhysicalLen];
memcpy(pNewData, pData, nTotalReaded);
nBufferLen = nBufferPhysicalLen - nTotalReaded - 1;
delete[] pData;
pData = pNewData;
pBuffer = pNewData + nTotalReaded;
}
}
dataLen = nTotalReaded;
pData[nTotalReaded] = '\0';
dataLen++;
delete pFile;
}
catch (CInternetException* e)
{
CString sErrMsg;
e->GetErrorMessage(sErrMsg.GetBuffer(1024), 1024);
sErrMsg.ReleaseBuffer();
szError.Format(_T("%s/%s 请求失败,%s"), szServer,szObject, sErrMsg);
return false;
}
catch (CException* e)
{
e->GetErrorMessage(szError.GetBuffer(1024), 1024);
szError.ReleaseBuffer();
e->Delete();
return false;
}
return true;
}
bool CMyDlg::PostData()
{
CJsonObj sJson;
sJson.AddItem(_T("username"), _T("张三"));
sJson.AddItem(_T("password"), _T("123"));
char* pData = NULL;
UINT uLen = 0;
CString strError;
char* utf8Data = NULL;
int nUft8Len = CGlobal::Ansi2UTF8(sJson.CreateJson(), utf8Data);
CString sObject(_T("/api/login"));
CString strServer = _T("127.0.0.1");
CString strPort = _T("8027");
int nPort = _tstoi(strPort);
bool bRet = PostJsonFile(pData, uLen, strError, sObject, strServer, nPort, utf8Data, nUft8Len);
delete[] utf8Data;
utf8Data = NULL;
UTF82TCHAR u2t(pData);
delete[] pData;
if (!bRet)
{
if (strError.IsEmpty())
OutputDebugString(strError);
return false;
}
CJsonObj resultJson;
if (resultJson.Load(u2t.Data()) == false)
{
return false;
}
int nStatus = -1;
if (!resultJson.ValueEx(_T("status"), nStatus, false) || nStatus < 0)
{
return false;
}
CHCString strMsg;
if (nStatus > 0)
{
return false;
}
}
bool PostUploadFile(LPCTSTR Url,LPCTSTR sAaccess_token, wstring UploadName, char*& _RetStr, const std::string& _FilePath, wstring strLocalFileName,std::wstring wsGuid)
{
CInternetSession session("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36", 0);
CHttpConnection* pConnection = NULL;
CHttpFile* pFile = NULL;
try{
DWORD ServerType = 0;
CString StrServer;
CString StrObj;
INTERNET_PORT ServerPort = 0;
if (AfxParseURL(Url, ServerType, StrServer, StrObj, ServerPort))
{
if (AFX_INET_SERVICE_HTTP != ServerType && AFX_INET_SERVICE_HTTPS != ServerType)
{
return false;
}
if (ServerType == AFX_INET_SERVICE_HTTPS)
{
pConnection = session.GetHttpConnection(StrServer, INTERNET_FLAG_SECURE, ServerPort,NULL,NULL);//取得一个Https连接
}
if (ServerType == AFX_INET_SERVICE_HTTP)
{
pConnection = session.GetHttpConnection(StrServer, ServerPort);//取得一个Https连接
}
if (pConnection)
{
if (ServerType == AFX_INET_SERVICE_HTTPS)
{
pFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST, StrObj, NULL, 1,
NULL, NULL, INTERNET_FLAG_SECURE |
INTERNET_FLAG_EXISTING_CONNECT |
INTERNET_FLAG_RELOAD |
INTERNET_FLAG_NO_CACHE_WRITE |
INTERNET_FLAG_IGNORE_CERT_DATE_INVALID |
INTERNET_FLAG_IGNORE_CERT_CN_INVALID |
INTERNET_FLAG_NO_COOKIES);//打开请求 ,这几个标识都要加上
}
if (ServerType == AFX_INET_SERVICE_HTTP)
{
pFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST, StrObj);
}
if (pFile)
{
/*szBoundary,任意的一个串,用以标识body中的数据*/
//该串需要够复杂,用以区别当前请求包中的数据
const char * szBoundary = "----------------------------096304854221961038114493";
/*构造头部*/
pFile->AddRequestHeaders("Accept:*/*");
pFile->AddRequestHeaders("Accept-Encoding:gzip, deflate");
//pFile->AddRequestHeaders("access_token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0aW1lU3RhbXAiOjE2NDIwNDM3NTY0NDgsImFjY291bnRJZCI6IjY3NDQ4MDk0OTMxOTAwNzA1OTgifQ.hhIwLw0IoQSitrvy7-V8wclnNokZ_EM1tggBEPaelHk");
//构造头中的access_token项
CString szAccesstoken = _T("access_token: ");
szAccesstoken += sAaccess_token;
pFile->AddRequestHeaders(szAccesstoken.GetBuffer(0));
//构造头中的Content-Type项,其中需要填上boundary
CString szContentType = _T("Content-Type:multipart/form-data; boundary=");
szContentType += szBoundary;
pFile->AddRequestHeaders(szContentType.GetBuffer(0));
/*打开文件,合成每个文件头部数据,取出文件数据,以及合成尾部数据,计算总长度*/
struct DataInfo
{
char* pBuf;
DWORD BufLen;
DataInfo()
{
ZeroMemory(this, sizeof(DataInfo));
}
};
std::vector<DataInfo> DataInfoList;
wstring strGuid = wsGuid;
char key1[1024] = { 0 };
sprintf(key1, "\r\n------------------------------096304854221961038114493\r\n"
"Content-Disposition: form-data;name=\"projectId\" \r\n\r\n%s", UnicodeToUtf8(strGuid).c_str());
char key2[1024] = { 0 };
sprintf(key2, "\r\n------------------------------096304854221961038114493\r\n"
"Content-Disposition: form-data;name=\"needUnZip\" \r\n\r\n%s","false");
char key3[1024] = { 0 };
sprintf(key3, "\r\n------------------------------096304854221961038114493\r\n"
"Content-Disposition: form-data;name=\"depot\" \r\n\r\n%s","release");
char strconnet[1024];
sprintf(strconnet, "\r\n------------------------------096304854221961038114493\r\n"
"Content-Disposition:form-data;name=\"%s\";filename=\"%s\"\r\n"
"Content-Type:application/zip\r\n\r\n", UnicodeToUtf8(UploadName).c_str(), UnicodeToUtf8(strLocalFileName).c_str());
string temp = key1;
temp += key2;
temp += key3;
temp += strconnet;
std::string filePath = _FilePath;
if (filePath.empty())
{
return false;
}
DWORD dwTotalBodyLen = 0;
CFile _File;
if (_File.Open(filePath.c_str(), CFile::modeRead | CFile::shareDenyWrite | CFile::typeBinary))
{
//CString FileName = _File.GetFileName();
//每个文件的头部信息
DataInfo preDi;
preDi.BufLen = strlen(temp.c_str());
preDi.pBuf = new char[preDi.BufLen];
memcpy(preDi.pBuf, temp.c_str(), preDi.BufLen);
DataInfoList.push_back(preDi);
dwTotalBodyLen += preDi.BufLen;
//文件内容
DataInfo ContDi;
ContDi.BufLen = (DWORD)_File.GetLength();
ContDi.pBuf = new char[ContDi.BufLen];
_File.Read(ContDi.pBuf, ContDi.BufLen);
DataInfoList.push_back(ContDi);
dwTotalBodyLen += ContDi.BufLen;
}
//尾长度
const char* szEndContent =
"\r\n"
"------------------------------096304854221961038114493--\r\n";
DataInfo EndDi;
EndDi.BufLen = strlen(szEndContent);
EndDi.pBuf = new char[EndDi.BufLen];
memcpy(EndDi.pBuf, szEndContent, EndDi.BufLen);
DataInfoList.push_back(EndDi);
dwTotalBodyLen += EndDi.BufLen;
/*发送数据*/
pFile->SendRequestEx(dwTotalBodyLen, HSR_SYNC | HSR_INITIATE);
std::vector<DataInfo>::iterator itInfo = DataInfoList.begin();
for (; itInfo != DataInfoList.end(); itInfo++)
{
pFile->Write(itInfo->pBuf, itInfo->BufLen);
delete[]itInfo->pBuf;
}
pFile->EndRequest(HSR_SYNC);
/*获取状态*/
DWORD dwStatusCode = -1;
pFile->QueryInfoStatusCode(dwStatusCode);
if (dwStatusCode == HTTP_STATUS_OK)
{
//读返回
_RetStr = new char[(DWORD)pFile->GetLength()];
pFile->Read(_RetStr, (UINT)pFile->GetLength());
if (pFile)
{
delete pFile;
}
if (pConnection)
{
delete pConnection;
}
session.Close();
return true;
}
}
}
}
}
catch (CInternetException* e)
{
delete e;
}
if (pFile)
delete pFile;
if (pConnection)
delete pConnection;
session.Close();
return false;
}