WinHTTP Website Login

1.2k views Asked by At

I am trying to retrieve the source code of a web page using WinHTTP. Reading from this page: http://msdn.microsoft.com/en-us/library/windows/desktop/aa384110(v=vs.85).aspx

I was able to come up with this code. The HTTP status code is 200 which means the request was completed correctly. I end up getting the source code for the login page instead of my intended web page behind it.

Should I send a httprequest to the login page and then to the file path?

Here is the code:

#include <windows.h>
#include <winhttp.h>
#include <string>
#include <stdio.h>
#include <iostream>
#include <fstream>
using namespace std;

#pragma comment(lib, "winhttp.lib")

DWORD ChooseAuthScheme(DWORD dwSupportedSchemes)
{
    //  It is the server's responsibility only to accept 
    //  authentication schemes that provide a sufficient
    //  level of security to protect the servers resources.
    //
    //  The client is also obligated only to use an authentication
    //  scheme that adequately protects its username and password.
    //
    //  Thus, this sample code does not use Basic authentication  
    //  becaus Basic authentication exposes the client's username
    //  and password to anyone monitoring the connection.

    if (dwSupportedSchemes & WINHTTP_AUTH_SCHEME_NEGOTIATE)
        return WINHTTP_AUTH_SCHEME_NEGOTIATE;
    else if (dwSupportedSchemes & WINHTTP_AUTH_SCHEME_NTLM)
        return WINHTTP_AUTH_SCHEME_NTLM;
    else if (dwSupportedSchemes & WINHTTP_AUTH_SCHEME_PASSPORT)
        return WINHTTP_AUTH_SCHEME_PASSPORT;
    else if (dwSupportedSchemes & WINHTTP_AUTH_SCHEME_DIGEST)
        return WINHTTP_AUTH_SCHEME_DIGEST;
    else
        return 0;
}

struct SWinHttpSampleGet
{
    LPCWSTR szServer;
    LPCWSTR szPath;
    BOOL fUseSSL;
    LPCWSTR szServerUsername;
    LPCWSTR szServerPassword;
    LPCWSTR szProxyUsername;
    LPCWSTR szProxyPassword;
};

void WinHttpAuthSample(IN SWinHttpSampleGet *pGetRequest)
{
    string contents;
    DWORD dwStatusCode = 0;
    DWORD dwSupportedSchemes;
    DWORD dwFirstScheme;
    DWORD dwSelectedScheme;
    DWORD dwTarget;
    DWORD dwLastStatus = 0;
    DWORD dwSize = sizeof(DWORD);
    BOOL  bResults = FALSE;
    BOOL  bDone = FALSE;

    DWORD dwProxyAuthScheme = 0;
    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);

    INTERNET_PORT nPort = (pGetRequest->fUseSSL) ?
    INTERNET_DEFAULT_HTTPS_PORT :
                                INTERNET_DEFAULT_HTTP_PORT;

    // Specify an HTTP server.
    if (hSession)
        hConnect = WinHttpConnect(hSession,
        pGetRequest->szServer,
        nPort, 0);

    // Create an HTTP request handle.
    if (hConnect)
        hRequest = WinHttpOpenRequest(hConnect,
        L"GET",
        pGetRequest->szPath,
        NULL,
        WINHTTP_NO_REFERER,
        WINHTTP_DEFAULT_ACCEPT_TYPES,
        (pGetRequest->fUseSSL) ?
    WINHTTP_FLAG_SECURE : 0);

    // Continue to send a request until status code 
    // is not 401 or 407.
    if (hRequest == NULL)
        bDone = TRUE;

    while (!bDone)
    {
        //  If a proxy authentication challenge was responded to, reset
        //  those credentials before each SendRequest, because the proxy  
        //  may require re-authentication after responding to a 401 or  
        //  to a redirect. If you don't, you can get into a 
        //  407-401-407-401- loop.
        if (dwProxyAuthScheme != 0)
            bResults = WinHttpSetCredentials(hRequest,
            WINHTTP_AUTH_TARGET_PROXY,
            dwProxyAuthScheme,
            pGetRequest->szProxyUsername,
            pGetRequest->szProxyPassword,
            NULL);
        // Send a request.
        bResults = WinHttpSendRequest(hRequest,
            WINHTTP_NO_ADDITIONAL_HEADERS,
            0,
            WINHTTP_NO_REQUEST_DATA,
            0,
            0,
            0);

        // End the request.
        if (bResults)
            bResults = WinHttpReceiveResponse(hRequest, NULL);

        // Resend the request in case of 
        // ERROR_WINHTTP_RESEND_REQUEST error.
        if (!bResults && GetLastError() == ERROR_WINHTTP_RESEND_REQUEST)
            continue;

        // Check the status code.
        if (bResults)
            bResults = WinHttpQueryHeaders(hRequest,
            WINHTTP_QUERY_STATUS_CODE |
            WINHTTP_QUERY_FLAG_NUMBER,
            NULL,
            &dwStatusCode,
            &dwSize,
            NULL);
        DWORD dwSize = 0;
        DWORD dwDownloaded = 0;
        LPSTR pszOutBuffer;




        if (bResults)
        {
            switch (dwStatusCode)
            {
            case 200:
                    // The resource was successfully retrieved.
                    // You can use WinHttpReadData to read the 
                    // contents of the server's response.
                    printf("The resource was successfully retrieved.\n");
                    do
                    {
                        // Check for available data.
                        dwSize = 0;
                        if (!WinHttpQueryDataAvailable(hRequest, &dwSize))
                        {
                            printf("Error %u in WinHttpQueryDataAvailable.\n",
                                GetLastError());
                            break;
                        }

                        // No more available data.
                        if (!dwSize)
                            break;

                        // Allocate space for the buffer.
                        pszOutBuffer = new char[dwSize + 1];
                        if (!pszOutBuffer)
                        {
                            printf("Out of memory\n");
                            break;
                        }

                        // Read the Data.
                        ZeroMemory(pszOutBuffer, dwSize + 1);

                        if (!WinHttpReadData(hRequest, (LPVOID)pszOutBuffer,
                            dwSize, &dwDownloaded))
                        {
                            printf("Error %u in WinHttpReadData.\n", GetLastError());
                        }
                        else
                        {
                            printf("%s", pszOutBuffer);
                            contents += pszOutBuffer;
                        }

                        // Free the memory allocated to the buffer.
                        delete[] pszOutBuffer;

                        // This condition should never be reached since WinHttpQueryDataAvailable
                        // reported that there are bits to read.
                        if (!dwDownloaded)
                            break;

                    } while (dwSize > 0);
                        bDone = true;
                    break;
            case 401:
                // The server requires authentication.
                printf(" The server requires authentication. Sending credentials...\n");

                // Obtain the supported and preferred schemes.
                bResults = WinHttpQueryAuthSchemes(hRequest,
                    &dwSupportedSchemes,
                    &dwFirstScheme,
                    &dwTarget);

                // Set the credentials before resending the request.
                if (bResults)
                {
                    dwSelectedScheme = ChooseAuthScheme(dwSupportedSchemes);

                    if (dwSelectedScheme == 0)
                        bDone = TRUE;
                    else
                        bResults = WinHttpSetCredentials(hRequest,
                        dwTarget,
                        dwSelectedScheme,
                        pGetRequest->szServerUsername,
                        pGetRequest->szServerPassword,
                        NULL);
                }

                // If the same credentials are requested twice, abort the
                // request.  For simplicity, this sample does not check
                // for a repeated sequence of status codes.
                if (dwLastStatus == 401)
                    bDone = TRUE;

                break;

            case 407:
                // The proxy requires authentication.
                printf("The proxy requires authentication.  Sending credentials...\n");

                // Obtain the supported and preferred schemes.
                bResults = WinHttpQueryAuthSchemes(hRequest,
                    &dwSupportedSchemes,
                    &dwFirstScheme,
                    &dwTarget);

                // Set the credentials before resending the request.
                if (bResults)
                    dwProxyAuthScheme = ChooseAuthScheme(dwSupportedSchemes);

                // If the same credentials are requested twice, abort the
                // request.  For simplicity, this sample does not check 
                // for a repeated sequence of status codes.
                if (dwLastStatus == 407)
                    bDone = TRUE;
                break;

            default:
                // The status code does not indicate success.
                printf("Error. Status code %d returned.\n", dwStatusCode);
                bDone = TRUE;
            }
        }

        // Keep track of the last status code.
        dwLastStatus = dwStatusCode;

        // If there are any errors, break out of the loop.
        if (!bResults)
            bDone = TRUE;
    }

    // Report any errors.
    if (!bResults)
    {
        DWORD dwLastError = GetLastError();
        printf("Error %d has occurred.\n", dwLastError);
    }


    ofstream fout("Output.txt");
    fout << contents;
    fout.close();

    // Close any open handles.
    if (hRequest) WinHttpCloseHandle(hRequest);
    if (hConnect) WinHttpCloseHandle(hConnect);
    if (hSession) WinHttpCloseHandle(hSession);
}

int main()
{
    wstring Server = L"moodle.redlands.edu";
    wstring Path = L"/course/view.php?id=2213/";
    wstring User = L"test";
    wstring Pass = L"password";
    wstring User_Proxy = L"test";
    wstring Pass_Proxy = L"password";

    SWinHttpSampleGet Lawl{
        Server.c_str(),
        Path.c_str(),
        1,
        User.c_str(),
        Pass.c_str(),
        User_Proxy.c_str(), Pass_Proxy.c_str()
    };

    WinHttpAuthSample(&Lawl);
    system("PAUSE");
    return 0;
}
0

There are 0 answers