Acting as a HTTP Server

This KCML can be used to process HTTP requests. A KCML HTTP server can either run as a standalone daemon or be invoked by a web server such as Apache.

In both cases a program must be run via the KCML command line. The program will need to create a dynamic HTTP server object that creates a HTTP server instance.

As soon as the server object has been created and configured the program should call the method ProcessRequests() which processes all incoming HTTP requests before calling the user specified callback routine. This is a blocking call that will only return on an error (such as a timeout) or when the HTTP client has disconnected.

Creating the HTTP object

The first step is creating a HTTP server object.

OBJECT oHttp = CREATE "dynamic","http"

After creating the HTTP server object you may wish to configure several options. You can change some options using the methods defined. It is also possible to use the methods GetLastError() and GetLastErrorString() to retrieve info about the last error to occur.

You must setup the callback routine before you can process messages. This should return TRUE if it can process the request by building a response message and calling the SetResponse() method. If you don't process the request and return FALSE then KCML will send a 404 Not Found response for you.

oHttp.SetCallBack(BYREF 'MyCallbackRoutine)

Setting the timeout property allows the ProcessRequest() method to return early with a timeout error in the event the timeout expires.

When the KCML is started by the connection manager listening on the port then the connection already exists. However it is also possible to start KCML as a daemon and have it do the listen by calling the Listen() method passing the port on which to listen out. This replaces the ProcessRequests() method and will also block until the client disconnects or there is an error. This can be useful when testing a server in the workbench. The timeout property also applies to connections with the Listen() method and can be used to timeout the initial connection as well as subsequent requests.

Processing HTTP requests

When the object has been configured correctly it is time to start processing the HTTP requests. You will do this by making a blocking call to ProcessRequests(). This will only return if an error occurred, a timeout expires or the HTTP client has disconnected.

$COMPLIANCE 3
DIM rc
OBJECT oHTTP = CREATE "Dynamic", "http"
oHTTP.SetCallBack(BYREF 'HTTPCallback)
rc = oHTTP.ProcessRequests()
$END
DEFSUB 'HTTPCallback(OBJECT oHTTP, sURL$, sMethod$, OBJECT oRequest, OBJECT oResponse) AS Bool
    LOCAL DIM sHost$0
    REDIM sHost$ = oRequest.Headers.Find$("host")
    oResponse.Headers.Add("X-Host", sHost$)
    IF (sMethod$ == "GET")
        SELECT CASE sURL$
        CASE "/Test2"
            oResponse.SetResponse("text/html", "<html><body><h1>HELLO WORLD</h1></body></html>")
            RETURN TRUE
        CASE "/Test7"
            IF (NOT oResponse.SendFile("text/html", "badfilename.htm"))
                oResponse.SetResponse("text/html", "<html><body><h1>NO FILE</h1></body></html>")
            END IF
            RETURN TRUE
        CASE ELSE
            RETURN FALSE
        END SELECT
    ELSE IF (sMethod$ == "POST")
        SELECT CASE sURL$
        CASE "/Test4"
            oResponse.SetResponse("text/xml", oRequest.Body$)
            RETURN TRUE
        CASE "/Test5"
            oResponse.SetResponse("text/xml", oRequest.Body$)
            RETURN TRUE
        CASE ELSE
            RETURN FALSE
        END SELECT
    ELSE
        RETURN FALSE
    END IF
    RETURN FALSE
END SUB
Error messages

In the event of a problem there are two methods implemented for error reporting.

...
error_number = oHttp.GetLastError()
...

Returns the last error number. These are small negative integers and are the same error codes as returned by the SOAP object.

error_string$ = oHttp.GetLastErrorString$()

Returns the last error text.