2013-08-16 3 views
0

Я пытаюсь получить содержимое веб-страницы с помощью WinHTTP на C++. Это своего рода работа, за исключением того, что я могу просматривать части источника, а не весь источник.C++ WinHTTP InternetReadFile не извлекает весь источник

Материал 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. Я думаю, что это может быть связано с циклом.

+0

Является ли ваша жалоба на ваш собственный переопределяющий 'szBuffer' в цикле, так что вы видите полный контент на выходе отладки и только последнюю часть в окне сообщения? –

+0

Даже когда я прокомментирую szBuffer [dwRead] = 0; Я все еще могу видеть только часть источника с MessageBox – SnakeByte

ответ

0

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; 
}          
+0

Работал. Спасибо, Роман. – SnakeByte

+0

@ Roman - нужно ли dzBuffer удалить после использования? –

+0

@ TheofanisPantelides: в этом фрагменте кода буфер находится в стеке, поэтому удаление не требуется. –

Смежные вопросы