HOWTO: Using HttpSendRequestEx with Password Protected URLs

ID: Q194700

The information in this article applies to:

SUMMARY

You can use HttpSendRequestEx to send requests to a password protected URL. This articles outlines the different techniques you can use.

MORE INFORMATION

Following is the usual sequence of APIs used with HttpSendRequest:

   InternetConnect ()
   HttpOpenRequest ()
   HttpSendRequestEx ()
   Do
   {
      InternetWriteFile ()
   }
   while (end condition)
   HttpEndRequest ()

Method 1

If the user name and password are known before sending the request (that is, they don't have to be dynamically entered by the user), then user name and password may be supplied directly to the InternetConnect API. However unlike HttpSendRequest, HttpSendRequestEx will not resubmit a request on its own after receiving the "401 Access Denied" status code from the server. Therefore HttpEndRequest will fail with an ERROR_INTERNET_FORCE_RETRY error. Receiving this error from HttpEndRequest indicates that application must go back to HttpSendRequestEx and send all the buffers with InternetWriteFile over again.

Method 2

If it is not possible to supply credentials in InternetConnect API, then the you must use the following steps:

1. Similarly to HttpSendRequest, status code of the request may be

   determined by calling HttpQueryInfo (hRequest, HTTP_QUERY_STATUS_CODE |
   HTTP_QUERY_FLAG). With HttpSendRequestEx, HttpQueryInfo must be called
   after HttpEndRequest, not after HttpSendRequestEx.

2. Valid credentials could be entered either with InternetErrorDlg() or by
   calling InternetSetOption with INTERNET_OPTION_USERNAME and
   INTERNET_OPTION_PASSWORD options.

3. Similarly to method 2, the application should go back HttpSendRequestEx.

Both methods above have a serious drawback. Because HttpSendRequestEx is used to send large amounts of data, resubmitting the entire data upon receiving the ERROR_INTERNET_FORCE_RETRY error or the 401 status code may waste network bandwidth and time. Following is the preferred method of handling user authentication with HttpSendRequestEx.

Method 3

This method involves sending an auxiliary request for the URL via HttpSendRequest. To preserve bandwidth and time, neither request nor reply should have large amounts of data. The Http HEAD method is preferred for such a situation. This method returns only headers and does not retrieve the body of the URL. The HEAD method is described in the HTTP/1.1 RFC 2068. The following steps show how to use an auxiliary request:

   hOpen = InternetOpen (...)
   hConnect = InternetConnect (hOpen, ...])
   hRequest = HttpOpenRequest (hConnect, "HEAD", "/myurl.htm", ...)
   HttpSendRequest (hRequest, ...)

   // at this point normal authentication logic can be used. If
   // credentials are supplied in InternetConnect, then Wininet will
   // resubmit credentials itself.  See HttpDump Internet Client SDK sample
   // for more information. Because HEAD does not generate any data
   // there is no need to read server's reply with InternetReadFile.

   InternetCloseHandle (hRequest)

   // Now open real request that will be send with HttpSendRequestEx. By
   // this time all authentication is done

   hRequest = HttpOpenRequest (...)
   HttpSendRequestEx (hRequest, ...)

Performing all the authentication in HEAD request, causes WinInet to create appropriate Authorization header that is sent with a large request submitted by HttpSendRequestEx.

REFERENCES

For additional information, please see the following articles in the Microsoft Knowledge Base:

   ARTICLE-ID: Q184352
   TITLE     : How to upload files to the Internet Information Server

   ARTICLE-ID: Q177188
   TITLE     : Using HttpSendRequestEx for Large POST Requests

(c) Microsoft Corporation 1998, All Rights Reserved. Contributions by Leon Braginski, Microsoft Corporation

Additional query words:

Keywords          : kbnokeyword
Version           : WINDOWS:4.0,4.01
Platform          : WINDOWS
Issue type        : kbhowto

Last Reviewed: October 26, 1998