RXS Router (RXSRTR)

The RXS Router (RXSRTR) is a program included since RPG-XML Suite v2.10+ that runs on the IBM i behind the Apache 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 URLs you use to access your CGI programs (such as user favorites or links from webpages).

RXSRTR enables you to perform the following additional functionality:

  • Route all CGI requests through a single URL format
  • Specify a library list to use when calling programs
  • Swap to a different user profile when calling programs
  • Log all information about the request to an audit log file
  • Call non-CGI programs, passing parameters and receiving responses
  • Specify an activation group allowing files to remain open between calls, while maintaining separation between environments
  • Specify product libraries which will be placed ahead of libraries in the user library list

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.

HTTP Configuration Without RXSRTR

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/MYPGM
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 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.

HTTP Configuration With RXSRTR

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

ScriptAliasMatch ^/(([^/.]+/)*[^/.]+)$ /qsys.lib/RXS.lib/rxsrtr.pgm
  <Directory /qsys.lib/RXS.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 URLs (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.

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
actgrp   Activation group
prdlib   Product library


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 RXS Router Configuration 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, RXS Router 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 Control Data 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.

actgrp

The actgrp flag defines the name of the activation group in which the program specified with the pgm flag will run. This value is ignored unless the program is specified with ACTGRP(*CALLER). If the special value -actgrp *dftactgrp is specified, the value specified for the dftactgrp flag in the *CONFIG record will be used. If the actgrp flag is not specified and the program is defined with ACTGRP(*CALLER), it will run in the same activation group as RXS Router - by default, this is the RXSRTR activation group.

prdlib

The prdlib flag specifies the name of the product library which is added to the library list prior to the program specified in the pgm flag being called. The product library is added above all user libraries, including the current library. This library will be removed after the program is called. If a value is specified for the dftprdlib flag in the *CONFIG record, that library will be overwritten by this value while the program is being called, and will be replaced afterwards.

If the prdlib flag is not specified, but the dftprdlib flag is specified in the *CONFIG record, that product library will be used for the duration of the program call.

If the prdlib flag is not specified and the dftprdlib flag is not specified in the *CONFIG record, no product library will be used for the duration of the program call.

Example RXSRTRCTL Record

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

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

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 Control Data 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.

RXS Router Configuration

Additional RXS Router configuration can be controlled by changing the options in the shipped *CONFIG record in the RXS Router control file RXSRTRCTL. The various control options are as follows:

routingid
Routing identifier
loglvl
Logging level (0, 1, or 2)
allowreset
Allow *RESET option from client (*YES or *NO)
debugmode
Run in debug mode(*YES or *NO)
dftactgrp
Specifies the default activation group for CGI programs
dftliblst
Specifies the default library list for CGI programs
dfterrpgm
Specifies the default error-handling program
dftprdlib
Specifies the default product library to use

The *CONFIG record in the RXSRTRCTL file is shipped as follows:

-routingid rxsrtr -loglvl 0 –allowreset *no –debugmode *no

Control Option: routingid

The routingid flag defines the type of routing that should be performed by RXSRTR. Depending on its value, RXSRTR will use either ‘static’ or ‘dynamic’ routing to determine the value of the request routing identifier (RRID), which actually defines the call definition. If the routingid flag is not specified, a value of ‘RXSRTR’ is assumed.

For more information about how RXS Router retrieves and uses the routingid, see the page Configuring RXS Router.

Control Option: loglvl

The loglvl flag defines the level of logging that will be performed by RXSRTR.

There are three different logging levels available within RXSRTR:

  1. Error – Only errors encountered by RXSRTR during initialization or when processing a request are logged.
  2. Basic – All initialization information is logged, as well as basic information about each request, including user profile swaps, addition of libraries to the library list, routing identifiers used and the SCRIPT_NAME and QUERY_STRING values used for the request
  3. Full – Complete information about each request is logged, including parameter values and response data (where appropriate)

All log entries are written to the RXSRTRLOG file, which contains a 1024-byte free-format field called DATA. Each log record consists of the following:

Start position
in DATA field
 
Length of data
 
Data
1   1   Log level (‘0’, ‘1’, or ‘2’) of log entry
3   26   Qualified HTTP server job name
30   26   Log entry timestamp
57   967   Log entry data


If logging level 1 is specified, all logging at level 0 is also included. If logging level 2 is specified, all logging at logging level 0 and logging level 1 is also included.

If the loglvl flag is not specified or is set to a value other than 0, 1 or 2, logging level 0 is assumed.

Control Option: allowreset

If the allowreset flag is set to *YES, a user can reset the RXS Router from the browser by specifying a value of ‘*RESET’ in the URL (e.g. ‘http://192.168.0.1/rxsrtr/*reset’). This will cause the RXS Router to reload all control records from the RXSRTRCTL file. It is recommended that a value of *YES is specified only if the RXS Router is being used on a development machine, since there is no checking to ensure which client used the reset option.

If the allowreset flag is not specified or is set to a value other than *YES, a value of *NO is assumed.

Control Option: debugmode

If the debugmode flag is set to *YES, RXSRTR will run in debug mode. In this mode, instead of calling the specified program, RXSRTR will return a page displaying details of the program which would be called, as well as any the values of the QUERY_STRING and SCRIPT_NAME environment variables (if they have been changed due to any conversion options specified with the cvtopt flag).

If the debugmode flag is not specified or is set to a value other than *YES, a value of *NO is assumed.

Control Option: dftactgrp

If the dftactgrp flag is specified, all programs called by RXS Router which are compiled with ACTGRP(*CALLER) will run using the specified activation group (unless the actgrp flag is specified in the RRID record for the program being called, in which case that value will be used instead).

If the dftactgrp flag is not specified, all programs called by RXS Router which are compiled with ACTGRP(*CALLER) will run in the same activation group as RXS Router - by default this activation group is called RXSRTR.

All programs called by RXS Router which are compiled with ACTGRP(*NEW) or ACTGRP(named-activation-group)) will run in the specified activation group.

Control Option: dftliblst

If the dftliblst flag is specified, the defined library list or list of libraries will be used for all CGI program calls. If a qualified job description is specified, e.g. -dftliblst qgpl/jobd, the initial library list (INLLIBL) for that job description is used. If a comma-separated list of libraries is specified, e.g.: -dftliblst qgpl,prdlib,dtalib, each library is added to the end of the existing library list in order. If a comma-separated list of libraries is specified, there must be no spaces between each library and each comma. No validation is performed when this flag is specified to check whether the job description or libraries exist, but runtime errors will occur.

If the dftliblst flag is not specified, CGI program calls will use the default library list defined for the HTTP server (although see also the dftprdlib flag, which can alter the library list for CGI program calls).

Control Option: dfterrpgm

If the dfterrpgm flag is specified, the specified error-handling program will be called if the RXS Router encounters an error either when calling a specified program or during other processing.

See the RXS Router user manual for details of the interface to the error handler and an example error handler.

If the dfterrpgm flag is not specified, no default error handling program will be used.

Control Option: dftprdlib

If the dftprdlib flag is specified, the specified product library will be added to the library list when the RXS Router is called and is removed when the RXS Router returns control to the HTTP server. The product library is added above all user libraries, including the current library.

If a value is specified for the prdlib flag in a user (non-*CONFIG) control record, this library will be overwritten by that value while the program is being called, and will be replaced afterwards.

If the dftprdlib flag is not specified, no default product library will be used.