www.krengeltech.com

RXS Router

From Wiki

User Guide
v2.10+

Contents

Overview

The RXS Router (RXSRTR) is a program included with RPG-XML Suite (RXS) v2.10+ which runs on the IBM i (AS/400, iSeries, System i) within the HTTP server, acting as a 'router' for CGI requests which use the HTTP protocol.

RXSRTR enables you to both simplify your HTTP processing and add functionality which is not directly available through the HTTP server configuration. Once installed, RXSRTR sits seamlessly between your HTTP server and your CGI programs; no changes are required to existing CGI program functionality and no changes are required to any existing URL's you use to access your CGI programs (such as user favorites or links from webpages).

RXSRTR enables you to perform the following additional functionality:

  1. Route all CGI requests through a single URL format
  2. Specify a library list to use when calling programs
  3. Swap to a different user profile when calling programs
  4. Log all information about the request to an audit log file
  5. Call non-CGI programs, passing parameters and receiving responses

All this functionality is data-driven – that is, it is controlled via data held in a single control file used by RXSRTR. If you need to add or change the programs you need to call, you simply update the RXSRTR control file.

Simplified HTTP Configuration

Below is an example HTTP server instance configuration fragment, showing how three different URL formats match different CGI program calls in different libraries:


  ScriptAliasMatch ^/cgi-bin/(.*) /qsys.lib/public.lib/$1.pgm
  ScriptAliasMatch ^/cust/(.*) /qsys.lib/customers.lib/initial.pgm
  ScriptAliasMatch ^/db2wse/(.*) /qsys.lib/db2wse.lib/db2wse.pgm
  <Directory /qsys.lib/public.lib/>
     Options +ExecCGI
     Allow From all
  </Directory>
  <Directory /qsys.lib/customers.lib/>
     Options +ExecCGI
     Allow From all
  </Directory>
  <Directory /qsys.lib/db2wse.lib/>
     Options +ExecCGI
     Allow From all
  </Directory>


In this case, multiple ScriptAliasMatch directives route different URLs to different CGI programs in different libraries. For instance, assuming this HTTP server is on a IBM i with an IP address of 192.168.0.1, below is a list of example URLs and the resulting program which will be called:


URL used CGI Program called
http://192.168.0.1/cgi-bin/mypgm PUBLIC/MYPGM
http://192.168.0.1/cgi-bin/yourpgm PUBLIC/YOURPGM
http://192.168.0.1/cust/john CUSTOMERS/INITIAL
http://192.168.0.1/cust/ CUSTOMERS/INITIAL
http://192.168.0.1/db2wse/string DB2WSE/DB2WSE


This can be confusing, since it's not always clear which program will eventually be called when a given URL is used and the configuration can grow very large and complex, since each library specified has to have its own <Directory> section in the configuration, specifying authorities etc. Additionally, if any changes are required, the HTTP server must be restarted. Finally, the above configuration is also insecure, since it allows any user to call any program in the PUBLIC library.

By contrast, RXSRTR allows you to replace all the above configuration with a single ScriptAliasMatch and <Directory> section in your HTTP server instance configuration file which can be used for all CGI program calls:


  ScriptAliasMatch ^/(.*) /qsys.lib/rxsrtr.lib/rxsrtr.pgm
  <Directory /qsys.lib/rxsrtr.lib/>
     Options +ExecCGI
     Allow From all
  </Directory>


Using the above directive, every URL will call RXSRTR and by configuring RXSRTR, you can ensure that all existing URL's (which may exist as links in web pages, user's bookmarks etc.) will result in the same programs being called as before.

Within the RXSRTR configuration itself, you define which programs should be called and how. You can dynamically change these configuration settings without needing to change the HTTP server configuration or restart the HTTP server.

This means that you can have a much simpler HTTP configuration. Because RXSRTR works at the program level, you can easily configure RXSRTR to specify exactly which programs can be called, immediately making your system more secure.

Enhanced HTTP Routing Functionality

When a request is matched by the HTTP server which results in RXSRTR being called, RXSRTR analyzes the URL to determine a 'request routing identifier' (RRID), which will be used to determine the routing call processing for the request. This processing is described in detail in the RXS Router Configuration section.

Once the RRID has been determined for a request, RXSRTR retrieves the control data for that RRID. The control data specifies not only the actual program to call, but also the following characteristics of the call:

  • Which additional libraries to add to the library list prior to calling the program
  • Which user profile to swap to for the call

RXSRTR control data is held in the RXSRTRCTL file. Each record has a key of the RRID and contains a 'routing data' field. Within the routing data field, various flag/value pairs can be specified to control what program will be called for the given RRID.

The format of the DATA field is as follows:

 {-flag value -flag value –flag value...}

where flag can be one of a number of special values as follows:


Flag Description of associated value
pgm Name of application program to be called (required)
lib Name of application library
usrprf User profile to run as
passwd Password for user profile
liblst Comma-separated library list (10 libraries max) or qualified job description name
cvtopt Comma-separated conversion options
response Response type for non-CGI programs


Note the following specifications related to control data flags and the way they must be specified in the DATA field in the RXSRTRCTL file:

  • Each flag must be prefixed with a minus-sign, e.g. -pgm
  • Values are automatically converted to upper-case for processing
  • Flag/value pairs can be specified in any order
  • Except for the pgm flag, all flag/value pairs are optional
  • Comma-separated lists (for the liblst and cvtopt flags) must contain no embedded blanks

Note that there is a special *CONFIG record shipped in the RXS router control file which contains different valid flag values. See the RXS Router Configuration section for more details.

Control Flag Details

pgm
The pgm flag defines the program to be called. It can either be a valid i5/OS name or a special value. Valid special values are *0-*9. If a special value is used, the corresponding SCRIPT_NAME path segment is used as the program name, where 0 is the RRID itself, 1 is the next segment and so on. For instance, if RXSRTR is called with the following URL:

 http://192.168.0.1/test/john/mike/fred

then TEST will be used as the RRID. If the TEST record in RXSRTRCTL has -pgm *1 specified, then JOHN will be used as the program name, if –pgm *2 is specified, MIKE will be used as the program name and so on.
lib
The lib flag defines the library of the program to be called. If the library is not in the library list, it will be added to the top of the library list. If the lib flag is not specified, *LIBL will be used.
usrprf/passwd
The usrprf and passwd flags define the user profile which the job should use whilst calling the program. If usrprf is specified, passwd must also be specified and vice-versa. If either the specified user profile or password are invalid or if the user profile is disabled, RXSRTR will return an error to the browser and will not call the program.
liblst
The liblst flag defines the library list which should be used for the request. The liblst flag can be specified in one of two ways:
  • liblst library1,library2,library3
  • liblst library/jobd
If a comma-separated list of libraries is specified, they are each added in order to the bottom of the library list. If a qualified job description (*JOBD) is specified, the initial library list (INLLIBL) of the *JOBD is retrieved and the libraries are each added in order to the bottom of the library list. All libraries added as a result of the liblst flag are removed when control is returned from the called program.
cvtopt
See the Conversion Options section for details of how the cvtopt flag should be specified.
response
See the Calling non-CGI programs section for details of how the response flag should be specified.

Example RXSRTRCTL Record

ID DATA
ZAP -pgm zappgm –liblst qgpl/zapjobd –lib qgpl -passwd donald -usrprf goofy


In this case, if the 'ZAP' RRID is used for the request, RXSRTR will change its library list to be the library list held in the QGPL/ZAPJOBD job description. It will then change to run using the GOOFY user profile. Finally, it will call program ZAPPGM in library QGPL.

Control Data Conversion Options

Depending on the value of the cvtopt control flag, RXSRTR may perform certain steps prior to calling the specified program. Some of the conversion options are designed to allow existing CGI programs which expect a particular value for the SCRIPT_NAME or QUERY_STRING environment variables to continue to be called as before, even though you may have changed the calling URL to implement RXSRTR control. Multiple conversion options can be combined in a comma-separated list. Each conversion option will be processed in the order it is found. The following sections describe the conversion options.

rm_sn (Remove RRID from SCRIPT_NAME)

The rm_sn conversion option indicates that if the RRID is included in the URL, it will be removed from the SCRIPT_NAME environment variable prior to the CGI program being called.

If the rm_sn conversion option is specified and the URL used to call RXSRTR is

 http://192.168.0.1/rxsrtr/db2wse/mylib/myfile

then if the CGI program retrieves the SCRIPT_NAME environment variable, it will retrieve a value of

 /db2wse/mylib/myfile

rather than the expected value of

 /rxsrtr/db2wse/mylib/myfile

rm_qs (Remove RRID from QUERY_STRING)

The rm_qs conversion option indicates that if the RRID is included in the URL, it will be removed from the QUERY_STRING environment variable prior to the CGI program being called.

If the rm_qs conversion option is specified and the URL used to call RXSRTR is

 http://192.168.0.1/cust/?fname=john&rxsrtr=mickey&lname=smith

then if the CGI program retrieves the QUERY_STRING environment variable, it will retrieve a value of

 fname=john&lname=smith

rather than the expected value of

 fname=john&rxsrtr=mickey&lname=smith

sn_pr (Parse parameters from SCRIPT_NAME)

The sn_pr conversion option indicates that the program being called will be passed a number of parameters, as specified in the SCRIPT_NAME environment variable, where every path segment after the RRID will be treated as a separate character parameter.

If the URL used to call RXSRTR is:

 http://192.168.0.1/zap/mickey/mouse

and the ZAP control record has the following value:

 -pgm zappgm –lib qgpl -cvtopt sn_pr

then RXSRTR will call program QGPL/ZAPPGM as follows:

 CALL PGM(QGPL/ZAPPGM) PARM('MICKEY' 'MOUSE')

All parameters passed to the specified program will be passed as string pointers. In RPG, this means that they should be defined as follows:

 D ZAPPGM          PR                  Extpgm('ZAPPGM')
 D   fname                         *   Const Options(*String)
 D   lname                         *   Const Options(*String)

Calling non-CGI programs using RXS Router

CGI programs work by writing their output (typically the HTML for a web page) to 'standard output'. When the CGI program ends and control is returned to the HTTP server, the standard output is sent to the browser, displaying as a web page. However, if you use the HTTP server to call a non-CGI 'application' program, because it doesn't write to standard output, an HTTP 500 error page will appear.

However, RXSRTR allows you to call a non-CGI application program, with the following limitations:

  • The program must be a batch (non-interactive) program
  • A maximum of 10 parameters can be passed to the program
  • All parameters must be defined in the program as character strings with a maximum length of 256 bytes

If you wish to pass parameters to the program, you must specify the sn_pr conversion option, which will pass each of the SCRIPT_NAME path segments following the RRID as a character parameter. See the Conversion Options section for details on how to specify this conversion option and the calling URL. When calling a non-CGI program, you must configure RXSRTR to send a response to the browser as an ad-hoc web-page, by specifying the response flag. It can be specified in one of the following two ways:

 -response *confirm

or

 -response *msg

After RXSRTR has called the program, it checks the value of the response flag. If -response *confirm is specified in the control record, RXSRTR will send a generic "Program called successfully" message to the browser. If -response *msg is specified, RXSRTR will retrieve the last message sent to it from the application program and will write it out to the browser.

For instance, if an application program is typically called from a command-line or from a green-screen menu and sends a completion message (e.g. "Audit record created") to the screen, calling this program from RXSRTR and specifying –response *msg in the RXSRTRCTL record will cause this same message to be sent to the browser.

Initializing RXS Router

For performance reasons, when the RXS Router is first called within a job, it reads the records from the RXS Router control file RXSRTRCTL and caches the data into a user space called RXSRTRCTLU, in the same library where the RXS Router itself exists. On subsequent calls within the same job, it uses the cached values, thus eliminating costly file I/O. However, if records in the RXSRTRCTL file are added, deleted or updated, the RXS Router cache must be updated.

A command called INZRXSRTR (Initialize RXS Router) is supplied with the RXS Router. When this command is run from a command line, the RXS Router cache is updated to contain the current values from the RXSRTRCTL file.

This command can also be used to refresh the cached call pointers in Apache CGI jobs. This is useful because normally OS/400 will cache programs for reuse, but when you are doing web service development you will want Apache to pick up the latest version of the program after compiling it. Normally one would have to either recompile the entry level program to clear all cached call pointers or restart Apache. Neither of those options are optimal, so that is why we introduced the INZRXSRTR command to effectively refresh all cached call pointers.

Configuring RXS Router

See RXS Router Configuration.