WinInet API ассинхронно
1. Соединяется с указанным хостом по HTTP
2. И отправляет ему заголовки и POST данные
Эта часть работает.
Но вот заголовки ответа и сами данные от хоста я никак не получу.
насколько я понял, это выполняется следующей ф-ей - InternetReadFileEx.
Эта ф-ция и должна заполнить структуру INTERNET_BUFFERS, в которой я указываю буфер для заголовков ответов и буфер для самих возвращаемых данных.
Так вот, вызов InternetReadFileEx выполняется успечно, а самих данных нет!
Подскажите, плз, где я ошибаюсь.
Вот часть кода:
//m_pLogger - мой класс для дебага
HRESULT CConnector::Start()
{
if (!m_strURL.GetLength()) {
m_pLogger->Put(TEXT("Error: Invalid URL"));
return E_FAIL;
}
{
if (InternetAttemptConnect(0) != ERROR_SUCCESS) return E_FAIL;
try {
// Step 1
m_hSession = InternetOpen(
TEXT("KSergApplication"),
(m_useProxy ? INTERNET_OPEN_TYPE_PROXY : INTERNET_OPEN_TYPE_PRECONFIG),
(LPCTSTR)m_strProxyName,
(LPCTSTR)m_strProxyBypass,
INTERNET_FLAG_ASYNC);
if (!m_hSession) {
m_pLogger->GetLastError(TEXT("InternetOpen: "));
throw 0;
}
// Step 2
INTERNET_STATUS_CALLBACK iscCallback = InternetSetStatusCallback(m_hSession, InternetStatusCallback);
if (iscCallback == INTERNET_INVALID_STATUS_CALLBACK) {
m_pLogger->GetLastError(TEXT("InternetSetStatusCallback: "));
throw 0;
}
// Step 3
m_hConnect = InternetConnect(
m_hSession,
(LPCTSTR)m_strServerName,
m_wPort,
(LPCTSTR)m_strLogin,
(LPCTSTR)m_strPass,
INTERNET_SERVICE_HTTP,
0,
(DWORD_PTR)this);
if (!m_hConnect)
{
m_pLogger->GetLastError(TEXT("InternetConnect: "));
throw 0;
}
// Step 4
LPTSTR szAcceptTypes[] = {
TEXT("text/html"),
TEXT("text/xml"),
TEXT("image/gif"),
TEXT("image/x-xbitmap"),
TEXT("image/jpeg"),
TEXT("image/pjpeg"),
TEXT("application/x-shockwave-flash"),
TEXT("application/vnd.ms-excel"),
TEXT("application/msword"),
TEXT("application/vnd.ms-powerpoint"),
TEXT("*/*"),
NULL};
m_hRequest = HttpOpenRequest(
m_hConnect,
(m_sizePOST ? TEXT("POST"): NULL),
(LPCTSTR)m_strURI,
HTTP_VERSION,
NULL,
(LPCTSTR*)szAcceptTypes,
INTERNET_FLAG_NEED_FILE | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_NO_UI, //INTERNET_FLAG_SECURE | INTERNET_FLAG_IGNORE_CERT_CN_INVALID | INTERNET_FLAG_IGNORE_CERT_DATE_INVALID
(DWORD_PTR)this);
if (!m_hRequest)
{
m_pLogger->GetLastError(TEXT("HttpOpenRequest: "));
throw 0;
}
// Step 5
INTERNET_BUFFERS lpBuffersIn = {
sizeof(INTERNET_BUFFERS),
NULL,
(LPCTSTR)m_strHeader,
m_sizeHeader,
m_sizeHeader,
(LPVOID)(LPCTSTR)m_strPOST,
m_sizePOST,
m_sizePOST,
0,0
};
m_bResult = HttpSendRequestEx(
m_hRequest,
&lpBuffersIn,
NULL,
HSR_DOWNLOAD,//HSR_INITIATE,//HSR_ASYNC,//HSR_USE_CONTEXT,//HSR_SYNC,//
(DWORD_PTR)this);
if (!m_bResult) {
DWORD errCode = GetLastError();
if (errCode != ERROR_IO_PENDING)
{
m_pLogger->GetLastError(TEXT("HttpSendRequestEx: "), errCode);
throw 0;
}
}
// Step 6
TCHAR szHeaderOut[1024];
TCHAR szBufferOut[1024];
INTERNET_BUFFERS lpBuffersOut = {
sizeof(INTERNET_BUFFERS),
NULL,
szHeaderOut,
1024,
1024,
(LPVOID)szBufferOut,
1024,
1024,
0,0
};
m_bResult = InternetReadFileEx(
m_hRequest,
&lpBuffersOut,
0,//IRF_NO_WAIT,//
(DWORD_PTR)this);
if (!m_bResult) {
DWORD errCode = GetLastError();
if (errCode != ERROR_IO_PENDING)
{
m_pLogger->GetLastError(TEXT("InternetReadFileEx: "), errCode);
throw 0;
}
}
} catch(...) {
CloseSession();
}
return m_hRequest ? S_OK : E_FAIL;
}
}
void CConnector::InternetStatusCallback(
HINTERNET hInternet,
DWORD_PTR dwContext,
DWORD dwInternetStatus,
LPVOID lpvStatusInformation,
DWORD dwStatusInformationLength
) {
CConnector *This = (CConnector *)dwContext;
try {
switch (dwInternetStatus)
{
case INTERNET_STATUS_CLOSING_CONNECTION:
This->m_pLogger->Put(TEXT("CLOSING_CONNECTION (%d)"), dwStatusInformationLength);
break;
case INTERNET_STATUS_CONNECTED_TO_SERVER:
This->m_pLogger->Put(TEXT("CONNECTED_TO_SERVER (%d)"), dwStatusInformationLength);
break;
case INTERNET_STATUS_CONNECTING_TO_SERVER:
This->m_pLogger->Put(TEXT("CONNECTING_TO_SERVER (%d)"), dwStatusInformationLength);
break;
case INTERNET_STATUS_CONNECTION_CLOSED:
This->m_pLogger->Put(TEXT("CONNECTION_CLOSED (%d)"), dwStatusInformationLength);
break;
case INTERNET_STATUS_HANDLE_CLOSING:
This->m_pLogger->Put(TEXT("HANDLE_CLOSING (%d)"), dwStatusInformationLength);
break;
case INTERNET_STATUS_HANDLE_CREATED:
This->m_pLogger->Put(TEXT("HANDLE_CREATED (%d)"), dwStatusInformationLength);
break;
case INTERNET_STATUS_INTERMEDIATE_RESPONSE:
This->m_pLogger->Put(TEXT("INTERMEDIATE_RESPONSE (%d)"), dwStatusInformationLength);
break;
case INTERNET_STATUS_NAME_RESOLVED:
This->m_pLogger->Put(TEXT("NAME_RESOLVED (%d)"), dwStatusInformationLength);
break;
case INTERNET_STATUS_RECEIVING_RESPONSE:
This->m_pLogger->Put(TEXT("RECEIVING_RESPONSE (%d)"), dwStatusInformationLength);
break;
case INTERNET_STATUS_RESPONSE_RECEIVED:
This->m_pLogger->Put(TEXT("RESPONSE_RECEIVED (%d)"), dwStatusInformationLength);
break;
case INTERNET_STATUS_REDIRECT:
This->m_pLogger->Put(TEXT("REDIRECT (%d)"), dwStatusInformationLength);
break;
case INTERNET_STATUS_REQUEST_COMPLETE:
if (LPINTERNET_ASYNC_RESULT(lpvStatusInformation)->dwError == 0)
{
This->m_pLogger->Put(TEXT("REQUEST_COMPLETE (%d)"), dwStatusInformationLength);
} else {
This->m_pLogger->GetLastError(TEXT("REQUEST_COMPLETE:"));
}
This->CloseSession();
break;
case INTERNET_STATUS_REQUEST_SENT:
This->m_pLogger->Put(TEXT("REQUEST_SENT (%d)"), dwStatusInformationLength);
break;
case INTERNET_STATUS_RESOLVING_NAME:
This->m_pLogger->Put(TEXT("RESOLVING_NAME (%d)"), dwStatusInformationLength);
break;
case INTERNET_STATUS_SENDING_REQUEST:
This->m_pLogger->Put(TEXT("SENDING_REQUEST (%d)"), dwStatusInformationLength);
break;
case INTERNET_STATUS_STATE_CHANGE:
This->m_pLogger->Put(TEXT("STATE_CHANGE (%d)"), dwStatusInformationLength);
break;
default:
This->m_pLogger->Put(TEXT("Unknown: Status %d Given"), dwInternetStatus);
break;
}
} catch(...) {
This->CloseSession();
}
}
CConnector::CConnector(
const CString& strURL,
const CString& strHeader,
const CString& strPOST,
const CString& strProxyName,
const CString& strProxyBypass,
const CString& strLogin,
const CString& strPass
):
m_strURL (strURL ),
m_strHeader (strHeader ),
m_strPOST (strPOST ),
m_strProxyName (strProxyName ),
m_strProxyBypass(strProxyBypass),
m_strLogin (strLogin ),
m_strPass (strPass ),
m_hSession(NULL),
m_hConnect(NULL),
m_hRequest(NULL)
{
m_pLogger = new CLogger(TEXT("______CConnector.log.txt"));
m_sizePOST = m_strPOST .GetLength();
m_sizeHeader = m_strHeader .GetLength();
m_useProxy = m_strProxyName.GetLength();
if (!m_useProxy) {
m_strProxyBypass.Empty();
}
Start();
}
CConnector::~CConnector()
{
CloseSession();
delete m_pLogger;
}
void CConnector::CloseSession() {
if (m_hRequest) {
InternetCloseHandle(m_hRequest);
m_hRequest = NULL;
}
if (m_hConnect) {
InternetCloseHandle(m_hConnect);
m_hConnect = NULL;
}
if (m_hSession) {
if (InternetSetStatusCallback(m_hSession, NULL) == INTERNET_INVALID_STATUS_CALLBACK) {
m_pLogger->GetLastError(TEXT("InternetSetStatusCallback"));
}
InternetCloseHandle(m_hSession);
m_hSession = NULL;
}
}
CallBack функция вызывается в данном случае в след. порядке
HANDLE_CREATED (4)
HANDLE_CREATED (4)
RESOLVING_NAME (10)
NAME_RESOLVED (10)
CONNECTING_TO_SERVER (10)
CONNECTED_TO_SERVER (10)
SENDING_REQUEST (0)
REQUEST_SENT (4)
REQUEST_COMPLETE (8)
CLOSING_CONNECTION (0)
CONNECTION_CLOSED (0)
HANDLE_CLOSING (4)
HANDLE_CLOSING (4)