1. У меня заголовок
работает.
2. Пробовал разные кодировки в запросе передавать на сервер yandex.ru - он все равно выдает результат запроса в кодировке UTF-8.
3. Правильнее будет после получения результата запроса определить заголовок ответа (HttpQueryInfo), а в нем кодировку ответа. Исходя из кодировки ответа раскодировать текст. Вот мой код потока, который умеет посылать данные формы на сервер, приаттаченный файл, получать данные с сервера в ассинхронном режиме:
DWORD WINAPI ClientWinHttpThreadProc(LPVOID pParam)
{
CSendRequestHttp* srh=(CSendRequestHttp*)pParam;
HINTERNET hSession = NULL,
hConnect = NULL,
hRequest = NULL;
INTERNET_BUFFERS BufferIn;
int i, j, len, pos=0;
CString s, s1, s2, s_pred, s_post, WriteData="";
char* bufer=NULL;
char* buf1=NULL;
char* buf2=NULL;
char* buffile=NULL;
char* buffiletemp=NULL;
char* buffiletemp2=NULL;
DWORD dwBytesWritten;
DWORD dwBytesToWrite;
DWORD dwStatusSize;
CAtlFile file;
ULONGLONG lenfilesize=0, lenbuffiles=0, posbuffile=0;
BOOL flag_attach=FALSE;
BOOL flag_postdata=FALSE;
//CAtlArray<CParamAttach> ExtParamsAttach;
if(srh->getIsProxy())
{
hSession=::InternetOpen(srh->getAppName(), INTERNET_OPEN_TYPE_PROXY,
srh->getProxyName(), srh->getProxyBypass(), 0);
}
else
{
hSession=::InternetOpen(srh->getAppName(), /*INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY*/INTERNET_OPEN_TYPE_PRECONFIG, NULL,
NULL, 0);
};
if(hSession==NULL)
{
::MessageBox(NULL, "InternetOpen filed", "Error", MB_OK | MB_ICONERROR);
srh->m_RequestState=SESSION_CLOSE;
return 0;
};
srh->m_RequestState=SESSION_OPEN;
if(srh->pRequestStateProc!=NULL)
srh->pRequestStateProc(srh->m_RequestState, srh->m_OutHeader, srh->m_OutData, WriteData);
switch(srh->getTypeProtocol())
{
case TYPE_HTTP:
hConnect=::InternetConnect(hSession, srh->getServerName(), srh->getPort()/*INTERNET_DEFAULT_HTTP_PORT*/,
srh->getUserName(), srh->getPassword(), INTERNET_SERVICE_HTTP, 0, NULL);
break;
case TYPE_HTTPS:
hConnect=::InternetConnect(hSession, srh->getServerName(), INTERNET_DEFAULT_HTTPS_PORT,
srh->getUserName(), srh->getPassword(), INTERNET_SERVICE_HTTP, 0, NULL);
break;
};
if(hConnect==NULL)
{
srh->WriteMsgToLog("InternetConnect filed");
srh->m_RequestState=SESSION_CLOSE;
return 0;
};
srh->m_RequestState=CONNECT;
if(srh->pRequestStateProc!=NULL)
srh->pRequestStateProc(srh->m_RequestState, srh->m_OutHeader, srh->m_OutData, WriteData);
switch(srh->getTypeProtocol())
{
case TYPE_HTTP:
hRequest=::HttpOpenRequest(hConnect, srh->getTypeRequest(), srh->getObjectName(),
NULL, NULL, NULL, /*INTERNET_FLAG_NO_CACHE_WRITE*/INTERNET_FLAG_KEEP_CONNECTION, NULL);
break;
case TYPE_HTTPS:
hRequest=::HttpOpenRequest(hConnect, srh->getTypeRequest(), srh->getObjectName(),
NULL, NULL, NULL, INTERNET_FLAG_SECURE, NULL);
break;
};
if(hRequest==NULL)
{
srh->WriteMsgToLog("HttpOpenRequest filed");
srh->m_RequestState=SESSION_CLOSE;
return 0;
};
srh->m_RequestState=OPEN_REQUEST;
if(srh->pRequestStateProc!=NULL)
srh->pRequestStateProc(srh->m_RequestState, srh->m_OutHeader, srh->m_OutData, WriteData);
if(srh->getSendData()=="")
{
if(srh->getpRequestAttachParam()!=NULL)
{
if(srh->getpRequestAttachParam()->getCountFileAttachParams()>0)
{
for(int i=0; i<srh->getpRequestAttachParam()->getCountFileAttachParams(); i++)
{
if(SUCCEEDED(file.Create(srh->getpRequestAttachParam()->getFileAttachParamAt(i).getAttachFilePatch(),
GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING)))
{
if(SUCCEEDED(file.GetSize(lenfilesize)))
{
s=CString("-----------------------------7d636b240634")+CString("\r\n")+
CString("Content-Disposition: form-data; name=")+CString('"')+
srh->getpRequestAttachParam()->getFileAttachParamAt(i).getNameParamFormFileName()+
CString('"')+CString("; filename=")+CString('"')+srh->getpRequestAttachParam()->getFileAttachParamAt(i).getNameFileAttach()+
CString('"')+CString("\r\n")+CString("Content-Type: application/octet-stream")+CString("\r\n\r\n");
if(i>0)
s=CString("\r\n")+s;
if(buffiletemp!=NULL)
{
delete [] buffiletemp;
buffiletemp=NULL;
};
buffiletemp=new char[s.GetLength()+lenfilesize];
::ZeroMemory(buffiletemp, s.GetLength()+lenfilesize);
strcpy(buffiletemp, s);
if(SUCCEEDED(file.Read(&buffiletemp[s.GetLength()], lenfilesize)))
{
if(!flag_attach)
{
flag_attach=TRUE;
srh->getpRequestHeaderParam()->AddRequestHeader("Content-Type: multipart/form-data; boundary=---------------------------7d636b240634");
};
lenbuffiles+=s.GetLength()+lenfilesize;
if(buffiletemp2!=NULL)
{
delete [] buffiletemp2;
buffiletemp2=NULL;
};
buffiletemp2=new char[lenbuffiles];
::ZeroMemory(buffiletemp2, lenbuffiles);
if(buffile!=NULL)
{
memcpy(buffiletemp2, buffile, posbuffile);
};
memcpy(&buffiletemp2[posbuffile], buffiletemp, s.GetLength()+lenfilesize);
posbuffile=lenbuffiles;
if(buffile!=NULL)
{
delete [] buffile;
buffile=NULL;
};
buffile=new char[lenbuffiles];
::ZeroMemory(buffile, lenbuffiles);
memcpy(buffile, buffiletemp2, lenbuffiles);
};
file.Close();
};
};
};
if(buffile==NULL)
{
flag_attach=FALSE;
srh->getpRequestHeaderParam()->DelRequestHeader("Content-Type: multipart/form-data; boundary=---------------------------7d636b240634");
};
};
};
};
if(srh->getpRequestPostDataParam()!=NULL)
{
if(srh->getpRequestPostDataParam()->GetRequestPostData()!="")
{
flag_postdata=TRUE;
if(flag_attach)
{
s=srh->getpRequestPostDataParam()->GetRequestPostData();
do
{
s1=s;
i=s.Find("&", 0);
if(i!=-1)
{
s1.Delete(i, s1.GetLength()-i);
s.Delete(0, i+1);
};
j=s1.Find("=", 0);
if(j==-1)
{
if(i==-1)
break;
else
continue;
};
s2=s1;
s1.Delete(j, s1.GetLength()-j);
s2.Delete(0, j+1);
srh->getpRequestAttachParam()->AddExtAttachParam(s1, s2);
}while(i!=-1);
}
else
srh->getpRequestHeaderParam()->AddRequestHeader("Content-Type: application/x-www-form-urlencoded");
};
};
if(srh->getpRequestHeaderParam()!=NULL)
{
if(srh->getpRequestHeaderParam()->GetRequestHeaders()!="")
{
if(!HttpAddRequestHeaders(hRequest, srh->getpRequestHeaderParam()->GetRequestHeaders(),
srh->getpRequestHeaderParam()->GetRequestHeaders().GetLength(), HTTP_ADDREQ_FLAG_ADD))
{
srh->WriteMsgToLog("HttpAddRequestHeaders filed");
}
else
{
srh->m_RequestState=ADD_REQUEST_HEADERS;
if(srh->pRequestStateProc!=NULL)
srh->pRequestStateProc(srh->m_RequestState, srh->m_OutHeader, srh->m_OutData, WriteData);
};
};
};
BufferIn.dwStructSize=sizeof(INTERNET_BUFFERS); // Must be set or error will occur
BufferIn.Next=NULL;
BufferIn.lpcszHeader=NULL;
BufferIn.dwHeadersLength=0;
BufferIn.dwHeadersTotal=0;
if((!flag_postdata)||(flag_attach))
{
BufferIn.lpvBuffer=NULL;
BufferIn.dwBufferLength=0;
}
else
{
if(flag_postdata)
{
buf2=new char[srh->getpRequestPostDataParam()->GetRequestPostData().GetLength()+1];
::ZeroMemory(buf2, srh->getpRequestPostDataParam()->GetRequestPostData().GetLength()+1);
strcpy(buf2, srh->getpRequestPostDataParam()->GetRequestPostData()+"\n");
BufferIn.lpvBuffer=buf2;
BufferIn.dwBufferLength=srh->getpRequestPostDataParam()->GetRequestPostData().GetLength()+1;
}
else
{
BufferIn.lpvBuffer=NULL;
BufferIn.dwBufferLength=0;
};
};
if(!flag_attach)
{
BufferIn.dwBufferTotal=srh->getSendData().GetLength(); // This is the only member used other than dwStructSize
len=BufferIn.dwBufferTotal;
}
else
{
s_pred=srh->getpRequestAttachParam()->getExtAttachParam();
s_post=CString("\r\n-----------------------------7d636b240634--");
BufferIn.dwBufferTotal=s_pred.GetLength()+lenbuffiles+s_post.GetLength();
len=lenbuffiles;
};
BufferIn.dwOffsetLow=0;
BufferIn.dwOffsetHigh=0;
if(!::HttpSendRequestEx(hRequest, &BufferIn, NULL, 0, 0))
{
srh->WriteMsgToLog("HttpSendRequestEx filed");
srh->m_RequestState=SESSION_CLOSE;
return 0;
};
srh->m_RequestState=SEND_REQUEST;
if(srh->pRequestStateProc!=NULL)
srh->pRequestStateProc(srh->m_RequestState, srh->m_OutHeader, srh->m_OutData, WriteData);
if(len>0)
{
if(flag_attach)
{
if(bufer!=NULL)
{
delete [] bufer;
bufer=NULL;
};
bufer=new char[s_pred.GetLength()+1];
::ZeroMemory(bufer, s_pred.GetLength()+1);
strcpy(bufer, s_pred);
bufer[s_pred.GetLength()]=0;
if(::InternetWriteFile(hRequest, bufer, s_pred.GetLength(), &dwBytesWritten))
{
do
{
if(len<=1024)
{
dwBytesToWrite=len;
//len=0;
}
else
{
dwBytesToWrite=1024;
};
if(bufer!=NULL)
{
delete [] bufer;
bufer=NULL;
};
bufer=new char[dwBytesToWrite];
::ZeroMemory(bufer, dwBytesToWrite);
memcpy(bufer, &buffile[pos], dwBytesToWrite);
pos+=1024;
len-=1024;
if(!::InternetWriteFile(hRequest, bufer, dwBytesToWrite, &dwBytesWritten))
{
srh->WriteMsgToLog("InternetWriteFile filed");
break;
}
else
{
WriteData=CString(bufer);
srh->m_RequestState=WRITE_DATA;
if(srh->pRequestStateProc!=NULL)
srh->pRequestStateProc(srh->m_RequestState, srh->m_OutHeader, srh->m_OutData, WriteData);
};
}while(len>0);
if(bufer!=NULL)
{
delete [] bufer;
bufer=NULL;
};
bufer=new char[s_post.GetLength()+1];
::ZeroMemory(bufer, s_post.GetLength()+1);
strcpy(bufer, s_post);
bufer[s_post.GetLength()]=0;
if(!::InternetWriteFile(hRequest, bufer, s_post.GetLength(), &dwBytesWritten))
srh->WriteMsgToLog("InternetWriteFile filed");
}
else
srh->WriteMsgToLog("InternetWriteFile filed");
}
else
{
do
{
if(bufer!=NULL)
{
delete [] bufer;
bufer=NULL;
};
bufer=new char[1024];
if(len<=1024)
{
s=srh->getSendData().Mid(pos, len);
dwBytesToWrite=len;
len=0;
}
else
{
s=srh->getSendData().Mid(pos, 1024);
pos+=1024;
len-=1024;
dwBytesToWrite=1024;
};
::ZeroMemory(&bufer[0], 1024);
strcpy(bufer, s);
if(!::InternetWriteFile(hRequest, bufer, dwBytesToWrite, &dwBytesWritten))
{
srh->WriteMsgToLog("InternetWriteFile filed");
break;
}
else
{
WriteData=s;
srh->m_RequestState=WRITE_DATA;
if(srh->pRequestStateProc!=NULL)
srh->pRequestStateProc(srh->m_RequestState, srh->m_OutHeader, srh->m_OutData, WriteData);
};
}while(len!=0);
};
};
WriteData="";
if(!::HttpEndRequest(hRequest, NULL, 0, 0))
{
srh->WriteMsgToLog("HttpEndRequest filed");
}
else
{
srh->m_RequestState=END_REQUEST;
if(srh->pRequestStateProc!=NULL)
srh->pRequestStateProc(srh->m_RequestState, srh->m_OutHeader, srh->m_OutData, WriteData);
};
dwStatusSize=0;
::HttpQueryInfo(hRequest, HTTP_QUERY_RAW_HEADERS_CRLF, NULL, &dwStatusSize, NULL);
buf1=new char[dwStatusSize];
ZeroMemory(buf1, dwStatusSize);
::HttpQueryInfo(hRequest, HTTP_QUERY_RAW_HEADERS_CRLF, buf1, &dwStatusSize, NULL);
srh->m_OutHeader=buf1;
delete [] buf1;
buf1=NULL;
srh->m_RequestState=READ_HEADER;
if(srh->pRequestStateProc!=NULL)
srh->pRequestStateProc(srh->m_RequestState, srh->m_OutHeader, srh->m_OutData, WriteData);
srh->m_OutData="";
do
{
dwStatusSize=0;
if(!::InternetQueryDataAvailable(hRequest, &dwStatusSize, 0, 0))
{
srh->WriteMsgToLog("InternetQueryDataAvailable filed");
srh->m_RequestState=SESSION_CLOSE;
return 0;
};
if(dwStatusSize>0)
{
buf1=new char[dwStatusSize+1];
::ZeroMemory(buf1, dwStatusSize+1);
if(!::InternetReadFile(hRequest, buf1, dwStatusSize, &dwBytesWritten))
{
srh->WriteMsgToLog("InternetQueryDataAvailable filed");
delete [] buf1;
buf1=NULL;
srh->m_RequestState=SESSION_CLOSE;
return 0;
}
else
{
srh->m_RequestState=READ_DATA;
if(srh->pRequestStateProc!=NULL)
srh->pRequestStateProc(srh->m_RequestState, srh->m_OutHeader, CString(buf1), WriteData);
};
srh->m_OutData+=buf1;
delete [] buf1;
buf1=NULL;
};
}while (dwStatusSize>0);
if(hRequest!=NULL)
::InternetCloseHandle(hRequest);
if(hConnect!=NULL)
::InternetCloseHandle(hConnect);
if(hSession!=NULL)
::InternetCloseHandle(hSession);
srh->m_RequestState=SESSION_CLOSE;
if(srh->pRequestStateProc!=NULL)
{
srh->m_OutHeader="";
srh->m_OutData="";
WriteData="";
srh->pRequestStateProc(srh->m_RequestState, srh->m_OutHeader, srh->m_OutData, WriteData);
};
return 0;
};