Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WinHttp Delphi wrapper

Please advise if there is a WinHTTP wrapper in Delphi XE

In order of preference:

  1. a Delphi out of the box unit
  2. a third party open source pas file with ported entry routines
  3. a xxx_TLB.pas wrapper

Solution:

Since comments do not allow formatted code I am pasting the solution in the questions:

const
  winhttpdll = 'winhttp.dll';

  WINHTTP_ACCESS_TYPE_DEFAULT_PROXY = 0;
  WINHTTP_FLAG_REFRESH              = $00000100;
  WINHTTP_FLAG_SECURE               = $00800000;
  WINHTTP_ADDREQ_FLAG_COALESCE      = $40000000;
  WINHTTP_QUERY_FLAG_NUMBER         = $20000000;

function WinHttpOpen(pwszUserAgent: PWideChar; dwAccessType: DWORD;
  pwszProxyName, pwszProxyBypass: PWideChar; dwFlags: DWORD): HINTERNET; stdcall; external winhttpdll;
function WinHttpConnect(hSession: HINTERNET; pswzServerName: PWideChar;
  nServerPort: INTERNET_PORT; dwReserved: DWORD): HINTERNET; stdcall; external winhttpdll;
function WinHttpOpenRequest(hConnect: HINTERNET; pwszVerb: PWideChar;
  pwszObjectName: PWideChar; pwszVersion: PWideChar; pwszReferer: PWideChar;
  ppwszAcceptTypes: PLPWSTR; dwFlags: DWORD): HINTERNET; stdcall; external winhttpdll;
function WinHttpCloseHandle(hInternet: HINTERNET): BOOL; stdcall; external winhttpdll;
function WinHttpAddRequestHeaders(hRequest: HINTERNET; pwszHeaders: PWideChar; dwHeadersLength: DWORD;
  dwModifiers: DWORD): BOOL; stdcall; external winhttpdll;
function WinHttpSendRequest(hRequest: HINTERNET; pwszHeaders: PWideChar;
  dwHeadersLength: DWORD; lpOptional: Pointer; dwOptionalLength: DWORD; dwTotalLength: DWORD;
  dwContext: DWORD): BOOL; stdcall; external winhttpdll;
function WinHttpReceiveResponse(hRequest: HINTERNET;
  lpReserved: Pointer): BOOL; stdcall; external winhttpdll;
function WinHttpQueryHeaders(hRequest: HINTERNET; dwInfoLevel: DWORD; pwszName: PWideChar;
  lpBuffer: Pointer; var lpdwBufferLength, lpdwIndex: DWORD): BOOL; stdcall; external winhttpdll;
function WinHttpReadData(hRequest: HINTERNET; lpBuffer: Pointer;
  dwNumberOfBytesToRead: DWORD; var lpdwNumberOfBytesRead: DWORD): BOOL; stdcall; external winhttpdll;
function WinHttpQueryDataAvailable(hRequest: HINTERNET; var lpdwNumberOfBytesAvailable: DWORD): BOOL; 
  stdcall; external winhttpdll;
function WinHttpSetOption(hInternet: HINTERNET; dwOption: DWORD; lpBuffer: Pointer; dwBufferLength: DWORD): BOOL; 
  stdcall; external winhttpdll;
function WinHttpQueryOption(hInternet: HINTERNET; dwOption: DWORD; var lpBuffer: Pointer; var lpdwBufferLength: DWORD): BOOL; 
  stdcall; external winhttpdll;
function WinHttpWriteData(hRequest: HINTERNET; lpBuffer: Pointer; dwNumberOfBytesToWrite: DWORD; 
  var lpdwNumberOfBytesWritten: DWORD): BOOL; stdcall; external winhttpdll;
function WinHttpCheckPlatform(): BOOL; stdcall; external winhttpdll;

There are still a couple more missing ones:

WinHttpCrackUrl
WinHttpCreateUrl
WinHttpSetStatusCallback
WinHttpTimeFromSystemTime
WinHttpTimeToSystemTime
like image 281
Gad D Lord Avatar asked Jul 17 '11 16:07

Gad D Lord


2 Answers

If you want to implement an HTTP client access in your application, you may consider several choices:

  • Use the provided Indy components;
  • Use third-party components like Synapse, ICS or your own WinSock-based wrapper;
  • Use WinINet;
  • Use WinHTTP.

For our ORM, for its HTTP/1.1 connection layer, we tried to avoid external dependencies, and did not have the need of all Indy's features and overhead.

We first wrote our own WinSock wrapper, then tried out WinInet. When used on our testing benchmark, we found out that WinINet was dead slow.

Then we tried WinHTTP, the new API provided by Microsoft, and we found out this was blazing fast. As fast as direct WinSock access, without the need of writing all the wrapper code.

So here is our OpenSource WinHTTP wrapper, in the unit named SynCrtSock. Tested from Delphi 5 up to XE.

You'll see that we used the same generic class for both WinINet and WinHTTP. In fact, both libraries are very close.

See this article for details. There is a note about automatic proxy retrieval.

Edit: with the upcoming Delphi XE2, you'll be able to cross-compile to Mac OS X. In this case, it does perfectly make sense to use "abstract" classes, like SynCrtSock. Under Windows, it will use WinHTTP, but under Mac OS X, it will call the socket API. To make your code compile, you'll just to adjust the class type, not your code.

like image 168
Arnaud Bouchez Avatar answered Oct 08 '22 10:10

Arnaud Bouchez


  • Project
  • Import Type Library
  • Microsoft WinHTTP Services, version 5.1 (Version 5.1) C:\Windows\system32\winhttp.dll

And then use it:

var
   http: IWinHttpRequest;
   szUrl: WideString;
begin
   szUrl := 'http://stackoverflow.com/questions/6725348/winhttp-delphi-wrapper';

   http := CoWinHttpRequest.Create;
   http.open('GET', szUrl, False);
   http.send(EmptyParam);

   if (http.status = 200) then
       ShowMessage(http.responseText);

So:

  • it it is out of the box - using the out of the box tools
  • it is open-source - you're free to modify the source as you like
  • it's the TLB
like image 20
Ian Boyd Avatar answered Oct 08 '22 09:10

Ian Boyd