Retrieving Internet Options in WinHTTP

This topic discusses a sample C/C++ application that retrieves Microsoft Windows HTTP Services (WinHTTP) options programmatically.

The sample uses WinHTTP functions synchronously to obtain a session HINTERNET handle, begin an HTTP session, request a document, and gather information about the current WinHTTP option settings.

Prerequisites and Requirements

To build the sample code presented here, be sure that you have an up-to-date version of the Windows SDK installed, including headers and libraries, and make sure that your include and library paths are set correctly to pick up the current files. The WinHTTP header file is "Winhttp.h", and the library file is "Winhttp.lib". If you are using the older SDK header files that come with Visual Studio 6.0, the project will not build correctly (for example, more recent type definitions such as 'DWORD_PTR' will be missing).

You should have some familiarity with C/C++ in general, with WinHTTP C/C++ API Reference and with HINTERNET handles.

If you use a proxy server to access remote HTTP servers, you need to use the proxy configuration tool. See ProxyCfg.exe, a Proxy Configuration Tool for more information.

Part 1: Retrieving the Connect Time-Out

The first part of the example uses WinHttpQueryOption to retrieve the time-out value for Internet connection requests. This value might help you determine whether your application is spending too much time waiting to connect to a remote server.

Open the "RetOptions.cpp" Source File

Begin by opening the "RetOptions.dsw" project file in Visual Studio, then expand the Source Files node and open "RetOptions.cpp". If you do not intend to build the sample, of course, you can use any text editor to open "RetOptions.cpp" directly.

Include Headers and Libraries

The sample begins by including the necessary header files, namely "windows.h", "winhttp.h" and, to support "printf", "stdio.h". As you can see if you examine the project in Visual Studio, the sample explicitly links with the "winhttp.lib" library.

Initial Steps

This sample console application is contained in a single standard function, "main( )", and takes no parameters. It begins by declaring a handful of global variables, including three different types of HINTERNET handles — a session handle, a connection handle, and a request handle. It then prints a description of itself to the console screen:


  HINTERNET hSession;
  HINTERNET hConnect;
  HINTERNET hRequest;
  BOOL httpResult;
  DWORD data;
  DWORD dwSize = sizeof(DWORD);
  LPWSTR pwszURL;

  // Print a description of the sample.
  printf("This sample demonstrates the process for retrieving WinHTTP\n");
  printf("options programmatically from a C/C++ application. WinHTTP\n");
  printf("application programming interface (API) functions are used to\n");
  printf("determine the default connect time-out value and to find the\n");
  printf("current URL after an HTTP request is redirected.\n\n");


Obtain a Session Handle

Internet options can be retrieved for a session, a connection, or for a single request, depending on the type of HINTERNET handle that is used. For example, the HINTERNET request handle returned by WinHttpOpenRequest allows you to retrieve settings and options that affect a single document or resource.

This example retrieves options associated with an entire WinHTTP session. The first step, then, is to use WinHttpOpen to initialize WinHTTP and return an HINTERNET session handle for this session. The first parameter of WinHttpOpen, pwszUserAgent, requires a string that specifies the name of the user agent, in this case "A WinHTTP Example Program/1.0".

WinHttpOpen also requires a flag that specifies the desired access type. Use the access information specified in the registry with the WINHTTP_ACCESS_TYPE_DEFAULT_PROXY flag. The next two parameters, pwszProxyName and pwszProxyBypass, should be NULL when using the settings in the registry. The value of the last parameter, dwFlags, must be zero when using WinHTTP synchronously.

The following code opens the session:


  // Use WinHttpOpen to obtain a session handle.
  hSession = WinHttpOpen( L"A WinHTTP Example Program/1.0", 
                          WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                          WINHTTP_NO_PROXY_NAME, 
                          WINHTTP_NO_PROXY_BYPASS, 0 );


Query the Connect Time-Out Option

The next step is to use the WinHttpQueryOption function to retrieve the setting of the Internet connection request time-out for this session by passing in the HINTERNET session handle returned by WinHttpOpen, along with one of the valid WinHTTP Option Flags, a buffer to store the information returned, and the size of that buffer.

The following code queries for the connection request time-out, and if successful, displays it on the command line, in milliseconds:


  // Use WinHttpQueryOption to retrieve Internet options.
  httpResult = WinHttpQueryOption( hSession,
                                   WINHTTP_OPTION_CONNECT_TIMEOUT, 
                                   &data,
                                   &dwSize );
  if( httpResult )
      printf( "Connect time-out:\t%u ms\n", data );


Part 2: Retrieving a URL

Some options cannot be retrieved in a simple data type. If an option needs a string or structure to describe it, your application must provide a buffer into which WinHttpQueryOption places the string or structure.

The next part of the example illustrates how to do this. It queries for the URL associated with a particular request handle, which is useful if the request has been redirected by the server.

The following steps are involved:

Connect to a Server and Request a Resource

The sample calls WinHttpConnect to create a connection to a target HTTP server. The first parameter of this function is the HINTERNET session handle that was created by WinHttpOpen. The second parameter, pswzServerName, is a wide character string that specifies the name of the server. You must also specify the port to which to connect on the server. A predefined constant, INTERNET_DEFAULT_HTTP_PORT, enables you to connect to the default port.

Next, the sample requests a document using WinHttpOpenRequest and WinHttpSendRequest, and receives the response using WinHttpReceiveResponse.

This is the code that performs these steps:


  // Use WinHttpConnect to specify an HTTP server.
  hConnect = WinHttpConnect( hSession,
                             L"msdn.microsoft.com",
                             INTERNET_DEFAULT_HTTP_PORT,
                             0 );

  // Open and Send a Request Header.
  hRequest = WinHttpOpenRequest( hConnect,
                                 L"GET", 
                                 L"/downloads/samples/internet/winhttp/retoptions/redirect.asp", 
                                 NULL,
                                 WINHTTP_NO_REFERER,
                                 WINHTTP_DEFAULT_ACCEPT_TYPES,
                                 0 );
                                 
  httpResult = WinHttpSendRequest( hRequest,
                                   WINHTTP_NO_ADDITIONAL_HEADERS, 
                                   0,
                                   WINHTTP_NO_REQUEST_DATA,
                                   0,
                                   0,
                                   0 );

  httpResult = WinHttpReceiveResponse( hRequest, NULL );


Determine the Buffer Size and Make the Query

If you call WinHttpQueryOption with a NULL buffer address, the function returns an ERROR_INSUFFICIENT_BUFFER and places the number of bytes required to hold the requested data in the DWORD pointed to by its lpdwBufferLength parameter.

The required size of the buffer is returned in bytes, but the URL itself is a wide-character string, so the array that the sample allocates for a buffer has a size equal to the number of bytes divided by the size of a wide character.

Using the new buffer, the sample again calls WinHttpQueryOption and retrieves the URL, which it then displays at the command line.

The code that performs these steps is the following:


  // Use WinHttpQueryOption to obtain a buffer size.
  httpResult = WinHttpQueryOption( hRequest,
                                   WINHTTP_OPTION_URL, 
                                   NULL,
                                   &dwSize );

  pwszURL = new WCHAR[dwSize/sizeof(WCHAR)];

  // Use WinHttpQueryOption again, this time to retrieve 
  // the URL in the new buffer
  httpResult = WinHttpQueryOption( hRequest,
                                   WINHTTP_OPTION_URL, 
                                   (void *)pwszURL,
                                   &dwSize );

  // Display the retrieved URL in the console
  printf( "Redirected URL:\t\t%S\n", pwszURL );


Clean Up and Exit

Before exiting, it is important to free the memory allocated for the URL buffer and to close the three HINTERNET handles that you have opened, in reverse order of their creation. The following code cleans up and exits the sample application:


  // Free the allocated memory.
  delete [] pwszURL;

  // Release the hRequest handle.
  httpResult = WinHttpCloseHandle( hRequest );
  if( !httpResult )
      printf( "Could not close the hRequest handle.\n" );

  // Release the hConnect handle.
  httpResult = WinHttpCloseHandle( hConnect );
  if( !httpResult )
      printf( "Could not close the hConnect handle.\n" );

  // Release the hSession handle.
  httpResult = WinHttpCloseHandle( hSession );
  if( !httpResult )
      printf( "Could not close the hSession handle.\n" );

  // Exit the main() function
  return( 0 );


If you build the sample and run it from the command prompt, it displays the length of the connect time-out in milliseconds followed by the URL currently associated with your request.

 

 

Send comments about this topic to Microsoft

Build date: 11/1/2010

Show: