您的位置:首页 > 理论基础 > 计算机网络

SAMPLE: Using HttpSendRequestEx for Large POST Requests

2016-10-13 15:26 531 查看
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:

Hsrex.exe
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:

Run Visual C++ and create a new Win32 Console Application called "BigPost."
In the directory where the project was created, run Hsrex.exe.
Add BigPost.cpp to the BigPost project.
Go to the Project Settings dialog box, click the Link tab, and add WinInet.lib to the "Object/library modules:" field.
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.
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
Keywords:

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: