SAMPLE: Using HttpSendRequestEx for Large POST Requests

Summary

This sample demonstrates proper usage of the HttpSendRequestEx function introduced in the Internet Explorer 4.0 WinInet.dll and documented in the Internet Client SDK. 

The original HttpSendRequest function has a significant limitation: all the data for the request has to be provided in a single buffer when the function is called. This is often inconvenient, leads to poor performance in certain client applications, and may make it impossible to upload large amounts of data from client machines with limited memory. The new HttpSendRequestEx function allows a program to start a request, send out the data in small pieces as available, then end the request once all the data has been sent. Internet Explorer 4.0 must be installed on the computer in order for this function to work. The following file is available for download from the Microsoft Download Center:
For additional information about how to download Microsoft Support files, click the following article number to view the article in the Microsoft Knowledge Base:
119591 How to Obtain Microsoft Support Files from Online Services
Microsoft scanned this file for viruses. Microsoft used the most current virus-detection software that was available on the date that the file was posted. The file is stored on security-enhanced servers that help to prevent any unauthorized changes to the file.
More information
Hsrex.exe is a self-extracting archive that contains BigPost.cpp (the code for the demonstration program) and Readall.asp, an Active Server Pages (ASP) script that will read all data sent in a POST request. Readall.asp is provided as a sample target for BigPost, which can be used on Microsoft Internet Information Server (IIS) versions that support ASP. For other Web servers, you will need to provide a corresponding server script to read the data. 

To compile the program with Microsoft Visual C++ 5.0, follow these steps: 

  1. Run Visual C++ and create a new Win32 Console Application called "BigPost."
  2. In the directory where the project was created, run Hsrex.exe.
  3. Add BigPost.cpp to the BigPost project.
  4. Go to the Project Settings dialog box, click the Link tab, and add WinInet.lib to the "Object/library modules:" field.
  5. Ensure that Visual C++ is configured so that the compiler and linker will use the Wininet.h and Wininet.lib from the Internet Client SDK. If this is not done, a compiler or linker error will result. The include and library files included in Visual C++ do not contain the prototype and export of HttpSendRequestEx.
  6. Build the project. It will create BigPost.exe.
The program is run as follows:
BigPost <Size> <Server> <Path>
For example, the following would POST 1 megabyte (1024KB) to http://yourserver/scripts/ReadAll.asp:
BigPost 1024 yourserver /scripts/ReadAll.asp
The output from this would be as follows:
   Test of POSTing 1024KB with WinInet
   1048576 bytes sent.
   The following was returned by the server:
   1048576 bytes were read.

   Finished.
				

Notes

  • When using HttpSendRequestEx, the flag INTERNET_FLAG_NO_CACHE_WRITE should be used in the call to HttpOpenRequest, as shown in the following line from BigPost.cpp:
    
    HINTERNET hRequest = HttpOpenRequest(hConnect, "POST", argv[3], NULL,
             NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
    					
  • The functionality demonstrated in this sample represents the full implementation of HttpSendRequestEx at this time. The other flags and parameters present in the documentation for this function are not yet implemented.
  • Even though the data can be sent in multiple buffers of whatever sizes are convenient to the programmer, the total number of bytes that will be sent in the request must be known before the request is begun, and the total number of bytes that are actually sent must match this number exactly, or an error will be returned by HttpEndRequest.
References
For additional information, please see the following article in the Microsoft Knowledge Base:
177190 BUG: Error 12019 When Calling InternetWriteFile
Properties

Article ID: 177188 - Last Review: 06/22/2014 18:38:00 - Revision: 5.0

  • kbdownload kbfile kbinfo kbsample KB177188
// NetPost.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Windows.h>
#include <WinINet.h>
#include <stdio.h>

#pragma comment(lib, "wininet.lib")

BOOL UseHttpSendReqEx(HINTERNET hRequest, DWORD dwPostSize);
#define BUFFSIZE 500

void main( int argc, char **argv )
{
	DWORD dwPostSize;

	if (argc < 4)
	{
		printf("Usage: Bigpost <Size> <Server> <Path>\n");
		printf("<Size> is the number of KB to POST\n");
		printf("<Server> is the server to POST to\n");
		printf("<Path> is the virtual path to POST to\n");
		exit(0);
	}

	if ( ((dwPostSize = strtoul(argv[1],NULL,10)) == 0) || (dwPostSize >= 2047999) )
	{
		printf("%s is invalid size.  Valid sizes are from 1 to 2047999\n", argv[1]);
		exit(0);
	}

	printf( "Test of POSTing %luKB with WinInet\n", dwPostSize);

	dwPostSize *= 1024;  // Convert KB to bytes

	HINTERNET hSession = InternetOpen( "HttpSendRequestEx", INTERNET_OPEN_TYPE_PRECONFIG,
		NULL, NULL, 0);
	if(!hSession)
	{
		printf("Failed to open session\n");
		exit(0);
	}


	HINTERNET hConnect = InternetConnect(hSession, argv[2], INTERNET_DEFAULT_HTTP_PORT,
		NULL, NULL, INTERNET_SERVICE_HTTP,NULL, NULL);
	if (!hConnect)
		printf( "Failed to connect\n" );
	else
	{
		HINTERNET hRequest = HttpOpenRequest(hConnect, "POST", argv[3], 
			NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0);
		if (!hRequest)
			printf( "Failed to open request handle\n" );
		else
		{
			if(UseHttpSendReqEx(hRequest, dwPostSize))
			{	
				char pcBuffer[BUFFSIZE];
				DWORD dwBytesRead;

				printf("\nThe following was returned by the server:\n");
				do
				{	dwBytesRead=0;
				if(InternetReadFile(hRequest, pcBuffer, BUFFSIZE-1, &dwBytesRead))
				{
					pcBuffer[dwBytesRead]=0x00; // Null-terminate buffer
					printf("%s", pcBuffer);
				}
				else
					printf("\nInternetReadFile failed");
				}while(dwBytesRead>0);
				printf("\n");
			}
			if (!InternetCloseHandle(hRequest))
				printf( "Failed to close Request handle\n" );
		}
		if(!InternetCloseHandle(hConnect))
			printf("Failed to close Connect handle\n");
	}
	if( InternetCloseHandle( hSession ) == FALSE )
		printf( "Failed to close Session handle\n" );

	printf( "\nFinished.\n" );
}



BOOL UseHttpSendReqEx(HINTERNET hRequest, DWORD dwPostSize)
{
	INTERNET_BUFFERS BufferIn;
	DWORD dwBytesWritten;
	int n;
	BYTE pBuffer[1024];
	BOOL bRet;

	BufferIn.dwStructSize = sizeof( INTERNET_BUFFERS ); // Must be set or error will occur
	BufferIn.Next = NULL; 
	BufferIn.lpcszHeader = NULL;
	BufferIn.dwHeadersLength = 0;
	BufferIn.dwHeadersTotal = 0;
	BufferIn.lpvBuffer = NULL;                
	BufferIn.dwBufferLength = 0;
	BufferIn.dwBufferTotal = dwPostSize; // This is the only member used other than dwStructSize
	BufferIn.dwOffsetLow = 0;
	BufferIn.dwOffsetHigh = 0;

	if(!HttpSendRequestEx( hRequest, &BufferIn, NULL, 0, 0))
	{
		printf( "Error on HttpSendRequestEx %d\n",GetLastError() );
		return FALSE;
	}

	FillMemory(pBuffer, 1024, 'D'); // Fill buffer with data

	bRet=TRUE;
	for(n=1; n<=(int)dwPostSize/1024 && bRet; n++)
	{
		if(bRet=InternetWriteFile( hRequest, pBuffer, 1024, &dwBytesWritten))
			printf( "\r%d bytes sent.", n*1024);
	}

	if(!bRet)
	{
		printf( "\nError on InternetWriteFile %lu\n",GetLastError() );
		return FALSE;
	}

	if(!HttpEndRequest(hRequest, NULL, 0, 0))
	{
		printf( "Error on HttpEndRequest %lu \n", GetLastError());
		return FALSE;
	}

	return TRUE;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
此示例演示在 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、付费专栏及课程。

余额充值