// Yuri Zarechny for News2News (c) 2006
#pragma once
#include < windows.h >
#include < conio.h >
#include < stdio.h >
#include < tchar.h >
#include < wininet.h > // dependencies: wininet.lib
wchar_t ccHost [256];
wchar_t ccRemotePath [256];
wchar_t ccExtraInfo [256];
HINTERNET hConn,
hSes,
hReq;
void inetexit()
{
if (hReq) InternetCloseHandle(hReq);
if (hConn) InternetCloseHandle(hConn);
if (hSes) InternetCloseHandle(hSes);
printf("\nPress any key to exit\n");
getch();
}
int _tmain(int argc, _TCHAR* argv[])
{
LPWSTR ccUrl = L"http://www.news2news.com/vfp/?example=397";
LPSTR cBuf;
URL_COMPONENTS strUrl;
DWORD i;
ZeroMemory(&strUrl, sizeof(strUrl));
strUrl.dwStructSize = sizeof(strUrl);
strUrl.lpszHostName = (LPWSTR) &ccHost;
strUrl.lpszUrlPath = (LPWSTR) &ccRemotePath;
strUrl.lpszExtraInfo = (LPWSTR) &ccExtraInfo;
strUrl.dwSchemeLength = -1;
strUrl.dwHostNameLength = 255;
strUrl.dwUrlPathLength = 255;
strUrl.dwExtraInfoLength = 255;
if (!InternetCrackUrl(ccUrl, 0, 0, &strUrl)) {
printf("Could not crack Url\n");
inetexit();
return -1;
}
hSes = InternetOpen(L"news2news example agent",
INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0);
if (hSes == 0) {
printf("Could not activate WinHTTP library\n");
inetexit();
return -2;
}
for (i=0; i<10; i++) {
hConn = InternetConnect(hSes, ccHost,
INTERNET_DEFAULT_HTTP_PORT, 0, 0,
INTERNET_SERVICE_HTTP, 0 ,0);
if (hConn == 0) {
wprintf(L"Could not connect to host: %s. Attempt #:%d\n",
ccHost, i);
Sleep(1000);
} else break;
}
if (hConn == 0) {
inetexit();
return -3;
}
strUrl.lpszUrlPath = wcscat(strUrl.lpszUrlPath,
strUrl.lpszExtraInfo);
hReq = HttpOpenRequest(hConn, L"GET", strUrl.lpszUrlPath,
L"HTTP/1.1", 0, 0, 0, 0);
if (hReq == 0) {
printf("Could not open HTTP request\n");
inetexit();
return -4;
}
BOOL bFlag = HttpSendRequest(hReq, NULL, NULL, 0, 0);
if (!bFlag) {
printf("Call to WinHttpSendRequest failed. LastError: %d\n",
GetLastError());
inetexit();
return -5;
}
do {
i = 0;
if (InternetQueryDataAvailable(hReq, &i, 0, 0)) {
cBuf = new char[i+1];
if (!cBuf) {
printf("Out of memory\n");
inetexit();
return -7;
}
bFlag = InternetReadFile(hReq, (LPVOID) cBuf, i, &i);
if (!bFlag) {
printf("Call to WinHttpReadData failed. LastError: %d\n",
GetLastError());
inetexit();
return -8;
}
printf("%s", cBuf);
delete [] cBuf;
}
} while (i>0);
inetexit();
return 0;
}
|
Nov. 2, 2003: code completely rewritten.
List of HTTP Status Codes on MSDN.
Recommended reading:
Post FoxPro Data to Your Web Server with WinInet written by Rick Strahl and published in April 1998 issue of FoxPro Advisor.
* * *
Here is a simple example of using this class to exchange information between VFP application and ASP.Net page. Two pieces of code, VFP and .Net, are required. VFP part posts HTTP Request stuffed with some data. C# part extracts data from the request, processes it and sends back a response.
Create ASP.Net Web application and call it SendRequest. Add new web form and call it ExchangeData.aspx. Both names are optional, though the complete name of the page (URL) must be provided to the VFP part.
Remove all HTML code from the web form. It is not going to be used anyway; moreover it may affect sending HTTP response headers. Open the code part (C#) and add the following method to ExchangeData class.
private void ProcessRequest()
{
//read HTTP Request header
string sender = Request.Headers["Request_Sender"];
//convert body of HTTP Request to array of bytes...
System.IO.Stream s = Request.InputStream;
byte[] buffer = new byte[(int) s.Length];
s.Read(buffer, 0, (int) s.Length);
//...and then to string
ASCIIEncoding enc = new ASCIIEncoding();
string b = enc.GetString(buffer);
//send back data as HTTP Response header
Response.AddHeader("Request_Confirmation",
"Dear " + sender +
"! Your request has been received at " +
DateTime.Now.ToString() + ".");
//send back data as HTTP Response body
Response.Write("Request received: " + b);
Response.End();
}
Call ProcessRequest from Page_Load method of the web form. Compile .Net SendRequest project.
Then create a VFP part for sending requests and obtaining responses from ASP.Net page. As I said, this part must include URL for the webpage. The local server is used for simplicity.
#DEFINE DESTINATION_URL;
"http://localhost/sendrequest/exchangedata.aspx"
SET PROCEDURE TO HttpRequest ADDITIVE
LOCAL oHttp As THttpRequest
oHttp = CREATEOBJECT("THttpRequest")
oHttp.Open("POST", DESTINATION_URL)
oHttp.SetRequestHeader("Request_Sender", SYS(0))
WAIT WINDOW NOWAIT "Sending HTTP Request..."
oHttp.Send(FILETOSTR("config.fpw")) && body
WAIT CLEAR
WITH oHttp
? .status && returns "200"
? .GetResponseHeader("Request_Confirmation")
? .ResponseText
ENDWITH
|