Download File (HTTP) with FoxPro

Today I was asked to help with the FoxPro problem on how to upload a file via HTTP.

I found two things: one was paid ActiveX, and the other required libcurl.

Is there a way to do this without any extra (VFP 8), something like HttpURLConnection in Java? For example, using Microsoft.XMLHTTP

+4
source share
6 answers

Two fragments that work and do not require additional files / dlls / flls / etc.

 Local loRequest, lcUrl, lcFilename lcUrl = "http://example.com/foo.zip" lcFilename = "C:\Temp\PSV.zip" loRequest = Createobject('MsXml2.XmlHttp') loRequest.Open("GET",lcUrl,.F.) loRequest.Send() StrToFile(loRequest.ResponseBody,lcFilename) 

and

 lox = CREATEOBJECT("inetctls.inet") lcSuff = lox.OpenURL("http://whatever.co.uk/suff.htm") STRTOFILE(lcStuff, "c:\data\myfile.htm") 

(taken from here )

+8
source

Is my HttpClient.prg file (only GET supported):

 #define INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY 4 #define REQ_STATE_UNINITIALIZED 0 && open()has not been called yet. #define REQ_STATE_LOADING 1 && send()has not been called yet. #define REQ_STATE_LOADED 2 && send() has been called, and headers and status are available. #define REQ_STATE_INTERACTIVE 3 && Downloading; responseText holds partial data. #define REQ_STATE_COMPLETED 4 && The operation is complete. DEFINE CLASS HttpClientRequest As Custom readystate=REQ_STATE_UNINITIALIZED Protocol=NULL Url=NULL requestBody=NULL responseBody=NULL PROCEDURE Open(tcProtocol, tcUrl) IF this.readystate != REQ_STATE_UNINITIALIZED ERROR "HttpClientRequest is already opened." ENDIF IF VARTYPE(m.tcProtocol)!="C" OR VARTYPE(m.tcUrl)!="C" ERROR "Invalid type or count of parameters." ENDIF IF NOT INLIST(m.tcProtocol,"GET") ERROR "Unsupported or currently not implemented protocol type." ENDIF this.Protocol = m.tcProtocol this.Url = m.tcUrl this.readystate = REQ_STATE_LOADING ENDPROC PROCEDURE Send(tcBody) IF this.readystate != REQ_STATE_LOADING ERROR "HttpClientRequest is not in initialized state." ENDIF IF PCOUNT()=0 m.tcBody=NULL ENDIF IF this.Protocol=="GET" AND (NOT ISNULL(m.tcBody)) ERROR "Invalid type or count of parameters." ENDIF this.requestBody = m.tcBody this.readystate = REQ_STATE_LOADED DECLARE integer InternetOpen IN "wininet.dll" ; string @ lpszAgent, ; integer dwAccessType, ; string @ lpszProxyName, ; string @ lpszProxyBypass, ; integer dwFlags DECLARE integer InternetCloseHandle IN "wininet.dll" ; integer hInternet DECLARE integer InternetCanonicalizeUrl IN "wininet.dll" ; string @ lpszUrl, ; string @ lpszBuffer, ; integer @ lpdwBufferLength, ; integer dwFlags DECLARE integer InternetOpenUrl IN "wininet.dll" ; integer hInternet, ; string @ lpszUrl, ; string @ lpszHeaders, ; integer dwHeadersLength, ; integer dwFlags, ; integer dwContext DECLARE integer InternetReadFile IN "wininet.dll" ; integer hFile, ; string @ lpBuffer, ; integer dwNumberOfBytesToRead, ; integer @ lpdwNumberOfBytesRead LOCAL m.hInternet,lcUrl,lnUrlLen,m.hInternetFile,lcBuffer,lnBufferLen,lnReaded m.hInternet = InternetOpen("akd HttpClientRequest for Visual FoxPro", ; INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY, ; NULL, NULL, 0) this.responseBody = "" IF m.hInternet != 0 m.lnUrlLen = LEN(this.Url)*8 m.lcUrl = REPLICATE(CHR(0),m.lnUrlLen) InternetCanonicalizeUrl(this.Url, @lcUrl, @lnUrlLen, 0) m.hInternetFile = InternetOpenUrl(m.hInternet, @lcUrl, NULL, -1, 0, 0) IF m.hInternetFile != 0 m.lnBufferLen = 10240 DO WHILE .T. m.lcBuffer = REPLICATE(CHR(0),m.lnBufferLen) m.lnReaded = 0 IF NOT (0!=InternetReadFile(m.hInternetFile, @lcBuffer, m.lnBufferLen, @lnReaded) AND m.lnReaded>0) EXIT ENDIF this.responseBody = this.responseBody + LEFT(m.lcBuffer,m.lnReaded) this.readystate = REQ_STATE_INTERACTIVE ENDDO InternetCloseHandle(m.hInternetFile) ENDIF InternetCloseHandle(m.hInternet) ENDIF this.readystate = REQ_STATE_COMPLETED ENDPROC ENDDEFINE 

Usage for GET requests:

 Local HttpClient m.HttpClient = NEWOBJECT("HttpClientRequest","httpclient.prg") m.HttpClient.Open("GET","http://servername/path/resourcename") m.HttpClient.Send() 

After the above code is executed, the server response is contained in the m.HttpClient.responseBody property, and you can save the value in a file or, for example, for images in the PictureVal property of the Image object:

 STRTOFILE(m.HttpClient.responseBody,"c:\filename"); m.myform.AddObject("myimg",""image") m.myform.myimg.PictureVal=m.HttpClient.responseBody 
+1
source

Take a look at using West Wind Web Connect. This is a framework that allows you to write a VFP application that is accessible from the Internet.

0
source

You can do this in VFP, but this requires registering Windows DLLs to open connection descriptors and make calls to receive data.

Another option is to use automation, for example, in Internet Explorer. You can create an ie object from VFP and call its methods to open the specified URL, wait for the "ready state" to complete, and then view the contents. As for trying to get things that require a string of URL parameters, you can add them without problems, but if it requires POST variables, this is a bit more effort.

As Jerry mentioned, West-Wind's instruments are quite powerful, and Rick Strahl has been doing this since ... about 1993, which I remember. Its other tool is specifically wwIPTools.DLL, which offers even more features.

0
source

You can also look at the free VFPConnection library, it also has a great free JSON library.

0
source

Option 1:

 Declare Integer URLDownloadToFile In urlmon.dll As _apiURLDownloadToFile; Integer pCaller, ; String szURL, ; String szFileName, ; Integer dwReserved, ; Integer lpfnCB 

Just do shure to clear the file from cache first:

 Declare Integer DeleteUrlCacheEntry In wininet.dll As _apiDeleteUrlCacheEntry ; String lpszUrlName 

Or add a random parameter at the end of the URL, for example, "? Somerandomvalue".

Option 2:

 Declare Integer InternetOpen In wininet.dll As _apiInternetOpen ; String lpszAgent, ; Integer dwAccessType, ; String lpszProxy, ; String lpszProxyBypass, ; Integer dwFlags Declare Integer InternetOpenUrl In wininet.dll As _apiInternetOpenUrl ; Integer hInternet,; String lpszUrl,; String lpszHeaders,; Integer dwHeadersLength,; Integer dwFlags,; Integer dwContext Declare Integer InternetReadFile In wininet.dll As _apiInternetReadFile ; Integer hFile, ; String @lpBuffer, ; Integer dwNumberOfBytesToRead, ; Integer @lpdwNumberOfBytesRead Declare Integer InternetCloseHandle In wininet.dll As _apiInternetCloseHandle ; Integer hInternet 

The proper use of functions can be found on MSDN.

PS: You missed this: http://curl.haxx.se/libcurl/foxpro/

0
source

Source: https://habr.com/ru/post/1386578/


All Articles