HTTPAUTH.CPP
// =========================================================================== 
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 
// PARTICULAR PURPOSE. 
// 
// Copyright 1997 Microsoft Corporation.  All Rights Reserved. 
// =========================================================================== 
#include <windows.h> 
#include <stdio.h> 
#include <fcntl.h> 
#include <io.h> 
#include <wininet.h> 
 
//============================================================================== 
BOOL NeedAuth (HINTERNET hRequest) 
{ 
    // Get status code. 
    DWORD dwStatus; 
    DWORD cbStatus = sizeof(dwStatus); 
    HttpQueryInfo 
    ( 
        hRequest, 
        HTTP_QUERY_FLAG_NUMBER | HTTP_QUERY_STATUS_CODE, 
        &dwStatus, 
        &cbStatus, 
        NULL 
    ); 
    fprintf (stderr, "Status: %d\n", dwStatus); 
 
    // Look for 401 or 407. 
    DWORD dwFlags; 
    switch (dwStatus) 
    { 
        case HTTP_STATUS_DENIED: 
            dwFlags = HTTP_QUERY_WWW_AUTHENTICATE; 
            break; 
        case HTTP_STATUS_PROXY_AUTH_REQ: 
            dwFlags = HTTP_QUERY_PROXY_AUTHENTICATE; 
            break;             
        default: 
            return FALSE; 
    } 
 
    // Enumerate the authentication types. 
    BOOL fRet; 
    char szScheme[64]; 
    DWORD dwIndex = 0; 
    do 
    { 
        DWORD cbScheme = sizeof(szScheme); 
        fRet = HttpQueryInfo 
            (hRequest, dwFlags, szScheme, &cbScheme, &dwIndex); 
        if (fRet) 
            fprintf (stderr, "Found auth scheme: %s\n", szScheme); 
    } 
        while (fRet); 
 
    return TRUE; 
} 
 
 
//============================================================================== 
DWORD DoCustomUI (HINTERNET hConnect, HINTERNET hRequest) 
{ 
    // Prompt for username and password. 
    char  szUser[64], szPass[64]; 
    fprintf (stderr, "Enter Username: "); 
    if (!fscanf (stdin, "%s", szUser)) 
        return ERROR_INTERNET_LOGIN_FAILURE; 
    fprintf (stderr, "Enter Password: "); 
    if (!fscanf (stdin, "%s", szPass)) 
        return ERROR_INTERNET_LOGIN_FAILURE; 
 
    // Set the values in the handle. 
    InternetSetOption 
        (hConnect, INTERNET_OPTION_USERNAME, szUser, sizeof(szUser)); 
    InternetSetOption 
        (hConnect, INTERNET_OPTION_PASSWORD, szPass, sizeof(szPass)); 
 
    // Drain the socket. 
    BYTE bBuf[1000]; 
    DWORD cbBuf = sizeof(bBuf); 
    DWORD cbRead; 
    while (InternetReadFile (hRequest, bBuf, cbBuf, &cbRead) && cbRead); 
     
    return ERROR_INTERNET_FORCE_RETRY; 
} 
 
 
//============================================================================== 
int main (int argc, char **argv) 
{ 
    HINTERNET hInternet = NULL; 
    HINTERNET hConnect  = NULL; 
    HINTERNET hRequest  = NULL; 
    PSTR pszErr = NULL; 
    BOOL fRet; 
     
#define CHECK_ERROR(cond, err) if (!(cond)) {pszErr=(err); goto done;} 
 
    // Check usage. 
    if (argc < 2) 
    { 
        fprintf (stderr, "Usage:   httpauth [-c] <server> [<object> [<user> [<pass>]]]\n"); 
        fprintf (stderr, "  -c: Use custom UI to prompt for user/pass"); 
        exit (1); 
    } 
 
    // Parse arguments. 
    BOOL fAllowCustomUI = FALSE; 
    if (argc >= 2 && argv[1][0] == '-') 
    { 
        fAllowCustomUI = TRUE; 
        argv++; 
        argc--; 
    } 
    PSTR pszHost   = argv[1]; 
    PSTR pszObject = argc >= 3 ? argv[2] : "/"; 
    PSTR pszUser   = argc >= 4 ? argv[3] : NULL; 
    PSTR pszPass   = argc >= 5 ? argv[4] : NULL; 
 
    // Initialize wininet. 
    hInternet = InternetOpen 
    ( 
        "HttpAuth Sample",            // app name 
        INTERNET_OPEN_TYPE_PRECONFIG, // access type 
        NULL,                         // proxy server 
        0,                            // proxy port 
        0                             // flags 
    ); 
    CHECK_ERROR (hInternet, "InternetOpen"); 
 
    // Connect to host. 
    hConnect = InternetConnect 
    ( 
        hInternet,                    // wininet handle, 
        pszHost,                      // host 
        0,                            // port 
        pszUser,                      // user 
        NULL,                         // pass 
        INTERNET_SERVICE_HTTP,        // service 
        0,                            // flags 
        0                             // context 
    ); 
    CHECK_ERROR (hConnect, "InternetConnect"); 
 
    if (pszPass) 
    { 
        // Work around InternetConnect disallowing empty passwords. 
        InternetSetOption (hConnect, INTERNET_OPTION_PASSWORD, 
            pszPass, lstrlen(pszPass)+1); 
    } 
     
    // Create request. 
    hRequest = HttpOpenRequest 
    ( 
        hConnect,                     // connect handle 
        "GET",                        // request method 
        pszObject,                    // object name 
        NULL,                         // version 
        NULL,                         // referer 
        NULL,                         // accept types 
        INTERNET_FLAG_KEEP_CONNECTION // flags: keep-alive 
             | INTERNET_FLAG_RELOAD,  // flags: bypass cache 
        0                             // context 
    ); 
    CHECK_ERROR (hRequest, "HttpOpenRequest"); 
 
resend: 
 
    // Send request. 
    fRet = HttpSendRequest 
    ( 
        hRequest,                     // request handle 
        "",                           // header string 
        0,                            // header length 
        NULL,                         // post data 
        0                             // post length 
    ); 
 
    // Handle any authentication dialogs. 
    if (NeedAuth(hRequest) && fAllowCustomUI) 
    { 
        if (DoCustomUI (hConnect, hRequest) == ERROR_INTERNET_FORCE_RETRY) 
            goto resend; 
    } 
    else 
    { 
        DWORD dwErr; 
        dwErr = InternetErrorDlg 
        ( 
            GetDesktopWindow(),                      
            hRequest,                                
            fRet ? ERROR_SUCCESS : GetLastError(),                          
            FLAGS_ERROR_UI_FILTER_FOR_ERRORS  |      
                FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS | 
                FLAGS_ERROR_UI_FLAGS_GENERATE_DATA,  
            NULL 
        ); 
 
        if (dwErr == ERROR_INTERNET_FORCE_RETRY) 
            goto resend; 
    } 
 
    // Dump some bytes. 
    BYTE bBuf[1024]; 
    DWORD cbBuf; 
    DWORD cbRead; 
    cbBuf = sizeof(bBuf); 
    _setmode( _fileno( stdout ), _O_BINARY ); 
    while (InternetReadFile (hRequest, bBuf, cbBuf, &cbRead) && cbRead) 
        fwrite (bBuf, 1, cbRead, stdout); 
     
done: // Clean up. 
 
    if (pszErr) 
        fprintf (stderr, "Failed on %s, last error %d\n", pszErr, GetLastError()); 
    if (hRequest) 
        InternetCloseHandle (hRequest); 
    if (hConnect) 
        InternetCloseHandle (hConnect); 
    if (hInternet) 
        InternetCloseHandle (hInternet); 
    return 0; 
}