Class HttpClient() Foundation

Class function of the HttpClient class.

Description

The HttpClient feature is a HTTP/1.1 compliant HTTP agent implementation, provided by the HttpClient class. It also introduces other classes for client-side request and response message handling. See HttpRequestMessage() as well as HttpResponseMessage() for more details on how to deal with the HTTP protocol message content.

HttpClient() supports synchronous and asynchronous request/response handling and state of the art security capabilities such as client certificates for authentication against a server. The HttpClient automatically uses the security protocols that are supported on the respective operating system, for example, SSL 3.0, TLS 1.0, TLS 1.1, or TLS 1.2.

Class Methods
:new()
Creates an instance of the HttpClient class.
Runtime Data
:httpRequest
The request message object.
:httpResponse
The response message object.
Connection/Session Control
:setAuthorization()
Sets username and password for server authentication.
:setCertificate()
Binds a client certificate from the Windows Certificate Store.
:setCertificateFromFile()
Binds a client certificate from a file.
:setOption()
Changes a HttpClient option.
:setProxy()
Enables the connection via a proxy server.
:setTimeout()
Sets communication timeouts.
Content/Protocol Control
:setAcceptCharset()
Defines the accepted charset for responses from the server.
:setAcceptType()
Defines the accepted content type for responses from the server.
:setMethod()
Sets the request method.
:setUserAgent()
Sets the user agent.
Error Handling
:getLastError()
Returns the numeric value of the last error.
:getLastMessage()
Returns the message associated with the last error.
Request Execution
:disconnect()
Cleans up resources and disconnects the socket.
:getFile()
Sends a request and writes the reponse to a file.
:getStatusCode()
Returns the HTTP status code of the last operation.
:getStatusText()
Returns the text associated with the HTTP status code.
:isBusy()
Determines whether a request is being executed.
:send()
Sends a synchronous request to the server.
:sendAsync()
Sends an asynchronous request to the server.
:wait()
Waits for completion of an asynschronous request.
Callbacks
:afterSend()
Notifies the application when a response is received.
:beforeSend()
Notifies the application when a request is about to be sent.
:onBusy()
Notifies the application about a state change.
Examples
Basic usage scenarios of the HttpClient class

// The example demonstrates basic usage-scenarios of the HttpClient class. 

#include "Common.ch" 
#pragma library("xpprt2.lib") 

PROCEDURE Main 
LOCAL oHC 
LOCAL cResult 

SET CHARSET TO ANSI 

// "Simple GET request with subsequent testing of the status code 
? "Simple GET request..." 
oHC     := HttpClient():new( "http://www.alaska-software.com" ) 
cResult := oHC:send() 
IF oHC:getStatusCode() != 200 
  // Handle error 
ENDIF 
?? IIF( oHC:getStatusCode() == 200, "ok", "failed: " + oHC:httpResponse:statusText ) 

// Simple GET request with parameters and subsequent testing of 
// the status code. This example uses "ugly" coding; manual string 
// concatenation and parameter mangling are required 
? 
? "Simple GET request with parameters..." 
oHC     := HttpClient():new( "http://www.alaska-software.com/reflection.cxp?name=Paul&id=120" ) 
cResult := oHC:send() 
IF oHC:getStatusCode() != 200 
  // Handle error 
ENDIF 
?? IIF( oHC:getStatusCode() == 200, "ok", "failed: " + oHC:httpResponse:statusText ) 

// Better way for handling requests with parameters 
? 
? "Better GET request with parameters..." 
oHC     := HttpClient():new( "http://www.alaska-software.com/reflection.cxp" ) 
oHC:httpRequest:setParameter( "name", "Paul" ) 
oHC:httpRequest:setParameter("id"   , 120 ) 
cResult := oHC:send() 
IF oHC:getStatusCode() != 200 
  // Handle error 
ENDIF 
?? IIF( oHC:getStatusCode() == 200, "ok", "failed: " + oHC:httpResponse:statusText ) 

// Using the POST method instead of GET for transferring the 
// form content 
? 
?  "Using POST instead of GET for transferring form content..." 
oHC     := HttpClient():new( "http://www.alaska-software.com/reflection.cxp" ) 
oHC:httpRequest:setParameter( "name", "Paul" ) 
oHC:httpRequest:setParameter( "id"  , 120 ) 
oHC:setMethod( "POST" ) 
cResult := oHC:send() 
IF oHC:getStatusCode() != 200 
  // Handle error 
ENDIF 
?? IIF( oHC:getStatusCode() == 200, "ok", "failed: " + oHC:httpResponse:statusText ) 

// Executing a request which will fail. A non-HTTP 
// protocol error is signaled by the status code -1. 
// In this example, the domain name cannot be resolved. 
? 
? "Trying a request which will fail..." 
oHC     := HttpClient():new("http://www.this-url-does-not-exist.anywhere") 
cResult := oHC:send() 

IF oHC:getStatusCode() != 200 
  IF oHC:getStatusCode() ==-1 
    ? "Non HTTP protocol error:" 
    ? oHC:getLastError() 
    ? oHC:getLastMessage() 
  ELSE 
    ? "HTTP protocol error:" 
    ? oHC:httpResponse:statusCode 
    ? oHC:httpResponse:statusText 
  ENDIF 
ENDIF 

UNUSED( cResult ) 
WAIT 
RETURN 
Uploading and downloading files with the HttpClient class

// The example demonstrates uploading and downloading files with the HttpClient class. 

#include "Common.ch" 

PROCEDURE Main 
LOCAL oHC 
LOCAL cResult 

SET CHARSET TO ANSI 

? "Uploading a file..." 
oHC     := HttpClient():new( "http://www.alaska-software.com/reflection.cxp" ) 
MemoWrit( GetEnv("TEMP")+"\file4upload.txt", "Hello World" ) 
oHC:httpRequest:setFileParameter( "file1", GetEnv("TEMP")+"\file4upload.txt" ) 
cResult := oHC:send() 
IF oHC:getStatusCode() != 200 
  // Handle error 
ENDIF 
?? IIF( oHC:getStatusCode() == 200, "ok", "failed: " + oHC:httpResponse:statusText ) 

// Downloading a file directly to a file on disk (C:\demofile.zip). 
// The approach shown here allows downloading arbitrary files. A 
// simple :send() would return the downloaded file in a binary string 
// instead, and hence would be restricted by the available memory. 
? 
? "Downloading a file..." 
oHC     := HttpClient():new( "http://www.alaska-software.com/demofile.zip" ) 
oHC:getFile( "c:\demofile.zip" ) 
IF oHC:getStatusCode() != 200 
  // Handle error 
ENDIF 
?? IIF( oHC:getStatusCode() == 200, "ok", "failed: " + oHC:httpResponse:statusText ) 

UNUSED( cResult ) 
WAIT 
RETURN 
Advanced concepts of the HttpClient class

// The example demonstrates advanced concepts of the HttpClient class. 

#include "Common.ch" 

PROCEDURE Main 
LOCAL oHC, oRM 
LOCAL cResult 
LOCAL oResponse1, oResponse2 
LOCAL aCookies 

SET CHARSET TO ANSI 

// Sending a request with a cookie name/value pair set, similar to 
// what a browser would do if a cookie was stored 
? "Sending request with cookie set..." 
oHC     := HttpClient():new( "http://www.alaska-software.com/reflection.cxp" ) 
oHC:httpRequest:setCookie( "myid", "the-key-is-my-key" ) 
cResult := oHC:send() 

// Get the cookies from the last response and reuse them with the next 
// request. This is required if you want to preserve session state 
// between requests 
aCookies:= oHC:httpResponse:getCookies() 
oHC     := HttpClient():new( "http://www.alaska-software.com/reflection.cxp" ) 
AEVal( aCookies, {|o| oHC:httpRequest:setCookie(o)} ) 
cResult := oHC:send() 
?? IIF( oHC:getStatusCode() == 200, "ok", "failed: " + oHC:httpResponse:statusText ) 

// Using a HttpClient object with pre-defined HttpRequest 
// instances and repeated requests with different response 
// formats. 
? 
? "Requesting a resource in different response formats..." 
oHC     := HttpClient():new() 
oRM     := HttpRequestMessage():new( "http://www.alaska-software.com/reflection.cxp" ) 

// Ask server to deliver content in HTML format 
oHC:setAcceptType( "text/html" ) 
oResponse1 := oHC:send( oRM ) 

// Ask server to deliver content in XML format 
oHC:setAcceptType( "application/xml" ) 
oResponse2 := oHC:send( oRM ) 

? "HTML:",SubStr( oResponse1:getContent(), 1, 30 ) 
? "XML :",SubStr( oResponse2:getContent(), 1, 30 ) 

// Performing authorization for accessing a protected 
// resource 
? 
? "Requesting a protected resource..." 
oHC     := HttpClient():new( "http://www.alaska-software.com/secure/auth-required.cxp" ) 
cResult := oHC:send() 
?? IIF( oHC:getStatusCode() == 200, "User authorized", "Authorization failed (code: " + Var2Char(oHC:getStatusCode()) + ")" ) 

? 
? "Requesting a protected resource with user name and password..." 
oHC:setAuthorization( "username","password" ) 
cResult := oHC:send() 
?? IIF( oHC:getStatusCode() == 200, "User authorized", "Authorization failed (code: " + Var2Char(oHC:getStatusCode()) + ")" ) 

UNUSED( cResult ) 
WAIT 
RETURN 
Performing a SOAP request

// The example demonstrates performing a SOAP request 
#include "Common.ch" 

PROCEDURE Main 
LOCAL cSoapRequest 
LOCAL oHC 
LOCAL cResult 

// Create the SOAP request message 
TEXT INTO cSoapRequest TRIMMED 
<?xml version="1.0" encoding="UTF-8"?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:ec.europa.eu:taxud:vies:services:checkVat:types"> 
 <SOAP-ENV:Body> 
  <ns1:checkVat> 
   <ns1:countryCode>DE</ns1:countryCode> 
   <ns1:vatNumber>100</ns1:vatNumber> 
  </ns1:checkVat> 
 </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 
ENDTEXT 

// Process the SOAP request 
oHC := HttpClient():new( "http://ec.europa.eu/taxation_customs/vies/services/checkVatService" ) 
oHC:setAcceptType( "text/xml" ) 
oHC:setAcceptCharSet( "utf-8" ) 
oHC:httpRequest:setMethod( "POST" ) 
oHC:httpRequest:setContentType( "text/xml" ) 
oHC:httpRequest:setContent( cSoapRequest ) 
cResult := oHC:send() 
? "Response returned for SOAP request:" 
? cResult 
WAIT 
RETURN 

Feedback

If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.