# WASD Hypertext Services - Scripting Environment

## 8 - Other Environments

> 8.1 - Java
> 8.1.1 - Requirements
> 8.2 - Perl
> 8.2.1 - Activating Perl
> 8.2.2 - CGI Environment
> 8.2.3 - POSTed Requests
> 8.2.4 - Reducing Latency
> 8.2.4.1 - CGIplus
> 8.2.4.2 - Run-Time Environment
> 8.2.5 - Requirements

[next] [previous] [contents] [full-page]

WASD supports a number of scripting engines.

  Java
  Perl
  PHP
  Python
  Tomcat (Java Server Pages)

Earlier releases of the WASD package included some of these in the basic package. Due to the growing number, greater complexity of the environments, and increasing version dependencies, these environments will be distributed independently of the main WASD package. Current releases may be found at the main WASD download site

> http://wasd.vsm.com.au/wasd/

Pages generated by scripting environments can optionally be cached by the server. For a certain class of script output this can offer reduced response latency and system impact. See 1.3 - Caching Script Output.

###
8.1 - Java

Java classes may be used to perform CGI/CGIplus scripting with WASD. This is not Java Server Pages, Tomcat, or anything of the like. The Java refered to here is a small, self-contained Java environment that may used with WASD "out-of-the-box". All you need is java installed on your VMS system. These may be designed as standard CGI scripts (with the inevitable latency of the class loading) or as CGIplus scripts (with the attendant benefit of lower latency).

Note that Java CGI/CGIplus scripts must always be mapped and executed using the CGIplus path, however some can behave as standard CGI scripts, exiting after responding to the request, while others can persist, responding to multiple requests (3 - CGIplus). The CGIplus path is always necessary as Java does not have direct access to a process' general environment, the traditional way of passing CGI variables, so the WASD implementation uses the CGIplus data stream to provide CGI information.

WASD provides a class to allow a relatively simple interface to the CGI environment for both GET and POST method scripts. This and a collection of demonstration scripts may be found in the HT_ROOT:[SRC.JAVA] directory.

As the Java environment is constantly under development, both as a platform-independent environment and on the VMS platform in particular, it is possible that the latest VMS Java kit may not integrate well with the WASD Java environment. Of course every effort will be made to keep the WASD Java environment current.

###
8.1.1 - Requirements

Ensure the Java class file type is mapped to the Java run-time in the HTTPD$CONFIG configuration file.

      [DclScriptRunTime]
      .CLASS  @CGI-BIN:[000000]JAVA.COM

The following content types are configured, also in HTTPD$CONFIG.

      [AddType]
      .CLASS  application/octet-stream  -  Java class
      .JAVA  text/plain  -  Java source
      .JAR  application/octet-stream  -  Java archive
      .PROPERTIES  text/plain  -  Java properties

Class files should be copied to the [CGI-BIN] directory (where all architecture neutral script files should be located).

###
8.2 - Perl

WASD supports Perl scripting in the CGI, CGIplus and RTE environments. Generally no source changes are required to use standard CGI Perl scripts! Information in this section pertains specifically to VMS Perl 5.6 and following. Earlier versions may have some limitations. VMS Perl 5.6 is a relatively complete Perl implementation and standard distributions contain some VMS-specific functionality. In particular the VMS::DCLsym and VMS::Stdio can make life simpler for the VMS perl developer.

Users of VMS Perl are directed to the "VMS Perl FAQ (Unofficial)" http://w4.lns.cornell.edu/~pvhp/perl/VMS.html, an extensive and detailed resource, and to "Perl on VMS" at http://www.sidhe.org/vmsperl/, providing access to the latest release of Perl for VMS.

> Please Note

> The author is very much the Perl novice and this chapter probably reflects that. Additional material and improved code always gratefully received.

###
8.2.1 - Activating Perl

There are a number of ways to activate a Perl script under VMS. Any of these may be used with the WASD server. If the script file is accessable via the exec or script rules of the HTTPD$MAP configuration file it can be activated by the server. The simplest example is to place the scripts somewhere in the CGI-BIN:[000000] path and execute via /cgi-bin/, although in common with other scripts it may be located anywhere a rule provides a path to access it (1.5 - Script Mapping).

###
Directly

When Perl is available from the command-line, either as a DCLTABLES defined verb, a DCL$PATH available verb, or as a foreign verb. The script (the file containg the Perl source) is provided to the Perl interpreter as a parameter to the Perl verb.

      $ PERL perl-script-file-name

###
DCL Procedure Wrapped

If DCL pre-processing, or some other specific environment needs to be set up, the activation of the Perl script can be placed inside a DCL wrapper procedure. This is often used to allow the transparent activation of Perl scripts via the DCL$PATH mechanism.

      $ PERL = "$PERL_ROOT:[000000]PERL.EXE"
      $ DEFINE /USER PERL_ENV_TABLES CLISYM_GLOBAL,LNM$PROCESS
      $ PERL perl-script-file-name

###
DCL Procedure Embedded

The Perl source is embedded as in-line data within a DCL procedure.

      $ DEFINE /USER PERL_ENV_TABLES CLISYM_GLOBAL,LNM$PROCESS
      $ PERL
      $ DECK /DOLLARS="__END__"
      # start of Perl script
      print "Hello \"$ENV{'WWW_REMOTE_HOST'}\"\n";
      __END__

###
8.2.2 - CGI Environment

Due to changes in environment handling sometime between versions 5.0 and 5.6 it was impossible to access DCL symbols via the %ENV hash, making CGI-based scripts impossible to use under VMS Web servers without modification. Version 5.6 addresses this issue by providing a versatile mechanism for controlling where the environment variables are manipulated. The logical name PERL_ENV_TABLES specifies this location, or if defined as a search list, the locations.

Name | Location
| CRTL_ENV | C run-time environment array (i.e. getenv())
| CLISYM_LOCAL | get DCL symbols, set local | CLISYM_GLOBAL | get DCL symbols, set global | logical name table | any logical name table, including LNM$FILE_DEV

For WASD Perl scripting it is recommended that this be defined as CLISYM_GLOBAL,LNM$PROCESS. The CLISYM_GLOBAL allows access to the CGI variable environment, and LNM$PROCESS to significant logical name definitions for the subprocess (e.g. HTTP$INPUT and callout sequences). This can be done on a system-wide basis (i.e. for all Perl scripting) using

      $ DEFINE /SYSTEM PERL_ENV_TABLES CLISYM_GLOBAL,LNM$PROCESS

during system startup, or by defining a user-mode logical in a DCL procedure wrapper immediately before activating the Perl interpreter (as show in the examples in this section).

> NOTE

> Never substitute the contents of CGI variables directly into the code stream using interpreters that will allows this (e.g. DCL, Perl). You run a very real risk of having unintended content maliciously change the intended function of the code. Always pre-process the content of the variable first, ensuring there has been nothing inserted that could subvert the intended purpose. There are a number of security-related Perl scripting issues. It is suggested the reader consult one of the many Perl-CGI documents/books available.

###
8.2.3 - POSTed Requests

Requests using the POST method contain all the content in the body of the request. In particular, requests generated via HTML <FORM> contructs do not deliver the form data via the request query string, it is provided in a URL-form-encoded body. This requires some explicit processing to recover the form elements. A number of Perl CGI modules exist to ease this chore, including the most popular CGI.pm. All of these should work in the VMS environment, and of course then with WASD.

For POSTed requests it is necessary for the script to have access to the request body. In Unix environments this is available via the <stdin> stream, and under Perl via STDIN, <>, etc. This equates to SYS$INPUT under VMS.

With WASD, when activating the .PL script file directly via a [DclScriptRunTime] entry (i.e. without a DCL procedure wrapper) STDIN is directly available without further issues.

If the script has a DCL wrapper procedure the DCL CLI has control of the SYS$INPUT stream and it becomes necessary to temporarily redirect this for the duration of the script. WASD provides the HTTP$INPUT process-level logical name to identify the script body stream (along with WWW_IN and APACHE$INPUT names for easing script portability). The redirection is simply done, as shown in the following example.

      $ DEFINE /USER PERL_ENV_TABLES CLISYM_GLOBAL,LNM$PROCESS
      $ DEFINE /USER SYS$INPUT HTTP$INPUT
      $ PERL perl-script-file-name

If the script is embedded in a DCL procedure the DCL CLI is using SYS$INPUT to provide the script source to the Perl interpreter and so is completely unavailable for use. The request body is still available to the script however but must be explicitly read from HTTP$INPUT. This example provides the basics.

      $ DEFINE /USER PERL_ENV_TABLES CLISYM_GLOBAL,LNM$PROCESS
      $ PERL
      $ DECK /DOLLARS="__END__"
      # start of Perl script
      print "HTTP method is \"$ENV{'WWW_REQUEST_METHOD'}\"\n";
      # read POSTed body stream
      open (HTTPIN, $ENV{"HTTP\$INPUT"})
         or die "Could not open $ENV{'HTTP\$INPUT'}\n";
      while (<HTTPIN>)
      {
        chop;  # remove trailing newline
        print "<HTTPIN> |$_|\n";
      }
      __END__

###
8.2.4 - Reducing Latency

Perl is an interpreter, meaning scripts are provided and activated as source form, the interpreter processing the program "on-the-fly". Perl actually translates the entire script into an intermediate form before beginning execution. This has the advantage of discovering and reporting syntax errors before beginning any actual processing, and also improves the final run-time performance.

While having Perl an interpreter eases development and portability it does incur a performance penalty, particularly in activation latency, due to both interpreter image activation, and script and associated Perl module preprocessing. With standard CGI, where each request processed is handled as an autonomous activation, this becomes quite noticable and can have significant system impact.

WASD provides two solutions for this and other persistent scripting issues. Both of these require the supplementary Perl package available from the WASD download page. Both are briefly described below.

###
8.2.4.1 - CGIplus

CGIplus substantially eliminates the overhead associated with CGI processing by allowing the subprocess and any associated image/application to continue executing between uses (3 - CGIplus). The good news is, CGIplus is relatively simple to support, even using Perl. The great news is, CGIplus can reduce latency and improve performance by some twenty-fold!!

With CGIplus the Perl script remains active for the life of the subprocess. That is it persists! Read the general philosphy and implementation details in the above reference. Note that it is still substantially CGI! The notable differences are two. CGI variables are obtained by reading a stream, not using the %ENV hash. The end-of-script is indicated by writing a special byte sequence (detected and used by the server). Of course the request body is still available via the usual stream.

Using the basic principles described in the CGIplus Chapter a Perl CGIplus script would be relatively simple to build from scratch. To assist in deploying CGIplus Perl scripting a CGIplus.pm Perl module has been provided as part of the supplementary package.

###
8.2.4.2 - Run-Time Environment

A Run-Time Environment (RTE) is almost identical to CGIplus. It allows an environment to persist between requests, substantially improving response latency and reducing system impact (4 - Run-Time Environments). There is a significant difference between RTE and CGIplus scripts. With CGIplus the script itself persists between uses, retaining all of it's state. With an RTE the script does not persist or retain state, only the RTE itself.

The WASD RTE Perl interpreter contains an embedded Perl engine and an associated Perl module that allows multiple scripts to be activated, preprocessed once and remain loaded read-to-run. This eliminates the overhead associated with activating the interpreter and Perl script with each request. This mechanism parallels the Apache perl_mod module and works on substantially unmodified CGI scripts. The test-bench indicates an improvement of some twenty-five fold!

###
8.2.5 - Requirements

These are the configuration requirements for using the basic CGI Perl.

- HTTPD$CONFIG configuration file.

        [DclScriptRunTime]
        .PL PERL
        .CGI PERL

- The following content types are configured, also in HTTPD$CONFIG.

        [AddType]
        .PL  text/plain  -  Perl source
        .POD  text/plain  -  Perl documentation
        .CGI  text/plain  -  Perl source

[next] [previous] [contents] [full-page]