httpS abfrage an einen webserver



  • Hallo,
    ich versuche ein einfaches Programm zu schreiben, welches eine Abfrage per httpS (ssl) an einen Webserver schickt und die Antwort in eine Variable spiechert.

    Nun ich habe es per LibCurl versucht, aber leider sagt mir Windows das Programm Funktioniert nicht mehr wenn die Funktion "curl_easy_cleanup(curl);" aufgerufen wird.

    hier der Test code, welche in in Code::Blocks geschrieben habe. Ich habe die lib sowie das programm mit dem Selben Kompiler kompeliert: MinGw

    Konfiguriet habe ich die Lib, in der MinGw Shell, vorm Kompelieren wie folgt:

    $ configure --disable-shared  --enable-static --with-winssl
    

    und anschliessend mit make kompeliert.

    das Programm:

    #include <stdio.h>
    #include <curl/curl.h>
    
    int main(void)
    {
        char url[255]       = "https://google.de";
    
        CURL *curl;
        CURLcode res;
        curl_global_init(CURL_GLOBAL_ALL);
    
        curl = curl_easy_init();
        if(curl)
        {
            curl_easy_setopt(curl, CURLOPT_URL, url);
    
            res = curl_easy_perform(curl);
            if(res != CURLE_OK)
            {
                fprintf(stderr, "curl_easy_perform() failed: %s\n",
                curl_easy_strerror(res));
            }
            else
            {
                //mach was
            }
    
            curl_easy_cleanup(curl); //<--- wenn das gemacht wird stürzt es ab
        }
        curl_global_cleanup();
        return 0;
    }
    

    Kompeliert ohne fehler und gibt sogar ein brauchbares Ergebnis aus, nur stürzt es ab und beendet sich daher nicht korrekt.

    Auch habe ich versucht mit MS Visual Studio Exrpess eine Lösung zu finden:

    #include <windows.h>
    #include <winhttp.h>
    #include <schannel.h>
    #include <stdio.h>
    #include <iostream>
    
    #pragma comment(lib, "winhttp.lib")
    
    void main(){
    
    	char y;
    
        DWORD dwSize = 0;
        DWORD dwDownloaded = 0;
        LPSTR pszOutBuffer;
        BOOL  bResults = FALSE;
        HINTERNET  hSession = NULL, 
                   hConnect = NULL,
                   hRequest = NULL;
    
        // Use WinHttpOpen to obtain a session handle.
        hSession = WinHttpOpen( L"WinHTTP Example/1.0",  
                                WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                                WINHTTP_NO_PROXY_NAME, 
                                WINHTTP_NO_PROXY_BYPASS, 0);
    
        // Specify an HTTP server.
        if (hSession)
            hConnect = WinHttpConnect( hSession, L"https://google.de",
                                       INTERNET_DEFAULT_HTTPS_PORT, 0);
    
        // Create an HTTP request handle.
        if (hConnect)
            hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL,
                                           NULL, WINHTTP_NO_REFERER, 
                                           WINHTTP_DEFAULT_ACCEPT_TYPES, 
                                           WINHTTP_FLAG_SECURE);
    
        // Send a request.
        if (hRequest)
            bResults = WinHttpSendRequest( hRequest,
                                           WINHTTP_NO_ADDITIONAL_HEADERS,
                                           0, WINHTTP_NO_REQUEST_DATA, 0, 
                                           0, 0);
    
    	if( !WinHttpReceiveResponse( hRequest, NULL ) )
    	{
    		if( GetLastError( ) == ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED )
    		{
    			//MY is the store the certificate is in.
    			hMyStore = CertOpenSystemStore( 0, TEXT("MY") );
    			if( hMyStore )
    			{
    			pCertContext = CertFindCertificateInStore( hMyStore,
    					X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
    					0,
    					CERT_FIND_SUBJECT_STR,
    					(LPVOID) szCertName, //Subject string in the certificate.
    					NULL );
    			if( pCertContext )
    			{
    				WinHttpSetOption( hRequest, 
    								WINHTTP_OPTION_CLIENT_CERT_CONTEXT,
    								(LPVOID) pCertContext, 
    								sizeof(CERT_CONTEXT) );
    				CertFreeCertificateContext( pCertContext );
    			}
    			CertCloseStore( hMyStore, 0 );
    
    			// NOTE: Application should now resend the request.
    			}
    		}
    	}
    
        // End the request.
        if (bResults)
            bResults = WinHttpReceiveResponse( hRequest, NULL);
    
        // Keep checking for data until there is nothing left.
        if (bResults)
            do 
            {
                // Check for available data.
                dwSize = 0;
                if (!WinHttpQueryDataAvailable( hRequest, &dwSize))
                    printf("Error %u in WinHttpQueryDataAvailable.\n", GetLastError());
    
                // Allocate space for the buffer.
                pszOutBuffer = new char[dwSize+1];
                if (!pszOutBuffer)
                {
                    printf("Out of memory\n");
                    dwSize=0;
                }
                else
                {
                    // Read the Data.
                    ZeroMemory(pszOutBuffer, dwSize+1);
    
                    if (!WinHttpReadData( hRequest, (LPVOID)pszOutBuffer, 
                                          dwSize, &dwDownloaded))
                        printf( "Error %u in WinHttpReadData.\n", GetLastError());
                    else
                        printf( "%s\n", pszOutBuffer);
    
                    // Free the memory allocated to the buffer.
                    delete [] pszOutBuffer;
                }
    
            } while (dwSize > 0);
    
        // Report any errors.
        if (!bResults)
            printf("Error %d has occurred.\n", GetLastError());
    
        // Close any open handles.
        if (hRequest) WinHttpCloseHandle(hRequest);
        if (hConnect) WinHttpCloseHandle(hConnect);
        if (hSession) WinHttpCloseHandle(hSession);
    
    	std::cin >> y;
    
    }
    

    dies lässt sich aber garnicht erst Kompeliern:

    1>------ Erstellen gestartet: Projekt: test2, Konfiguration: Debug Win32 ------
    1> test.cpp
    1>c:\users\seb\documents\visual studio 2010\projects\test2\test2\test.cpp(52): error C2065: 'hMyStore': nichtdeklarierter Bezeichner
    1>c:\users\seb\documents\visual studio 2010\projects\test2\test2\test.cpp(53): error C2065: 'hMyStore': nichtdeklarierter Bezeichner
    1>c:\users\seb\documents\visual studio 2010\projects\test2\test2\test.cpp(55): error C2065: 'pCertContext': nichtdeklarierter Bezeichner
    1>c:\users\seb\documents\visual studio 2010\projects\test2\test2\test.cpp(55): error C2065: 'hMyStore': nichtdeklarierter Bezeichner
    1>c:\users\seb\documents\visual studio 2010\projects\test2\test2\test.cpp(59): error C2065: 'szCertName': nichtdeklarierter Bezeichner
    1>c:\users\seb\documents\visual studio 2010\projects\test2\test2\test.cpp(61): error C2065: 'pCertContext': nichtdeklarierter Bezeichner
    1>c:\users\seb\documents\visual studio 2010\projects\test2\test2\test.cpp(65): error C2065: 'pCertContext': nichtdeklarierter Bezeichner
    1>c:\users\seb\documents\visual studio 2010\projects\test2\test2\test.cpp(67): error C2065: 'pCertContext': nichtdeklarierter Bezeichner
    1>c:\users\seb\documents\visual studio 2010\projects\test2\test2\test.cpp(69): error C2065: 'hMyStore': nichtdeklarierter Bezeichner
    ========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========

    Am beste fände ich es wenn ich eine möglichkeit hätte den fehler bei der libcurl zu beheben, da dort das code sich für meine Problemstellung viel einfacher gestaltet als der "Microsoft" code.

    Ich habe schon viel Zeit in Google investiert und wirklich nicht viel zum Thema gefunden, was ich gebrauchen könnte. Zum MS Code habe quasie garnichts gefunden.
    sobalt es um httpS geht finde ich nichts mehr.

    Weiss Jemand eine lösung für das Problem? Wäre mir sehr hilfreich.

    Gruß
    S.



  • dies lässt sich aber garnicht erst Kompeliern:

    Da fehlen die Deklarationen und Definitionen einiger Bezeichner die der Compiler bemängelt. Am besten so vorgehen:
    1. Fehlermeldung ansehen, z.B. hMyStore fehlt.
    2. Lokalisieren wo dieser das erste Mal benutzt wird, z.B. bei CertOpenSystemStore(..)
    3. Den fehlenden Code einfügen, z.B.

    // Anstatt:
    hMyStore = CertOpenSystemStore(..);
    // einfach so:
    HCERTSTORE hMyStore = CertOpenSystemStore(..);
    

    Was für Typen die Bezeichner brauchen, kannst du mit googeln der entsprechenden Funktionen herausfinden (wie die MSDN Seite die ich dir verlinkt habe).
    4. Neu kompilieren und prüfen ob der eine Fehler verschwindet.
    5. Nächstes Problem lösen..

    Zum Curl Problem kann ich nicht viel sagen. Aber du könntest noch ein weniger genauer erläutern, wie der Absturz aussieht (Segfault, Exception, ec.). Hast du schon gedebugt?

    Gruss Simon



  • Hallo
    Ich habe die Libcurl variante mal durch den Codeblocks Debugger geschickt und erhalte da nun folgendes:

    Building to ensure sources are up-to-date
    Selecting target:
    Debug
    Adding source dir: C:\Users\Seb\Documents\test\
    Adding source dir: C:\Users\Seb\Documents\test\
    Adding file: C:\Users\Seb\Documents\test\bin\Debug\test.exe
    Changing directory to: C:/Users/Seb/Documents/test/.
    Set variable: PATH=.;C:\MinGW\bin;C:\MinGW;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Windows\System32;C:\Windows;C:\Windows\System32\wbem;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Program Files (x86)\Smart Projects\IsoBuster
    Starting debugger: C:\Program Files (x86)\CodeBlocks\MINGW\bin\gdb.exe -nx -fullname -quiet -args C:/Users/Seb/Documents/test/bin/Debug/test.exe
    done
    Registered new type: wxString
    Registered new type: STL String
    Registered new type: STL Vector
    Setting breakpoints
    Debugger name and version: GNU gdb (GDB) 7.5
    Child process PID: 3676
    Program received signal SIGSEGV, Segmentation fault.
    In Curl_ssl_getsessionid () ()
    Debugger finished with status 0

    wenn ich noch ein

    curl_easy_setopt(curl, CURLOPT_SSL_SESSIONID_CACHE, 0);
    

    hinzufüge, läuft das Programm im debugger tadellos, aber wenn ich es dann manuell ausführe stürzt es wieder ab.

    ------

    Zum MS part:

    ich habe den Code angepasst.

    Irgendwie schon komisch das der eigentlich fast (SSL Teil) 1:1 von der MS seite ist und nicht Funktioniert.

    #include <windows.h>
    #include <winhttp.h>
    #include <schannel.h>
    #include <stdio.h>
    #include <iostream>
    
    #pragma comment(lib, "winhttp.lib")
    
    void main(){
    
    	char y;
    
        DWORD dwSize = 0;
        DWORD dwDownloaded = 0;
        LPSTR pszOutBuffer;
    	LPCSTR szCertName = (LPCSTR) "Cert_subject_1";
        BOOL  bResults = FALSE;
        HINTERNET  hSession = NULL, 
                   hConnect = NULL,
                   hRequest = NULL;
    
        // Use WinHttpOpen to obtain a session handle.
        hSession = WinHttpOpen( L"WinHTTP Example/1.0",  
                                WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                                WINHTTP_NO_PROXY_NAME, 
                                WINHTTP_NO_PROXY_BYPASS, 0);
    
        // Specify an HTTP server.
        if (hSession)
            hConnect = WinHttpConnect( hSession, L"https://google.de",
                                       INTERNET_DEFAULT_HTTPS_PORT, 0);
    
        // Create an HTTP request handle.
        if (hConnect)
            hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL,
                                           NULL, WINHTTP_NO_REFERER, 
                                           WINHTTP_DEFAULT_ACCEPT_TYPES, 
                                           WINHTTP_FLAG_SECURE);
    
        // Send a request.
        if (hRequest)
            bResults = WinHttpSendRequest( hRequest,
                                           WINHTTP_NO_ADDITIONAL_HEADERS,
                                           0, WINHTTP_NO_REQUEST_DATA, 0, 
                                           0, 0);
    
    	if( !WinHttpReceiveResponse( hRequest, NULL ) )
    	{
    		if( GetLastError( ) == ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED )
    		{
    			//MY is the store the certificate is in.
    			HCERTSTORE hMyStore = CertOpenSystemStore( 0, TEXT("MY") );
    			if( hMyStore )
    			{
    			PCCERT_CONTEXT pCertContext = CertFindCertificateInStore( hMyStore,
    					X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
    					0,
    					CERT_FIND_SUBJECT_STR,
    					(LPVOID) szCertName, //Subject string in the certificate.
    					NULL );
    			if( pCertContext )
    			{
    				WinHttpSetOption( hRequest, 
    								WINHTTP_OPTION_CLIENT_CERT_CONTEXT,
    								(LPVOID) pCertContext, 
    								sizeof(CERT_CONTEXT) );
    				CertFreeCertificateContext( pCertContext );
    			}
    			CertCloseStore( hMyStore, 0 );
    
    			// NOTE: Application should now resend the request.
    			}
    		}
    	}
    
        // End the request.
        if (bResults)
            bResults = WinHttpReceiveResponse( hRequest, NULL);
    
        // Keep checking for data until there is nothing left.
        if (bResults)
            do 
            {
                // Check for available data.
                dwSize = 0;
                if (!WinHttpQueryDataAvailable( hRequest, &dwSize))
                    printf("Error %u in WinHttpQueryDataAvailable.\n", GetLastError());
    
                // Allocate space for the buffer.
                pszOutBuffer = new char[dwSize+1];
                if (!pszOutBuffer)
                {
                    printf("Out of memory\n");
                    dwSize=0;
                }
                else
                {
                    // Read the Data.
                    ZeroMemory(pszOutBuffer, dwSize+1);
    
                    if (!WinHttpReadData( hRequest, (LPVOID)pszOutBuffer, 
                                          dwSize, &dwDownloaded))
                        printf( "Error %u in WinHttpReadData.\n", GetLastError());
                    else
                        printf( "%s\n", pszOutBuffer);
    
                    // Free the memory allocated to the buffer.
                    delete [] pszOutBuffer;
                }
    
            } while (dwSize > 0);
    
        // Report any errors.
        if (!bResults)
            printf("Error %d has occurred.\n", GetLastError());
    
        // Close any open handles.
        if (hRequest) WinHttpCloseHandle(hRequest);
        if (hConnect) WinHttpCloseHandle(hConnect);
        if (hSession) WinHttpCloseHandle(hSession);
    
    	std::cin >> y;
    
    }
    

    der Kompiler sagt mir dazu folgendes:

    1>------ Erstellen gestartet: Projekt: test2, Konfiguration: Debug Win32 ------
    1> test.cpp
    1>test.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__CertCloseStore@8" in Funktion "_main".
    1>test.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__CertFreeCertificateContext@4" in Funktion "_main".
    1>test.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__CertFindCertificateInStore@24" in Funktion "_main".
    1>test.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__CertOpenSystemStoreW@8" in Funktion "_main".
    1>C:\Users\Seb\documents\visual studio 2010\Projects\test2\Debug\test2.exe : fatal error LNK1120: 4 nicht aufgelöste externe Verweise.
    ========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========


Anmelden zum Antworten