Examples Delphi

Title: Posting Data using WININET API
Question: How to post data using wininet API, supporting both HTTP and HTTPS connection with proxy and SSL certificate authentication
Answer:
Many time we are face with the situation in which we have to sent data to URL using standard WININET API.
The code snippet deals shows you such code which is capable of sending DATA using WININET API.
The code features includes
- SSL support, enabled by global boolean variable gbUseSSL.
- Error Handling, including proxy authentication dialog as well invalid SSL certificate error.
- Received data is returned as string.
- Support using preconfig internet settings.
the strURL function specify the website and strParams specify the HTTP data that need to be posted. For example
for a google search on music you need to pass
'www.google.com' as strURL and
search?hl=en&ie=UTF-8&q=music as strParams
However the strParams must be canonicalize (space to %020 and conversion of such characters) using InternetCanonicalizeUrl.
function GetURLInput(strURL, strParams: String): string;
var
hInet: HINTERNET;
hConn: HINTERNET;
hReq: HINTERNET;
dwLastError:DWORD;
buf :Array[0..4095] of char;
iBytesRead:Cardinal;
data: DWORD;
size,dummy:Cardinal;
nilptr:Pointer;
dwRetVal:DWORD;
bKeepOnLooping: boolean;
bFlag: boolean;
port:Integer;
iInternetFlags:DWORD;
dwFlags, dwBuffLen:DWORD;
begin
hInet := InternetOpen('TESTAPP',INTERNET_OPEN_TYPE_PRECONFIG,nil, nil,0);
if hInet = nil then exit;
if gbUseSSL then
port := INTERNET_DEFAULT_HTTPS_PORT
else
port :=INTERNET_DEFAULT_HTTP_PORT;
hConn := InternetConnect(hInet, PChar(strURL), port,
nil, nil, INTERNET_SERVICE_HTTP, 0, 0);
if hConn = nil then
begin
InternetCloseHandle(hInet);
exit;
end;
iInternetFlags := INTERNET_FLAG_KEEP_CONNECTION OR INTERNET_FLAG_NO_CACHE_WRITE OR INTERNET_FLAG_RELOAD;
if gbUseSSL then iInternetFlags := iInternetFlags OR INTERNET_FLAG_SECURE;
hReq := HttpOpenRequest(hConn, 'POST', PChar(strParams), 'HTTP/1.0', nil, nil,iInternetFlags, 0);
if hReq = nil then
Begin
InternetCloseHandle(hConn);
InternetCloseHandle(hInet);
exit;
end;
bKeepOnLooping := true;
while bKeepOnLooping do
begin
if HttpSendRequest(hReq, nil, 0, nil, 0) then
dwLastError := ERROR_SUCCESS
else
dwLastError:= GetLastError();
if (dwLastError = ERROR_INTERNET_INVALID_CA) then
begin
dwBuffLen := sizeof(dwFlags);
InternetQueryOption (hReq, INTERNET_OPTION_SECURITY_FLAGS,
@dwFlags, dwBuffLen);
dwFlags := dwFlags OR SECURITY_FLAG_IGNORE_UNKNOWN_CA;
InternetSetOption (hReq, INTERNET_OPTION_SECURITY_FLAGS,
@dwFlags, sizeof (dwFlags) );
continue;
end;
//Now check whether data is available
size := sizeof(data);dummy := 0;
HttpQueryInfo(hReq, HTTP_QUERY_STATUS_CODE or HTTP_QUERY_FLAG_NUMBER, @data, size, dummy);
if (data = HTTP_STATUS_DENIED) or (data = HTTP_STATUS_PROXY_AUTH_REQ) then
begin
dwRetVal:= InternetErrorDlg(application.handle, hReq, dwLastError,
FLAGS_ERROR_UI_FILTER_FOR_ERRORS or
FLAGS_ERROR_UI_FLAGS_GENERATE_DATA or
FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS,
nilptr );
if dwRetVal = ERROR_INTERNET_FORCE_RETRY then
continue
else //the only reason is user pressed CANCEL
begin
InternetCloseHandle(hReq);
InternetCloseHandle(hConn);
InternetCloseHandle(hInet);
exit;
end;
end
else
bKeepOnLooping := false; //Everything was fine now.
end; //End while looop
while(true) do
begin
bFlag:=InternetReadFile(hReq,@buf,BUFF_SIZE,iBytesRead);
if ((bFlag) and (not(iBytesRead=0))) then
begin
if iBytesRead buf[iBytesRead]:=#0;
Result:=Result + buf;
end
else
break;
end;
if hConn nil then InternetCloseHandle(hConn);
if hReq nil then InternetCloseHandle(hReq);
if hInet nil then InternetCloseHandle(hInet);
end;