1 - Introduction
Before OS/400 Release V4R3, CGI programs could only be run as
non-persistent.
A non-persistent CGI program is reloaded at every browser request.
Because of this, there is only one way a non-persistent CGI program
can know the values its variables had when it provided
an html response to a client browser.
This is done by saving variable values in fields of the
output html (usually "hidden" fields in an html form),
so that they are sent back to the program
with the next browser request.
Starting with OS/400 Release V4R3, CGI programs can be run as
persistent.
Persistent CGI is an extension to the CGI interface that allows a CGI
program to remain active across multiple browser requests and
maintain a session with that browser client.
This allows
- the program state to be maintained
- files to be left open
- long running database transactions
to be committed or rolled back on end-user input.
The AS/400 CGI program must be created using a
named activation group
which allows the program to remain active
after returning to the server.
The CGI program notifies the server it wants to remain
persistent using the
"Accept-HTSession"
CGI header as the first header it returns in the output html.
This header defines the session ID associated with this instance of the
CGI program, is taken off from the http server, and is not
returned to the browser.
Subsequent URL requests to this program must contain
the session ID as the first parameter
after the program name.
The server uses this ID to route the request to that specific
instance of the CGI program.
The CGI program should
regenerate this session ID
for each request.
Though not mandatory, it is strongly recommended
that you use the Secure Socket Layer (SSL) for
persistent and secure business transaction processing.
2 - Apache HTTP Directives for persistent CGI programs
There are three Apache HTTP directives for persistent CGI jobs.
- MaxPersistentCGI - Maximum number of persistent CGI jobs
Use this directive to set the
maximum number of persistent CGI jobs
that you want to have active at one time.
The default is 50.
Example
MaxPersistentCGI 10
|
- PersistentCGITimeout -
Default timeout value for persistent CGI jobs
This directive specifies the number of seconds that your server waits for a client response before ending a
persistent CGI session. The CGI program can override the value that you specify on a request-by-request basis.
The default timeout value is 300 seconds.
Example
PersistentCGITimeout 120
|
- MaxPersistentCGITimeout -
Maximum timeout value for persistent CGI jobs
This is the maximum number of seconds that a CGI program can use
when overriding the PersistentCGITimeout directive.
The default timeout value is 1800 seconds.
Example
MaxPersistentCGITimeout 3600
|
Notes on persistent CGI running under Apache
- Persistent CGI running under Apache must use the POST method, not the GET method
- The ScriptAliasMatch directive for executing persistent CGI programs MUST HAVE the following format
ScriptAliasMatch /cgidev2p/(.*) /qsys.lib/cgidev2.lib/$1
The following format WOULD NOT WORK:
ScriptAliasMatch /cgidev2p/(.*).pgm /qsys.lib/cgidev2.lib/$1.pgm
3 - Tips for developing output html skeleton members
(when using Mel's service program technique)
-
Accept-HTSession Header
The first html section issued by your program
should start as follow
<as400>section_name
Accept-HTSession:/%HANDLE%/
Content-type: text/html
<HTML>
|
where
/%HANDLE%/
will be substituted with the "unique session ID"
computed by your program (see the next topic).
The "Accept-HTSession" header will not be sent to the client
browser. It will be detected and taken off by the http server.
The "unique session ID" will be associated with your program
instance, so that the next request from the client browser
mentioning it will cause your program instance be re-activated.
-
HTTimeout Header
This header defines the amount of time, in minutes,
that a CGI program wants to wait for a subsequent request.
If not specified, the value specified on the HTTP
PersistentCGITimeout directive is used.
If specified, it overrides the HTTP
PersistentCGITimeout directive,
but the server will not wait longer than the time specified on the HTTP
MaxPersistentCGITimeout directive.
This allows individual CGI programs to give users more time to
respond to lengthy forms or explanations.
However, it still gives the server ultimate control
over the maximum time to wait.
This header must be preceded by an
Accept-HTSession header;
if not, it is ignored.
If you omit this header, the default time-out value for the
server is used.
-
To enable the client browser to re-activate your program instance,
your html URL link
should be specified in the following way
/path/cgi_name/handle/rest_of_path
where
- path is the path to your CGI persistent program
- cgi_name is the name of your program
followed by .pgm
- handle is the "unique session ID"
you already put in the "Accept-HTSession" header
- rest_of_path is the parameter string
(if any) expected by your program
Examples:
<FORM METHOD="POST" ACTION="/path/mypgm.pgm/
/%HANDLE%/>
<INPUT TYPE="HIDDEN" NAME="action" VALUE="go">
. . .
</FORM>
|
<A HREF="/path/mypgm.pgm//%HANDLE%/?action=go>
. . . </A>
|
4 - Tips for developing persistent CGI RPG programs
- Also a CGI persistent program,
after returning the ouput html to the browser
should return to the server.
This is different from a traditional non CGI program,
where the program sits after an EXFMT instruction.
- do not set on the LR indicator,
when you want the program to remain active
for further requests
- set on the LR indicator
when you want the program be no longer active.
In this case, make sure the browser
receives some html response, otherwise the
end user will wait until a script-timeout is issued
from the http server.
- When receiving control from the http server,
the persistent CGI program should test some variable
of its own to establish the state it was left in.
- Have the program itself regenerating every time a new
session ID
(also called "handle")
to be inserted in two points of the output html:
In building a new session ID, you may use a random number
obtained through Mel's service program
random subprocedure.
- When creating a persistent CGI program,
be sure to specify a
named activation group
in the parameter ACTGRP.
As an example, the name of the activation group could be the
same for all CGIs in an application.
5 - Calling another program from a persistent one
Calling another program from inside a CGI persistent program may have unpredictable results.
The best practice is to perform this "call" through the external HTML.
Example: through some javascript function, or from abutton submitting a <form>.
In this way the HTTP server starts a new request which is then routed to a job different from the one currently running the persistent program.
In this way the persistent program maintains its status.
As soon as the called program returns to its caller, HTTP returns to the last web page where the call was activated.
As an example, see how the Giovanni Perotti's demo (a persistent CGI program, listed in the next topic) performs a call to a non-persistent CGI program,
the one running the Boats Demo.
5 - Sample persistent CGI RPG programs
Mel Rothman's demo |
|
Giovanni Perotti's demo |
---|
What day of the week?
It computes its Session ID ("Handle")
using the getSessionID subprocedure.
|
|
Sample persistent RPG CGI program
It computes its Session ID ("Handle")
just using the random subprocedure.
|
|