Home page Home page Home page Home page
Pixel
Pixel Header R1 C1 Pixel
Pixel Header R2 C1 Pixel
Pixel Header R3 C1 Pixel
Pixel
By Sprezz | Tuesday 19 November 2013 10:04 | 0 Comments
When programming for the web using OECGI3, whether using O4W or just directly, occasions arise when the developer needs to query HTTP headers sent by the client that aren't included in the default information passed forward by OECGI3. Additionally, it can become necessary to set HTTP headers for return to the client. The following article discusses how to achieve such functionality.

Querying HTTP Headers

By default OECGI3 passes through a subset of the available HTTP headers. However there may be times when access to additional headers is required. For example, recently when writing a multi-lingual O4W application we wanted to determine which language the user who was attempting to use the system had set their browser to. Knowing this would allow us to deliver back content in their native tongue.

To achieve this we'd have to examine the HTTP_ACCEPT_LANGUAGE header value. Examination of the HTTP_REQUEST passed through showed that this was not available to us.Fortunately  a little known registry entry saved the day for us.

The registry key value "AdditionalValues" allows the specification of a comma delimited list of additional HTTP header values that should be passed into the HTTP Request. The first value will be inserted in field 27, the second in field 28 etc. Please note that this behaviour is likely to change with OpenInsight X when the list of additional values will likely be made multi-valued in field 30.

So for our application we modified the registry entry (Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\RevSoft\OECGI3) as follows :-




Which resulted in a modified request with our desired values :-



It was then a simple  programmatic exercise to extract the language and return the correct pages to the client.

Setting HTTP Headers

When interacting with external APIs, it can sometimes be necessary to set specific HTTP header values - to communicate, for example, the results of an operation via the Status HTTP Header element. There are two ways of approaching this from within OpenInsight - using the INET API routines or playing directly with the labelled common used for setting HTML Headers.

INET API Routines

OpenInsight ships with a number of routines designed to make interacting with the return results of an INET procedure easier. There are currently five of these. They are actually documented in the help file "OpenInsight and Internet", but if, like me, you expect to find system subroutines documented in the Programmer's Reference Manual, I redocument them here with a little more detail.

INETAPI_SETCONTENTTYPE

This takes one parameter - the content type to set. For a definitive list of possible content types see the IANA site. Content type is used by the rendering browser to know how to treat the information that follows. If the content type is found to be incorrect, browsers will examine the beginning of the information looking for a "magic number" that identifies the file type. If that fails browsers will resort to checking the extension of the file.

INETAPI_SETNOCACHE

This takes one parameter, a boolean. If set to 0 then the header is updated to contain an EXPIRES value of 0 and a PRAGMA value of "No-cache". That is to say, somewhat counterintuitively if you want to set no caching you pass FALSE$ not TRUE$. Regretfully this is likely to be ignored by browsers as the Pragma directive is an HTTP 1.0 standard designed for requests only - not responses.

If you as a developer wish to control caching correctly you should use the CACHE-CONTROL header value which is discussed here and defined in the RFC here. With CACHE-CONTROL you can set whether caching is allowed only at the browser or also at proxy/web servers and you can specify how long the information can be cached for. CACHE-CONTROL can be used in conjunction with the section below on setting custom headers.

OpenInsight X will modify this behaviour to use the CACHE-CONTROL directives.

INETAPI_SETSTATUS

This takes one parameter - the status code to set.  A list of all valid codes may be found in the RFC here.

INETAPI_SETREDIRECT

This routine takes four parameters :-

location the destination URI to redirect to
request the original request
addPath a boolean value. To quote the documentation "If the <addPath> parameter is set to "1", then the original (incoming) search string is appended to the destination url, with any parameters passed in the <excluded> list removed from the resulting url"
excluded list of parameters to remove from the search string - these parameters should be field mark delimited.

This is perhaps most easily understood with a simple example. Imagining that we have invoked a program using OECGI3.EXE such as INET_LOOKUP as follows

inet_Lookup?First=John&Second=Smith&Third=Male

and within our program we decided that we wished to redirect to a program called INET_RESULT but only passing in the gender, we would


   call inetApi_SetRedirect("inet_Result", request, 1,"First,Second")


This would result in the STATUS header being set to 302 for a redirect and the LOCATION header being set to the fully qualified location of inet_Result?Third=Male.

INETAPI_SETCOOKIE

This takes eight parameters and these may be field mark delimited to permit the setting of multiple cookies at once. The parameters are as follows :-

name name of the cookie to set
value value to set the cookie to
expDate the internal date at which the cookie should expire. NB  this must be expressed as GMT.
expTime the internal time at which the cookie should expire
path defines the path that the cookie should be returned for. So if you wished to only send a cookie when the user was browsing www.sprezzatura.com/clients you would set path to "/clients"
domain the domain for which you wish the cookie to be returned. For obvious security reasons you can only return cookies for the host domain but by specifying ".sprezzatura.com" cookies would be returned for www.sprezzatura.com, ftp.sprezzatura.com etc.
httpOnly instructs the browser not to expose cookies through channels other than HTTP (and HTTPS) requests. Thus they may not be manipulated by javaScript preventing the stealing of them by cross site scripting attacks.
secureFlag instructs the browser only to send the cookie if the connection is using SSL. This is a security measure to prevent cookie sniffing.

If inetApi_SetCookie were invoked as follows


   call inetapi_setCookie("Mario","Brothers", 17000, 8000, |
                          "", ".sprezzatura.com", 1, 1) 


the SET-COOKIE header would be set to

"Mario=Brothers; expires=Thu, 17-07-2014 02:13:20 GMT; path=/; domain=.sprezzatura.com; httponly; secure"

Setting Custom Headers 

If you wish to set any headers other than the ones catered for above, it is actually very straightforward. Just include the insert INET_HEADERS. This includes a labelled common area with two variables - the headers and their values as field mark delimited arrays. Then depending upon the header type being set, you would either replace an existing value with the new value, or append to the list. For example if you were setting STATUS you would only want one STATUS value in the header, but if you were wishing to set cookies you might have more than one.


   locate headerName in inet_Header_Names% using @FM setting loc else null
   inet_Header_Names%< loc >  = headerName
   inet_Header_Values%< loc > = headerValue




By Sprezz | Friday 15 November 2013 08:37 | 0 Comments
For those of you who've expressed an interest, the internal Sprezzatura OpenInsight Coding Standards document is now available for download from our Whitepapers Section.
By Sprezz | Wednesday 6 November 2013 17:13 | 3 Comments
Regular users will know that calls to SET_PROPERTY and GET_PROPERTY can be made more efficient by passing @rm delimited arrays to the routines rather than making multiple individual calls.

Although using the @rm concatenation method can lead to improved performance you need to be aware of how it is actually implemented, otherwise it can lead to some subtle bugs that may be hard to track down. This is because internally there are two types of properties; PS (Presentation Server) properties, and Synthetic properties, and the order in which they are processed when combined together could cause your code to behave in a manner that you are not expecting.

The PS properties are implemented at a low-level inside the Presentation Server (OINSIGHT.EXE) and generally deal with “real” visual properties such as TEXT, SIZE, LIST and so on: basically they wrap the low-level UI attributes of forms and controls. Access to these properties is via two functions called ps_Get_Property and ps_Set_Property. They are not documented but are used internally by the normal Get_Property and Set_Property functions as needed.

The Synthetic properties are implemented in Basic+ and deal with Form IO logic, data conversion and suchlike; i.e. the things that are specific to OI rather than Windows.

When you don’t use the @rm concatenation method then Get_Property and Set_Property first try to process the request as a Synthetic property, and, if not found, it is then passed on to the PS. This obviously doesn’t cause any issues as no concatenation is involved.

When you do use the @rm concatenation method both Get_Property and Set_Property first pass the arrays onto the PS, which deals with the properties it is responsible for. After that the arrays are scanned for any Synthetic properties and processed accordingly.

In many cases this would have no effect unless the order in which the properties are called is critical. Consider the following example:


   * // Set the TEXT _without_ firing a CHANGED event 
   * // (This will NOT work!) 

   objxArray = "SYSTEM"
   propArray = "BLOCK_EVENTS"
   dataArray = TRUE$

   objxArray := @rm : @window : ".EDL_NAME"
   propArray := @rm : "DEFPROP"
   dataArray := @rm : strName

   objxArray := @rm : "SYSTEM"
   propArray := @rm : "BLOCK_EVENTS"
   dataArray := @rm : FALSE$

   Call Set_Property( objxArray, propArray, dataArray ) 



In this case both BLOCK_EVENTS property calls (PS properties) will be processed before the DEFPROP call (a synthetic property), meaning they will have no effect and the CHANGED event will fire. Consider yourself warned!

This is taken from the document "OI Coding Standards" published by Sprezzatura.
Pixel
Pixel Footer R1 C1 Pixel
Pixel
Pixel
Pixel