Access HTTP content over the Web
West Wind Internet Protcols supports HTTP access through the wwHTTP class. Downloading content off the Web and posting data to a Web site is easy using the wwHTTP class.
A number of mechanisms for accessing Web content with just a few lines of code are available. Web content includes anything that is accessible via the HTTP protocol; content can be HTML, but more importantly it can be XML, a document in some binary format or even raw data such a DBF file passed as a string. wwHttp supports most of the functionality that HTTP provides including GET and POST operations, secure communication over SSL/HTTPS and security via Basic or Windows Authentication .
Most operations can be performed using the
wwHttp::HttpGet() method. To retrieve HTTP content - which can be HTML text as the example below, images, files and anything else really - from a Web site you can use this simple code:
oHTTP=CREATEOBJECT("wwHTTP") lcHTML = oHTTP.Get("http://www.west-wind.com/") *** Show HTML generated in Browser ShowHTML( lcHTML ) && in wwUtils.prg
To post form data like an HTML form to a server you can use the
.AddPostKey() method to add values to send. If you need to add HttpHeaders use
.AppendHeader() to add any standard or custom HTTP headers to your request. Then just use
.HttpGet() to make the request:
oHTTP=CREATEOBJECT("wwHTTP") oHTTP.AddPostKey("FirstName","Rick") oHTTP.AddPostKey("LastName","Strahl") oHTTP.AddPostKey("Company","West Wind Technologies") *** Optionally add custom headers oHTTP.AppendHeader("cache-control",private") oHttp.AppendHeader("Custom-Header","Custom value") lcHTML = oHTTP.Post("http://www.west-wind.com/wconnect/TestPage.wwd") ShowHTML( lcHTML )
This properly formats the HTTP POST buffer for sending the variables to the Web server which simulates an HTML form submission.
The above example posts using Html Form type POST data that is provided in key value pairs. wwHttp supports 3 data post modes via the nHttpPostMode property:
- 1 - application/x-www-form-urlencoded (default - Html Form submissions)
- 2 - multi-part forms (useful for file uploads and multi-part HTML form submissions)
- 4 - raw data passed as is (send data and binary files in raw format)
A common scenario is to post XML to a server for some sort of XML Service. In this case you'll need to change the POST format. For XML or Raw data set the nHttpPostMode to 4. By default this uses a Content-type of text/xml, but you can optionally override the cContentType property for other types of content.
To send XML data to a server you can use the following code:
loHttp = CREATEOBJECT("wwHttp") *** Specify that we want to post raw data and a custom content type loHttp.cContentType = "text/xml" && Content type of the data posted * loHttp.cHttpVerb = "POST" && Use for anything but POST/GET verbs (PUT/DELETE/HEAD/OPTIONS) *** Load up the XML data any way you need lcXML = FILETOSTR("XmlData.xml") *** Set the POST buffer - Note: No name parameter, just the buffer loHttp.AddPostKey(lcXML) lcXmlResult = loHttp.Post("http://www.west-wind.com/SomeXmlService.xsvc") IF (loHttp.nError # 0) RETURN ENDIF ShowXml(lcXmlResult)
REST services are the latest rage, and when using REST you typically deal with JSON data instead of XML. The client tools include a wwJsonSerializer class that can handle serialization and deserialization for you.
DO wwHttp DO wwJsonSerializer loSer = CREATEOBJECT("wwJsonSerializer") lcJsonIn = loSer.Serialize(loPostObject) && Some object or value to serialize loHttp = CREATEOBJECT("wwHttp") loHttp.cContentType = "application/json" * loHttp.cHTTPVerb = "POST" && not required for GET/POST but use for PUT/DELETE/HEAD/OPTIONS etc, loHttp.AddPostKey(lcJsonIn) && raw post data lcJsonResult = loHttp.Post(lcUrl) loResultObject = loSer.DeserializeJson(lcJsonResult) *** Do something with the result object ? loResultObject.status ? loResultObject.Data.SummaryValue
To make things even easier with JSON REST Services take a look at the JsonServiceClient class which handles all the HTTP calls and serialization and error handling all via single
The following sends JSON data to a service and receives a JSON result back as a FoxPro object:
loProxy = CREATEOBJECT("wwJsonServiceClient") lcUrl = "http://albumviewer.west-wind.com/api/album" lvData = loAlbum && FoxPro object lcVerb = "PUT" && HTTP Verb *** Make the service call and returns an Album object loAlbum2 = loProxy.CallService(lcUrl,lvData,lcVerb) IF (loProxy.lError) ? loProxy.cErrorMsg RETURN ENDIF ? loAlbum2.Title ? loAlbum2.Artist.ArtistName
You can also send binary data, which in FoxPro is just represented as a string. Make sure you set the
.cContentType property to specify what you are sending to the server:
loHttp = CREATEOBJECT("wwHttp") *** Specify that we want to post raw data with a custom content type loHttp.cContentType = "application/pdf" lcPdf = FILETOSTR("Invoice.pdf") loHttp.AddPostKey(lcPdf) && Add as raw string *** Send to server and retrieve result lcHtml = loHttp.Post("http://www.west-wind.com/SomeUril.xsvc")
Note that you can use the cContentType property to specify the content type of the data POSTed to the server.
You can also stream the content of a URL directly to a file. To do this you can use additional parameters on the HttpGetMethod which takes the Url, username and password and output file as parameters.
loHttp = CREATEOBJECT('wwhttp') loHttp.Get("http://www.west-wind.com/","","","c:\test.htm") IF loHttp.nError # 0 wait window loHttp.cErrorMsg return ENDIF *** Browse the file from local disk GoUrl("c:\test.htm")
Streaming to file allows you to bypass large memory usage as wwHTTP doesn't build up a large string but instead reads one buffer at a time and outputs it to disk.
wwHttp also includes an OnHttpBufferUpdate event wich provides you download progress information via an event handler on the wwHttp class. You can find out more on how this works and an example here:
Comment or report problem with topic