How to use HttpSendRequestEx with password-protected URLs

http://support.microsoft.com/default.aspx?scid=kb;en-us;194700

This article was previously published under Q194700

This is the usual sequence of APIs used with HttpSendRequest:
   InternetConnect ()
   HttpOpenRequest ()
   HttpSendRequestEx ()
   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 can 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. This error message from HttpEndRequest indicates that the application must go back to HttpSendRequestEx and send all the buffers with InternetWriteFile again.

Method 2

If it is not possible to supply credentials in the InternetConnect API, then you must use the following steps:
  1. Similarly to HttpSendRequest, the 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 can be entered either with InternetErrorDlg() or by calling InternetSetOption with INTERNET_OPTION_USERNAME and INTERNET_OPTION_PASSWORD options.
  3. Similarly to method 1, the application should go back toHttpSendRequestEx.

Both of the 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. Method 3 is the preferred method of handling user authentication with HttpSendRequestEx:

Method 3

This method involves sending an auxiliary request for the URL via HttpSendRequest. Note that HttpSendRequestEx should be called on the same handle as HttpSendRequest. This will ensure that the request sent by HttpSendRequestEx will be sent over the connection authenticated by the first call to HttpSendRequest. Reusing the connection (using "Keep-Alive" connection) is necessary for NTLM (NT LAN manager authentication) support. To preserve bandwidth and time, neither request nor reply should have large amounts of data. The best way to accomplish this is to send the same type of request with HttpSendRequest as HttpSendRequestEx, but with the 0 content length.

The following steps show how to use an auxiliary request. It assumes that large amounts of data need to be POSTed to /Scripts/Poster.exe URL:
 hOpen = InternetOpen (...)
 hConnect = InternetConnect (hOpen, ...)

 // Note INTERNET_FLAG_KEEP_CONNECTION flag needed for NTLM

 hRequest = HttpOpenRequest (hConnect, "POST", 
                            "/scripts/poster.exe", 
                            lpszVersion, lpszReferer, lpszAcceptTypes, 
                            INTERNET_FLAG_KEEP_CONNECTION, dwContext)
 HttpSendRequest (hRequest, NULL, 0, NULL, 0);

 // 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. 

 // Read all returned data with InternetReadFile () 
 do
 {
     InternetReadFile (hRequest, ..., &dwSize);
 }
 while ( dwRead != 0);



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

 // Note that we are using the same handle as HttpSendRequest<BR/>
 Again:
 HttpSendRequestEx (hRequest, ...);
 do
 {
    InternetWriteFile()
                  }
 while () ; // stop condition
 if ( !HttpEndRequest ())
 {
    if ( ERROR_INTERNET_FORCE_RETRY == (dwError= GetLastError() ) )
    {
         Goto again;
    }
    // handle other errors here
 }
				
Performing all the authentication in HEAD request causes WinInet to create an appropriate authorization header that is sent with a large request submitted by HttpSendRequestEx.
 
====================================
结论:
解决方案一:
1.HttpOpenRequest 里面要 INTERNET_FLAG_KEEP_CONNECTION,http版本:HTTP/1.1
 
2.要把windows集成认证的用户名、密码,填入到InternetConnectr的第四、五个参数中去

3.
先用HttpSendRequest 试探性地访问资源,并用
InternetReadFile 读完返回结果
要把这次的hRequest 关掉,再打开一个hRequest(否则上传时Content-Lenth为0),或者在第四步自己把Content-Length设置好

4.使用HttpSendRequestEx -InternetWriteFile-HttpEndRequest 组合上传文件,如果最后返回ERROR_INTERNET_FORCE_RETRY则这步重新来过。
解决方案二(测试通过):
1.HttpOpenRequest 里面要 INTERNET_FLAG_KEEP_CONNECTION,http版本:HTTP/1.1
2.使用HttpSendRequestEx -InternetWriteFile-HttpEndRequest 组合上传文件,如果最后返回ERROR_INTERNET_FORCE_RETRY则这步重新来过。
 
此示例演示在 Internet Explorer 4.0 WinInet.dll 中引入并记录在 Internet 客户端 SDK 中的 HttpSendRequestEx 函数的正确用法。 原始的 HttpSendRequest 函数有这样一个重大限制: 所有请求的数据都有一个缓冲区时调用该函数时将提供。这是通常不方便、 导致在某些客户端应用程序中,性能较差,可能会无法上载大量数据从客户端计算机使用有限的内存。新的 HttpSendRequestEx 函数允许启动请求,发送出数据分小段为可用,然后结束后已发送的所有数据的请求的程序。为了使此函数以处理计算机上必须安装 Internet Explorer 4.0。下列文件已可从 Microsoft 下载中心下载: Hsrex.exe 有关如何下载 Microsoft 支持文件的其他信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章: 119591 如何从在线服务获得 Microsoft 支持文件微软已对此文件进行病毒扫描。Microsoft 使用该文件投递日期时可用的最新的病毒检测软件。该文件存储在安全增强型服务器上,以防止对文件进行任何未经授权的更改。 Hsrex.exe 是自解压的存档文件,其中包含 BigPost.cpp (演示程序代码) 和 Readall.asp,一个 Active Server Pages (ASP) 脚本将读取所有发送 POST 请求中的数据。Readall.asp 是 BigPost,可以使用 Microsoft 互联网信息服务器 (IIS) 版本的支持 ASP 作为示例目标提供。对于其他 Web 服务器,您需要提供相应的服务器脚本来读取数据。 若要编译此程序包含在 Microsoft Visual C++ 5.0,请执行以下步骤: 1.运行 Visual C++ 和创建一个新的 Win32 控制台应用程序调用"BigPost"。 2.在目录中创建项目的位置,运行 Hsrex.exe。 3.将 BigPost.cpp 添加到 BigPost 项目。 4.转到项目设置对话框中,单击链接选项卡,然后添加到 WinInet.lib"对象/库模块:"字段。 5.请确保配置 Visual C++,以便编译器和链接器将使用 Wininet.h 和 Wininet.lib 从 Internet 客户端 SDK。如果未能做到这一点,将导致编译器或链接器错误。原型和 HttpSendRequestEx 的导出不包含 Visual C++ 中包含的包括和库文件。 6.生成项目。它将创建 BigPost.exe。 在程序运行,如下所示: BigPost < 大小 >< 服务器 >< 路径 > 例如,以下将开机自检 1 兆字节 (1024 KB) 到 http://yourserver/scripts/ReadAll.asp: 您的服务器 /scripts/ReadAll.asp BigPost 1024
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值