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 .

Simple HTTP Content Download

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

Posting Form Data and sending Headers to a Server

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)

POSTING Raw Data

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

*** Explicitly specify HTTP verb optionall
* loHttp.cHttpVerb = "POST"       && (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)

Making a REST Service call with JSON

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

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 CallService() method.

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

Sending Binary Data

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.

Streaming output directly to file

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.

Reveiving Download Event Notifications

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:

wwHttp::OnHttpBufferUpdate


© West Wind Technologies, 1996-2019 • Updated: 05/02/19
Comment or report problem with topic