Accessing the HTTP Protocol

Use the HTTP functions provided by Windows Internet Services (WinInet) to use the HTTP protocol to access resources on the Internet. The following illustration shows the relationships of the WinInet functions used to access the HTTP protocol. Shaded boxes represent functions that return HINTERNET handles, while the plain boxes represent functions that use the HINTERNET handle created by the function on which they depend.

HttpAddRequestHeaders, HttpQueryInfo, and HttpSendRequest are dependent on the HINTERNET handle created by HttpOpenRequest.

The following illustration shows the WinInet functions that use the HINTERNET handle created by HttpOpenRequest after it is sent by HttpSendRequest. The shaded boxes represent functions that return HINTERNET handles, while the plain boxes represent functions that use the HINTERNET handle created by the function on which they depend.

After HttpSendRequest has been used on the handle returned by HttpOpenRequest, InternetQueryDataAvailable and InternetReadFile can be used on that handle.

To use the HTTP WinInet functions

  1. Call the InternetOpen function to initialize an Internet handle.

    InternetOpen creates the root HINTERNET handle used to establish the HTTP session. The HINTERNET is used by all subsequent functions.

  2. Call InternetConnect using the HINTERNET returned by InternetOpen to create an HTTP session.

    When calling InternetConnect, specify INTERNET_DEFAULT_HTTP for the nServerPort parameter and INTERNET_SERVICE_HTTP for the dwService parameter.

    InternetConnect uses the handle returned by InternetOpen to create a specific HTTP session. InternetConnect initializes an HTTP session for the specified site, using the arguments passed to it and creates HINTERNET that is a branch off the root handle. InternetConnect does not attempt to access or establish a connection to the specified site.

  3. Call HttpOpenRequest to open an HTTP request handle.

    HttpOpenRequest uses the handle created by InternetConnect to establish a connection to the specified site.

  4. Call HttpSendRequest using the handle created by the HttpOpenRequest to send an HTTP request to the HTTP server.

  5. Call InternetReadFile to download data.

    - or -

    Call InternetQueryDataAvailable to query how much data is available to be read by a subsequent call to InternetReadFile.

  6. Call InternetCloseHandle to close the handle created by HttpOpenRequest.

  7. Call InternetCloseHandle to close the HTTP session created by InternetConnect.

  8. Call InternetCloseHandle to close the handle created by InternetOpen.

The following example shows how to use the HTTP functions to establish an HTTP session and retrieve a file. Two global Boolean variables — g_bproxy, which uses a proxy server, and g_bOpenURL, which uses a URL — are options set in the CeHttp application dialog box.

/***********************************************************************

FUNCTION: 
  GetInternetFile

PURPOSE: 
  This function demonstrates how to create and submit an HTTP request.
  It requests the default HTML document from the server, and then 
  displays it along with the HTTP transaction headers.
 
***********************************************************************/
BOOL GetInternetFile (LPTSTR lpszServer, LPTSTR lpszProxyServer)
{
  BOOL bReturn = FALSE;

  HINTERNET hOpen = NULL, 
            hConnect = NULL, 
            hRequest = NULL;

  DWORD dwSize = 0, 
        dwFlags = INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE; 

  TCHAR szErrMsg[200];
  
  char *lpBufferA,
       *lpHeadersA;

  TCHAR *lpBufferW,
        *lpHeadersW;

  LPTSTR AcceptTypes[2] = {TEXT("*/*"), NULL}; 

 
  // Initialize the use of the Windows CE Internet functions.
  if (g_bProxy)
  {
    hOpen = InternetOpen (TEXT("CeHttp"), INTERNET_OPEN_TYPE_PROXY, 
                          lpszProxyServer, 0, 0);
  }
  else
  {
    hOpen = InternetOpen (TEXT("CeHttp"), INTERNET_OPEN_TYPE_PRECONFIG,
                          NULL, 0, 0);
  }

  if (!hOpen)
  {
    wsprintf (szErrMsg, TEXT("%s: %x"), TEXT("InternetOpen Error"), 
              GetLastError());
    return FALSE;
  }
  
  if (g_bOpenURL)
  {
    if (!(hRequest = InternetOpenUrl (hOpen, lpszServer, NULL, 0, 
                                      INTERNET_FLAG_RELOAD, 0)))
    {
      wsprintf (szErrMsg, TEXT("%s: %x"), TEXT("InternetOpenUrl Error"),
                GetLastError());
      goto exit;
    }
  }
  else
  {
    // Open an HTTP session for a specified site by using lpszServer. 
    if (!(hConnect = InternetConnect (hOpen, 
                                      lpszServer, 
                                      INTERNET_INVALID_PORT_NUMBER, 
                                      NULL, NULL, 
                                      INTERNET_SERVICE_HTTP, 
                                      0, 0)))
    {
      wsprintf (szErrMsg, TEXT("%s: %x"), TEXT("InternetConnect Error"),
                GetLastError());
      goto exit;
    }

    // Open an HTTP request handle. 
    if (!(hRequest = HttpOpenRequest (hConnect, 
                                      TEXT("GET"), 
                                      NULL, 
                                      HTTP_VERSION, 
                                      NULL, 
                                      (LPCTSTR*)AcceptTypes, 
                                      dwFlags, 0)))
    {
      wsprintf (szErrMsg, TEXT("%s: %x"), TEXT("HttpOpenRequest Error"),
                GetLastError());
      goto exit;
    }

    // Send a request to the HTTP server. 
    if (!HttpSendRequest (hRequest, NULL, 0, NULL, 0))
    {
      wsprintf (szErrMsg, TEXT("%s: %x"), TEXT("HttpSendRequest Error"),
                GetLastError());
      goto exit;
    }
  }
  
  // Call HttpQueryInfoAto find out the size of the headers.
  HttpQueryInfoA(hRequest, HTTP_QUERY_RAW_HEADERS_CRLF, NULL, &dwSize,
                 NULL);

  // Allocate a block of memory for lpHeadersA.
  lpHeadersA = new CHAR [dwSize];
  //if memory allocation fails, then free the block of memory.
  if(!lpHeadersA)
  {
    delete[] lpHeadersA;
    goto exit;
  }
  // Call HttpQueryInfoA again to get the headers.
  if (!HttpQueryInfoA(hRequest, 
                      HTTP_QUERY_RAW_HEADERS_CRLF, 
                      (LPVOID) lpHeadersA, &dwSize, NULL))
  {
    wsprintf (szErrMsg, TEXT("%s: %x"), TEXT("HttpQueryInfo"), 
              GetLastError());
    goto exit;
  }
  else
  {
    // Clear all of the existing text in the edit control and prepare 
    // to put the new information in it.
    SendMessage (g_hwndEdit, EM_SETSEL, 0, -1);
    SendMessage (g_hwndEdit, WM_CLEAR, 0, 0);
    SendMessage (g_hwndEdit, WM_PAINT, TRUE, 0);
  }

  // Terminate headers with NULL.
  lpHeadersA [dwSize] = '\0';
  
  // Get the required size of the buffer that receives the Unicode 
  // string. 
  dwSize = MultiByteToWideChar (CP_ACP, 0, lpHeadersA, -1, NULL, 0);
  
  // Allocate a block of memory for lpHeadersW.
  lpHeadersW = new TCHAR [dwSize];
  //if memory allocation fails, then free the block of memory.
  if(!lpHeadersW)
  {
    delete[] lpHeadersW;
    goto exit;
  }

  // Convert headers from ASCII to Unicode.
  MultiByteToWideChar (CP_ACP, 0, lpHeadersA, -1, lpHeadersW, dwSize);  
  
  // Put the headers in the edit control.
  SendMessage (g_hwndMain, WM_PUTTEXT, NULL, (LPARAM) lpHeadersW);
   
  // Free the blocks of memory.
  delete[] lpHeadersA;
  delete[] lpHeadersW;

  // Allocate a block of memory for lpHeadersW.
  lpBufferA = new CHAR [32000];
  //if memory allocation fails, then free the block of memory.
  if(!lpBufferA)
  {
    delete[] lpBufferA;
    goto exit;
  }

  do
  {
    if (!InternetReadFile (hRequest, (LPVOID)lpBufferA, 31999, &dwSize))
    {
      wsprintf(szErrMsg, TEXT("%s: %x"), TEXT("InternetReadFile Error"), 
               GetLastError());
      goto exit;
    }

    if (dwSize != 0)    
    {
      // Terminate headers with NULL.
      lpBufferA [dwSize] = '\0';                 

      // Get the required size of the buffer which receives the Unicode
      // string. 
      dwSize = MultiByteToWideChar (CP_ACP, 0, lpBufferA, -1, NULL, 0);
      
      // Allocate a block of memory for lpBufferW.
      lpBufferW = new TCHAR [dwSize];
        //if memory allocation fails, then free the block of memory.
        if(!lpBufferW)
        {
          delete[] lpBufferW;
          goto exit;
        }

      // Convert the buffer from ASCII to Unicode.
      MultiByteToWideChar (CP_ACP, 0, lpBufferA, -1, lpBufferW, dwSize);  

      // Put the buffer in the edit control.
      SendMessage (g_hwndMain, WM_PUTTEXT, NULL, (LPARAM) lpBufferW);      

      // Free the block of memory.
      delete[] lpBufferW;  
    }    
  } while (dwSize);

  // Free the block of memory.
  delete[] lpBufferA;  

  bReturn = TRUE;

exit:

  // Close the Internet handles.
  if (hOpen)
  {
    if (!InternetCloseHandle (hOpen))
      wsprintf (szErrMsg, TEXT("%s: %x"), TEXT("CloseHandle Error"), 
                GetLastError());
  }
  
  if (hConnect)
  {
    if (!InternetCloseHandle (hConnect))
      wsprintf (szErrMsg, TEXT("%s: %x"), TEXT("CloseHandle Error"), 
                GetLastError());
  }

  if (hRequest)
  {
    if (!InternetCloseHandle (hRequest))
      wsprintf (szErrMsg, TEXT("%s: %x"), TEXT("CloseHandle Error"), 
                GetLastError());
  }

  return bReturn;

See Also

HTTP Sessions

Last updated on Wednesday, April 13, 2005

© 2005 Microsoft Corporation. All rights reserved.