| | | | Filter Programming Interface PIPE Input Streams | PIPE Output Streams | Filter Environment | Skeleton Filter To code a filter, write a CMS Pipelines stage using REXX. For information on writing CMS Pipelines stages, refer to IBM Pipelines documentation. When defining the content filetype for a filter, a system administrator can identify input arguments. VM:Webgateway passes the input arguments to the filter when it is invoked. VM:Webgateway also defines three input streams and four output streams as shown below: Input Streams Output Streams ------------------ -------------------- +---+ | F | 0 static file ------>| I |-> 0 reformatted file 1 HTTP headers ----->| L |-> 1 HTTP headers 2 Filter variables ->| T |-> 2 server log records | E |-> 3 console messages | R | +---+ Sterling Software, Inc. provides a sample filter, FILTER1 XREXX, which is loaded to the VMRMAINT 192 or 193 minidisk during installation. VM:Webgateway always supplies three input streams to a filter. The filter can read zero or more of the input streams; the streams can be read in any order. VM:Webgateway supplies the following data on the input streams: Stream Number | Contents | | 0 | static file | | 1 | HTTP headers | | 2 | Filter variables | - Input Stream 0Static File
- File the web browser user requested.
VM:Webgateway invokes a filter for this file because the file's content filetype indicates that VM:Webgateway should use a filter. The content filetype also indentifies the filter VM:Webgateway is to invoke. VM:Webgateway places a record in the input stream for each record in the static file. - Input Stream 1HTTP Headers
- The proposed HTTP response headers that VM:Webgateway will send to the web browser for the static file.
VM:Webgateway places one header in each record. The headers are in the format, header: value, for example: Content-Type: text/html - Input Stream 2Filter Variables
- Variables for the filter program.
The filter variables have the same name as CGI variables. However, the contents of a filter variable is based on the static file being filtered, and the contents of a CGI variable is based on the CGI program being served. VM:Webgateway places one filter variable in each record. The filter variables are in the format name value, for example: SERVER_PORT 80 The filter can write up to four output streams. VM:Webgateway requires that the filter write the body of the reformatted file to output stream 0. The filter is not required to write to output stream 1, stream 2, or stream 3. VM:Webgateway ignores any data that is written to subsequent output streams. VM:Webgateway expects the following data in the output streams: Stream Number | Contents | | 0 | reformatted file | | 1 | HTTP headers | | 2 | server log records | | 3 | console messages | - Output Stream 0Reformatted File
- File to send to the web browser; the filter is required to write data to this output stream.
If the content filetype of the file being filtered indicates that VM:Webgateway should translate the reformatted file data, VM:Webgateway appends a CRLF character to the end of each record in this output stream before sending the record to the web browser. - Output Stream 1HTTP Headers
- HTTP response headers for the reformatted version of the file; VM:Webgateway does not require the filter to write data to this output stream.
If the filter does not write the HTTP response headers, VM:Webgateway will send all the HTTP response headers that it supplied in input stream 1. If the filter does write HTTP response headers, it must write all headers to output stream 1 before it writes any data to output stream 0. VM:Webgateway merges the HTTP headers it supplies in input stream 1 with the HTTP headers the filter supplies in output stream 1. As a result, the filter can override the value VM:Webgateway supplies for a HTTP header or suppress an HTTP header that VM:Webgateway supplies. The filter can also add addtional HTTP response headers. Create one record in output stream 1 for each HTTP response header. The headers must be in the format header: value. To override an HTTP header or supply an additional header, write the header and its value to the output stream. To suppress a header, include the header in the output stream but do not include a value for the header. For example, to suppress the Last-Modified header, place the following record in the output stream: Last-Modified: VM:Webgateway always sends its values for the HTTP Date: and Server: headers to the output stream; the filter cannot override or suppress these headers. Also, VM:Webgateway always sends an HTTP Status: header; the filter can override the value of the HTTP Status: header, but cannot suppress this header. - Output Stream 2Server Log Records
- Records to include in the VM:Webgateway server log; VM:Webgateway does not require the filter to write data to this output stream.
If the filter writes log records, it must create one record for each server log record. The server log records can be in any format and can contain any data. The records can contain 1-243 characters. Note: Although VM:Webgateway 3.0 writes server log information to the VM:Webgateway console, be sure to use this output stream specifically for information you want in the server log. Use output stream 3 for messages you want displayed on the VM:Webgateway console. - Output Stream 3Console Messages
- Messages to write to the VM:Webgateway console; VM:Webgateway does not require the filter to write data to this output stream.
If the filter writes messages to the console, it must create one record for each message. The messages can contain 1-123 characters. The messages must be in the following format: nnnns message_text - nnnns
- message number (nnnn) and severity code (s)
- message_text
- text of the message
Messages 0600-0699 in the VMWEBSRV MESSAGES file are reserved for use by site-written programs. VM:Webgateway issues the specified message number substituting the message text you supply. Use a message number based on the type of message you want to display: | Type of Message | Message Number | | Informational | 0600I-0633I | | Warning | 0634W-0666W | | Error | 0677E-0699E | When a system administrator associates a filter with a filetype, the system administrator can specify input arguments that should be passed to the filter. The filter can obtain the input arguments using the REXX PARSE ARG command. A filter can obtain data from the input streams and place data in the output streams using standard PIPE interfaces. Filters run on worker machines. When a file requiring a filter is requested, VM:Webgateway allocates a worker machine and copies the filter program to the worker machine. The filter environment does not support stages, such as REXX, that would require VM:Webgateway to copy other files from the SVM to the worker machine. Because filters are owned by the VM:Webgateway SVM, the worker machine has the permissions and authorizations of the VM:Webgateway SVM. Commands such as the CP LINK and CMS ACCESS execute as if they were executed on the VM:Webgateway SVM. Depending on how the VM:Webgateway system administrator set up the worker, the worker should have either a read/write minidisk or file space available for a filter to use. /* This skeleton code shows how to: */ /* */ /* - Obtain the input arguments */ /* - Obtain data from each input stream */ /* - Place data in each output stream */ /* */ address PIPE /* Write an informational message to the */ /* console indicating the filter is starting.*/ 'SELECT OUTPUT 3' 'OUTPUT 600I Starting the filter.' /* Get the input arguments that a */ /* system administrator specified */ /* for the filter when */ /* defining the content filetype */ /* that static file being filtered uses. */ /* */ parse arg Arg1 RestOfArgs /* */ /* Read the filter variables from input */ /* stream 1 and look for the */ /* SCRIPT_NAME variable that identifies */ /* the static file. Place a line in the */ /* server log indicating the file is */ /* being filtered. */ /* */ /* Also look for the X_TRANSLATE variable */ /* to determine whether VM:Webgateway will */ /* add CRLF characters to the ends of lines */ /* in output stream 0. The filter needs this */ /* information so it can determine the */ /* content length of the reformatted file. */ /* */ /* */ /* Set up to read from input stream 2 */ /* (filter variables) and write to output */ /* stream 2 (server log). */ 'SELECT INPUT 2' /* read from here */ 'SELECT OUTPUT 2' /* write to here */ NameFound = (0=1) TransFound = (0=1) CRLF = 2 /* assume translation */ Do Forever until (NameFound & TransFound) 'PEEKTO filtervar' /* get a var */ if rc <> 0 then Leave /* leave if none*/ /* Get the name and value for a variable */ parse var filtervar Name Value /* If we found SCRIPT_NAME, write the */ /* message to the server log. */ If upper(Name) = 'SCRIPT_NAME' then Do 'OUTPUT' Value 'is being filtered', 'by the' Arg1 'filter.' NameFound = (1=1) End /* If we found X_TRANSLATE and it is */ /* set to NONE, set the CRLF variable to 0,*/ /* so the filter does not account for the */ /* CRLF characters when determining the */ /* content length of the reformatted file. */ If upper(Name) = 'X_TRANSLATE' then Do If Value = 'NONE' then CRLF = 0 TransFound = (1=1) End 'READTO' /* Consume the record so */ /* PEEKTO will give the next*/ /* HTTP header. */ if rc <> 0 then Leave End /* Forever */ /* If we left the loop for a reason other */ /* than one of the following, write an error */ /* message and exit: */ /* */ /* - Both SCRIPT_NAME & X_TRANSLATE found */ /* - EOF condition */ /* */ If (rc <> 0) | (rc <> 12) then Do 'SELECT OUTPUT 3' /* write to here */ 'OUTPUT 677E Error processing the', 'filter variables.' Exit rc End /* Get the records in the static file */ /* to filter into the stem variable */ /* FileRecs. */ /* */ 'CALLPIPE' '*.input.0:' /* stream 0 */ '| STEM FILERECS.' /* to FileRecs. */ /* */ /* Add additional stages if you want */ /* to modify the records before */ /* putting them into the FileRecs. */ /* stem variable. */ /* */ : : Place code here to reformat the : file and store the reformatted file : records into the stem OutputRecs. : /* Determine the content length of the */ /* reformatted file. */ /* */ NewLen = 0 Do i = 1 to OutputRecs.0 NewLen = NewLen + Length(OutputRecs.i) + CRLF End /* Read the HTTP headers from input */ /* stream 1. Look for the Date: header and */ /* use its value on the Expires: header (a */ /* header that VM:Webgateway does not supply).*/ /* */ /* Read from input stream 1 (proposed HTTP */ /* response headers) and write to output */ /* stream 1 (HTTP response headers for the */ /* reformatted file). */ 'SELECT INPUT 1' /* read from here */ 'SELECT OUTPUT 1' /* write to here */ DateFound = (0=1) Do Forever until DateFound 'PEEKTO hdr' /* get a header */ if rc <> 0 then Leave /* leave if none*/ parse var hdr Name ': ' Value /* If this is the Date: header, write an */ /* Expires header. */ If upper(Name) = 'DATE' then Do 'OUTPUT Expires:' Value DateFound = (1=1) End 'READTO' /* Consume the record so */ /* PEEKTO will give the next*/ /* HTTP header. */ if rc <> 0 then Leave End /* Forever */ /* If we left the loop for a reason other */ /* than one of the following, write an error */ /* message and exit: */ /* */ /* - Date: header found */ /* - EOF condition */ /* */ If (rc <> 0) | (rc <> 12) then Do 'SELECT OUTPUT 3' /* write to here */ 'OUTPUT 677E Error processing the', 'HTTP headers.' Exit rc End /* - Override the Content-Type header that */ /* VM:Webgateway supplies */ /* - Write out the Content-Length header with*/ /* the value of the reformatted file */ /* - Suppress the Last-Modified header */ /* */ /* Write out the Content-type header. */ 'OUTPUT Content-Type: text/html' /* Write out the Content-length of the value */ /* of the reformatted file. */ 'OUTPUT Content-Length:' NewLen /* Suppress the Last-Modified header. */ 'OUTPUT Last-Modified:' /* Write the reformatted file to output */ /* stream 0. */ /* */ 'SELECT OUTPUT 0' Do i = 1 to OutputRecs.0 'OUTPUT' OutputRecs.i End Exit 0 |