Я пытаюсь получить содержимое веб-страницы с помощью WinHTTP в C ++.
Это вроде работает, за исключением того, что я могу просматривать части источника, а не весь источник.
OpenSSL есть, потому что в конце концов я хочу иметь возможность использовать HTTP поверх SSL, но это следующая задача.
#include <windows.h>
#include <Wininet.h>
#pragma comment(lib, "Crypt32.lib")
#pragma comment(lib, "wininet.lib")bool SetupSSL(HINTERNET request)
{
HCERTSTORE store = CertOpenSystemStore(NULL,"CA");
DWORD ret = 0;
bool ok = false;
if(store==NULL)
return false;
PCCERT_CONTEXT context = CertFindCertificateInStore(store,X509_ASN_ENCODING,0,CERT_FIND_SUBJECT_STR,L"WebClient",NULL);
if(context!=NULL)
{
ok = InternetSetOption(request,INTERNET_OPTION_CLIENT_CERT_CONTEXT,(LPVOID)context,sizeof(CERT_CONTEXT))==TRUE;
if(!ok)
ret = GetLastError();
CertFreeCertificateContext(context);
}
MessageBoxA(0, "1", 0, 0);
CertCloseStore(store,0);
return ok;
};int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
HINTERNET hint = InternetOpen("WebTestClient",INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,0);
if(hint!=NULL)
{
//InternetSetStatusCallback(hint,&HTTPStatusCallbackFunc);
HINTERNET hsession = InternetConnect(hint,"encrypted.google.com",443,NULL,NULL,3,0,NULL);
if(hsession!=NULL)
{
HINTERNET hreqest = HttpOpenRequest(hsession,"GET","/","HTTP/1.1",NULL,NULL,INTERNET_FLAG_SECURE|INTERNET_FLAG_NO_AUTH,NULL);
if(hreqest!=NULL)
{
//if(SetupSSL(hreqest))
//{
if(HttpSendRequest(hreqest,NULL,0, NULL, 0))
{
//char szResponse[1024] = "";
char szBuffer[1024] = "";
DWORD dwRead=0;while(InternetReadFile(hreqest, szBuffer, sizeof(szBuffer)-1, &dwRead) && dwRead)
{
//strcat(szBuffer, szResponse);
szBuffer[dwRead] = 0;
OutputDebugStringA(szBuffer);
dwRead=0;
}
//InternetReadFile(hreqest, szBuffer, sizeof(szBuffer)-1, &dwRead);
MessageBoxA(0, szBuffer, 0, 0); // Only shows the first part of the source.
}
//}
//else
//{
//MessageBoxA(0, "SetupSSL failed", 0, 0);
//}
InternetCloseHandle(hreqest);
}
InternetCloseHandle(hsession);
}
InternetCloseHandle(hint);
}
return 0;
}
OutPutDebugStringA выводит весь исходный код на консоль отладки, поэтому все готово. Просто не храните все это в переменной szBuffer. Я думаю, что это может быть связано с петлей.
while(InternetReadFile(hreqest, szBuffer, sizeof(szBuffer)-1, ...
Вы продолжаете читать, используя InternetReadFile
в тот же буфер szBuffer
переписывать вещи, которые у вас уже есть.
Как правило, вам нужен гибкий / перераспределенный буфер здесь или список буферов, и просто для краткости кода здесь, вот что вы можете сделать для последовательного чтения в достаточно большой буфер фиксированного размера:
static const SIZE_T g_nBufferCapacity = 128 * 1024; // 128 KB
CHAR szBuffer[nBufferCapacity] = "";
SIZE_T nBufferSize = 0;
szBuffer[0] = 0;
for(; ; )
{
DWORD nReadableSize = min(1024, sizeof(szBuffer) - nBufferSize - 1);
DWORD nReadSize = 0;
InternetReadFile(hreqest, szBuffer + nBufferSize, nReadableSize, &nReadSize); // TODO: Error Checking
if(!nReadSize)
break;
szBuffer[nBufferSize + nReadSize] = 0;
OutputDebugStringA(szBuffer + nBufferSize);
nBufferSize += nReadSize;
}
Других решений пока нет …