OpenInsight 10.2 introduces a new control type called HTTPSERVER, which provides a lightweight HTTP web-server control for use in your applications.
Using the control is a simple process:
- Drop a “HTTP Server” control onto a form
- Set the port number to listen on via the PORT property
- Use the START method to start the server, or set the STARTUPMODE property to “Automatic” if you want the server to start when the form is created.
- Listen for requests via the HTTPREQUEST event and respond to them using methods such as the SETRESPONSECONTENT and SETRESPONSEFILE methods
- Return the response using the SENDRESPONSE method
So, if you set up a HTTPSERVER on port 8089 and execute the form you can use a browser to communicate with it via a URL something like this:
The HTTPREQUEST event
As you can see, setting up the control is fairly easy, but the bulk of the work needs to be done in the HTTPREQUEST event where you examine the contents of the request and return the appropriate content.
The event has the following interface:
bForward = HTTPREQUEST( CtrlEntID, | CtrlClassID, | RequestID, | RequestHeaders )
And the following parameters:
|CtrlEntID||ID of the HTTP Server control firing the event|
|CtlrClassID||Type of control firing the event – this is always “HTTPSERVER”|
|RequestID||Unique identifier for returning a response to the client – this is used with the various “SETRESPONSE” methods that set response data.|
|RequestHeaders||An @FM delimited dynamic array of data that describes the request. The format is similar to the HTTPRequest argument used in OECGI programming. The full format is described in the PS_HTTPSERVER_EQUATES insert record.|
As mentioned above, the RequestHeaders parameter describes the details of the request using a format similar to the format used in OECGI programming. There are some differences that are worth highlighting however:
- For a GET request the query values are already parsed into their own fields (<37> and <38>) as an associated multi-value pair. They are not found unparsed in field <1> as per OECGI.
- For a POST or PUT request the content is obtained using the GETREQUESTCONTENT method (see below) – it is not passed in the RequestHeaders variable.
- Cookies are already parsed into their own fields (<39> and <40>) as an associated multi-value pair.
- Headers are already parsed into their own fields (<35> and <36>) as an associated multi-value pair.
Note that out of the box we do not enforce any restrictions or framework on how you handle the request – compare this to classic OECGI programming where the “PathInfo” field is used to determine which “INET_” procedure is executed to fulfill it (via the RUN_INET_REQUEST stored procedure) There is no such requirement with the HTTPSERVER control, and you may create your own framework if you wish (although see the note on RTI_RUN_HTTPSERVER_REQUEST below).
Returning a response
There are several methods described below that you may use to process the content that you return to the client.
Note: With each of these you must use the unique RequestID parameter passed to you in the HTTPREQUEST event.
E.g. Returning HTML in the HTTPREQUEST event
ReposID = @AppID<1> : "*DOC*HTML*INDEX_PAGE" HTML = Repository( "ACCESS", ReposID ) Call Exec_Method( CtrlEntID, "SETRESPONSECONTENT", RequestID, HTML ) Call Exec_Method( CtrlEntID, "SENDRESPONSE" )
E.g. Returning a file in the HTTPREQUEST event
ReposID = @AppID<1> : "*DOC*HTML*INDEX_PAGE" FilePath = Repository( "GETSUBKEY", ReposID ) Call Exec_Method( CtrlEntID, "SETRESPONSEFILE", RequestID, FilePath ) Call Exec_Method( CtrlEntID, "SENDRESPONSE" )
The HTTPSERVER methods
Gets the raw content sent to the server by the client as part of a POST or PUT request.
ReqContent = Exec_Method( CtrlEntID, "GETREQUESTCONTENT", RequestID )
Returns raw content for the response as set via a previous call to the SETRESPONSECONTENT method.
RspContent= Exec_Method( CtrlEntID, "GETRESPONSECONTENT", RequestID )
Returns details for a response cookie as set via a previous call to the SETRESPONSECOOKIE method (see below for the CookieVal format).
CookieVal = Exec_Method( CtrlEntID, "GETRESPONSECOOKIE", RequestID, | CookieName )
Returns the name and path of the response content file set with a previous call to the SETRESPONSEFILE method.
RspFile = Exec_Method( CtrlEntID, "GETRESPONSEFILE", RequestID )
Returns the details for a response header as set via a previous call to the SETRESPONSEHEADER method.
HeaderVal = Exec_Method( CtrlEntID, "GETRESPONSEHEADER", RequestID, | HeaderName )
Returns the HTTP status code of the response (defaults to 200).
RspStatus = Exec_Method( CtrlEntID, "GETRESPONSESTATUS", RequestID )
Returns TRUE$ if the specified port is in use on the local machine.
InUse = Exec_Method( CtrlEntID, "ISPORTINUSE", Port, IPv6 )
- Port – Identifies the port to check
- IPv6 – if TRUE$ then check the IPv6 bindings, otherwise check the IPv4 bindings
Sends the response back to the client. This method should be called when you have finished setting the response details (Note that this is called by the promoted system HTTPREQUEST handler in case you forgot to do it in your own code!).
RspSent = Exec_Method( CtrlEntID, "SENDRESPONSE", RequestID )
Sets the content to return to the client, such as a string containing an HTML page.
SetOK= Exec_Method( CtrlEntID, "SETRESPONSECONTENT", RequestID, | Content )
Sets a cookie that is returned to the client via the “Set-Cookie” header.
SetOK = Exec_Method( CtrlEntID, "SETRESPONSECOOKIE", RequestID, | CookieName, | CookieValue )
CookieValue is an @fm-delimited array formatted as follows:
<1> Value <2> Path <3> Domain <4> Expires (internal date format) <5> Max Age (seconds) <6> Secure (TRUE$/FALSE$) <7> HttpOnly (TRUE$/FALSE$) <8> SameSite
If you have a file that contains the content you wish to return then you should use this method to let the server read the file and return it to the client itself. This offers better performance than reading the contents via Basic+ and using the SETRESPONSECONTENT method as it avoids any unnecessary copying of data.
SetOK = Exec_Method( CtrlEntID, "SETRESPONSEFILE", RequestID, | FileNamePath )
Sets a response header and value to be returned to the client.
SetOK = Exec_Method( CtrlEntID, "SETRESPONSEHEADER", RequestID, | HeaderName, | HeaderValue )
Sets the HTTP status code for the response (200, 404, 500 etc).
SetOK = Exec_Method( CtrlEntID, "SETRESPONSESTATUS", RequestID, | StatusCode )
Example HTTPREQUEST handler
As part of version 10.2 we have included a sample HTTPREQUEST event handler called RTI_RUN_HTTPSERVER_REQUEST which you can examine and copy for your own applications if you wish. It emulates the core behavior of the OECGI RUN_INET_REQUEST handler in that it uses the “PathInfo” field to determine the stored procedure to fulfill the request. In this case it looks for a matching procedure that has the prefix “HTTPSVR_” and we have included a couple of example “HTTPSVR_” procedures for you to review as well.
With the addition of the HTTPSERVER control it is now possible to provide HTML content directly from your application, and also provide a means of web-development directly from your desktop without necessarily needing to install a dedicated web-server like IIS.
It is also a good solution for when you want to provide local HTML content in your application’s user-interface via an embedded browser control, because it can avoid the usual security restrictions that browsers enforce for such scenarios.