Mega Code Archive

 
Categories / Delphi / Examples
 

Posting Data using WININET API

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;