Using the Perl relay with the VisualWorks Application Server
(c) 2006-2007 Cincom Systems, Inc.
Last updated, April 2, 2007 by M. D. Roberts
This directory includes a Perl gateway that enables web servers such as IIS or Apache to pass HTTP requests to a VisualWorks server. It can be run as a CGI script, forking a process for each request. In this it is roughly equivalent to the compiled C CGI for the VisualWorks Application Server, and is likely to be slower, but easier to configure and debug. The Perl gatway can also be run using mod_perl and Apache to run directly inside the Apache process space. In this configuration it may actually be significantly faster than the compiled CGI, depending on server configuration and load.
Note that this gateway differs from the others in that it reads neither the .INI file for configuration or the hostmap file. Since the script is a plain text file, the relevant parameters are embedded directly into the script.
Contents of this Readme:
* Using the Perl Gateway as a CGI with Apache
* Configuring Apache to pass the HTTP Authentication headers to a CGI script
* Using the Perl Gateway with mod_perl and Apache
* Using the Perl Gateway with IIS
* Compiling the Perl script into C
* Support for Chunked-Transfer Encoding
Using the Perl Gateway as a CGI with Apache
--------------------
To use this as a CGI, the easiest way is to refer to it directly in the URL, e.g.:
http://host/cgi-bin/visualworks.pl/your/path/to/file.ssp
This will then serve the Smalltalk Server Page indicated by the path your/path/to/file.ssp.
You can also map all requests within a particular location to use the gateway file. For example, if you used the location "smalltalk", URLs of the form:
http://host/smalltalk/your/path/to/file.ssp
would serve the Smalltalk Server Page indicated by the path your/path/to/file.ssp. For example, if visualworks.pl is in /var/www/cgi-bin/visualworks.pl, use the ScriptAlias directive to indicate that visualworks.pl is a script to be executed:
ScriptAlias /smalltalk /var/www/cgi-bin/visualworks.pl
Configuring Apache to pass the HTTP Authentication headers to a CGI script
--------------------
By default, Apache mod_cgi will not pass HTTP Authentication headers to cgi scripts. In order to enable this behavior, you need to use mod_rewrite to manually copy these headers into the request's environment so they are passed to the scripts.
Method 1: Using .htaccess
Create a file named .htaccess in your cgi-bin directory which contains the cgi script, in this example visualworks.pl. This file should contain:
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [E=HTTP_AUTHORIZATION:%1]
Method 2: Using the server's httpd.conf
You can use the same directives as above in the httpd.conf (or Vhosts.conf) file. Simply locate the section for the directory that contains the visualworks.pl file and insert the same directives into that section.
Using the Perl Gateway with mod_perl and Apache
--------------------
There are many ways to configure apache so that the Perl Gateway runs with mod_perl. We will cover a basic configuration here.
Many installations use two daemons, httpd and httpd-perl. The latter is basically the httpd binary that is statically linked with libperl.so. The majority of package-based installations are of this type.
Supposing that the server's data files are located in /var/www, there is typically a directory /var/www/perl that contains perl scripts. In the main server config file (httpd.conf), all requests for either http://server/perl/script.pl or http://server/cgi-perl/script.pl are passed to the httpd-perl daemon (typically running on port 8200). The configuration for this daemon (httpd-perl.conf) will set up aliases for the /perl and /cgi-perl locations, both pointing to the /var/www/perl directory.
The problem with this configuration is it assumes that the scripts will not be called using path arguments (e.g., http://server/perl/script.pl/arg/subarg). Since this is a requirement for our script, we need to enhance the default configuration just a bit.
Assuming the following
Perl Gateway location: /var/www/perl/visualworks.pl
Desired query URL: http://server/myscript/info.ssp
we would use the following configuration (to be placed in the Vhosts.conf file):
#Enable mod_rewrite
RewriteEngine on
#For queries sent to the httpd server, pass to httpd-perl server
RewriteRule ^(/myscript.*)$ http://%{HTTP_HOST}:8200$1 [P]
#Configuration used by httpd-perl server
# Configure /myscript to represent the Perl Gateway
Alias /myscript /var/www/perl/visualworks.pl
# mod_cgi will not pass the HTTP Authorization header
# in the environment. This can be fixed by tailoring
# the Perl Gateway to use more Apache::Registry behavior.
# As a quick fix, one that can be used for all CGI scripts,
# we do the following:
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [E=HTTP_AUTHORIZATION:%1]
# Finally, configure the Perl Gateway to run under
# Apache::Registry
SetHandler perl-script
PerlHandler Apache::Registry
PerlSendHeader On
This configuration will also work on a server that dynamically loads mod_perl. In this case, the ... section is not used and may be deleted from the configuration file.
For more help on configuring mod_perl, refer to http://perl.apache.org/docs.
Using the Perl Gateway with IIS
--------------------
The Perl gateway may be used with Microsoft's IIS server, but there are some restrictions. In particular, there seem to be some bugs (see below) in the IIS interface that do not have current workarounds and which prevent using the VisualWorks CGI or Perl Gateway successfully with wildcard mapping behind a virtual directory. Since the preferred executable is an ISAPI Extension (such as the VisualWorks ISAPI Gateway), and the configuration mechanisms are well documented and robust, we strongly recommend this approach when using IIS as your Web Server.
Under IIS, the basic setup of the Perl gateway is as follows:
The naming convensions for the script file "visualworks.pl" are: "host@port.pl" or "anyname.pl". The script file must be located on the same physical drive as the IIS installation, or in a physical or virtual directory accessible to IIS. The host/port configuration may also be explicitly coded in the script file.
When configuring IIS, you have two general options. You can either (a) simply copy the Perl gateway from the VisualWorks installation to the appropriate IIS directory, renaming it as necessary, or (b) use a virtual directory. The former is very easy to set up, but offers only limited control over the appearance of the URL. The latter is more complicated to configure, but offers greater control over the URL space.
If you choose first approach (i.e., the 'host@port' naming convention), these URL patterns work for IIS 5.0, 5.1 & IIS 6.0:
Home directory default:
http://host/scripts/localhost@2226.pl
Website index.ssp file default:
http://host/scripts/localhost@2226.pl/index.ssp
When using servlets, you can access this URL pattern works for IIS 5.0, 5.1 & IIS 6.0:
http://host/scripts/perl2vw.pl/servlet/Redirect?url=../index.ssp
The following discussion explains how to configure and use a VisualWorks Gateway with an IIS virtual directory, and identifies the known points of failure. In general, the following approaches all work with IIS 5.0, but with IIS 5.1 and IIS 6.0
there are some problems, as documented below.
Using a virtual directory ("named virtual host" in Apache) to host your web site files can eliminate the physical name and location of the VisualWorks Gateway executable file from your URLs. This approach uses the application mapping mechanisms of the web server to forward a request to an executable file. IIS can map certain file types to an executable file or use wildcard mapping to send all requests using a specific virtual directory to an executable file.
The virtual directory, as a URL path component, must be known both to the Web Server and to the VisualWorks Application Server so that the Application Server understands how to resolve and serve the incoming request. A virtual directory on the Web Server can represent a specific WebSite (of the same name) in the VisualWorks Application Server, and requests using that virtual directory are managed by the Smalltalk HttpApplication specific to the individual WebSite. Otherwise, if requests do not need individual handling and the default WebSite can serve a request from any virtual directory, you can inform the Application Server about the virtual directory names by providing them to the Server when you create it (using the Server Console).
To map all files in a virtual directory, open the IIS configuration tool, and get the properties for the desired directory (creating it first, if necessary). From the "Virtual Directory" tab, press the "Configuration" button. This takes you to a dialog which includes Application Mappings. Use this dialog to map the wildcard extension "*" to the perl script, e.g.:
c:\perl\bin\perl.exe c:\inetpub\scripts\visualworks.pl
If the physical location of the /scripts directory is C:\Inetpub\Scripts, you may also use the following wildcard mappings:
TestCGI [mapped to -- C:\Inetpub\Scripts\cgi2vw.exe]
TestISAPI [mapped to -- C:\Inetpub\Scripts\isapi2vw.dll]
TestISAPIDebug [mapped to -- C:\Inetpub\Scripts\isapi2vw-debug.dll]
TestPERL [mapped to -- C:\perl\bin\perl.exe "C:\Inetpub\Scripts\perl2vw.pl"]
Case is not important in naming the virtual directory to IIS.
Set Execute permissions to "Scripts and Executables".
When defining the IIS virtual directory, set a wildcard application mapping to redirect every request to the respective executable as follows:
For IIS 5.0, 5.1, select 'Properties', press the 'Configuration' button and 'Add' an Application Mapping with :
Executable = Fully qualified physical location of the gateway executable
including, in the case of the Perl Gateway, the .pl script
file as a command line argument
Extension = * [IIS 5.0] or .* [IIS 5.1]
For IIS 6.0, use the "Wildcard application maps" list.
De-Select both checkboxes ('Script Engine' and 'Check that file exists').
For IIS 6.0, you will also need to add a "Web Services Extension" entry which references all the VisualWorks Gateway executable files. If you need to enable the Perl Gateway, you will need to add the Perl executable file to your Web Services Extension. Perl can be executed with one of 3 command line formats, and you will need to add each one that you expect to use:
C:\Perl\bin\perl.exe
C:\Perl\bin\perl.exe "%s"
C:\Perl\bin\perl.exe "%s" %s
Be sure to enclose the first replacable parameter in double quotes in case the fully qualified path of the script file contains special characters.
You may also need to add the following to the MIME types for Default Web Site so IIS runs a Perl script rather than trying to download the file:
.pl application/octet-stream
The configurations described above work for IIS 5.0, 5.1 & IIS 6.0, with the following exceptions:
[1] When using IIS 5.1 and the CGI or Perl Gateway, the virtual directory does not appear to work unless the request is for what IIS perceives as a reference to a file, even though it might not actually exist. If the request is for a Servlet, or no file is specified (e.g., the home directory default) IIS returns a Server Error (500). This seems to be a bug in IIS.
[2] When using IIS 6.0 and the Perl Gateway, the wildcard mapped virtual directory does not appear to work at all. This is most likely some additional permission or configuration that is missing, since the documentation specifically indicates this form should work, and IIS 6.0 does work correctly for the CGI Gateway (cgi2vw.exe) mapped behind a virtual directory. There does not seem to be a way to create a wildcard application mapping for perl.exe with a Perl script parameter (namely visualworks.pl) on the command line. With or without an explicit file in the path, IIS returns a Not Found error : 404.2 - Lockdown Policy Prevents This Request.
Release version (home directory default) [1][2]
http://host/TestPERL
Release version (with Servlet) [1][2]
http://host/TestPERL/servlet/Redirect?url=../index.ssp
Release version (with explicit index.ssp file) [2]
http://host/TestPERL/index.ssp
In the VisualWorks IDE, open the VisualWave Server console (by clicking on the globe icon in the Launcher toolbar, or selecting Web -> Server Console from the Launcher's menu bar). Then, select our IPWebListener (see the Web Server Configuration Guide for full documentation on how to create an IPWebListener), and select "Edit Server". In the "Virtual Directories" box, add the name of our virtual directory (e.g. "smalltalk").
If we create the virtual directory "smalltalk" and map it this way (described above), then URLs of the form:
http://host/smalltalk/your/path/to/file.ssp
would result in serving the Smalltalk Server Page indicated by the path your/path/to/file.ssp.
To map only some of the files, we open the IIS application mapping tool as above, but map only those extensions required. e.g. we could map ".ssp" to the script. This can be done within a virtual directory, or for all files with that particular extension served from the web site. If we map all files from the IIS web site, then it's not necessary to add a virtual directory within the VisualWorks IDE.
Compiling the Perl script into C
--------------------
It is also possible to compile the perl script to an executable, using the Perl-to-C compiler. This would result in some speed improvement, and also make it possible to use the gateway as a direct URL within IIS. However, this option would not allow the use of mod_perl under Apache, and so would probably have slower performance there.
Support for Chunked-Transfer Encoding
--------------------
With VisualWorks 7.5, the Perl gateway supports HTTP requests that are sent in "chunked transfer encoding", i.e., without specified Content-Length. This can happen when the body of the request is large or compressed, e.g. when sending a large file attachment with the request. Also as of VisualWorks 7.5 the HttpClient will send any request that exceeds a configurable limit (8K by default) in chunked transfer encoding.
Apache 2.0 can handle "chunked transfer encoding" and the Perl script works with that. However Apache 2.0 seems unable to handle "zipped transfer encoding" whether chunked or not.
IIS doesn't seem to pass chunked requests throught the CGI interface at all. Non-chunked requests, which do specify full Content-Length should work.
An older version of the VisualWorks Perl relay which does not support chunked transfer encoding may be found in: /obsolete/waveserver/waverelays/perl