mod_tcl | Apache Web Server Module |
|
Latest Info mod_tcl not developed and supported anymore
We are sorry but we discontinued mod_tcl support and development for lack of resources.
Also the discussion mailing list was closed, so if you're interested in taking up this subproject within the Apache Tcl
project to bring it back into life please contact private@tcl.apache.org
Tested Platforms SunOS-5.8/gcc-3.0.2/tcl-8.3.4/Apache-2.0.28 SunOS-5.8/gcc-3.0.4/tcl-8.4b1/Apache-2.0.39 SunOS-5.9/gcc-3.1.1/tcl-8.4b1/Apache-2.0.40 SunOS-5.9/gcc-3.1.1/tcl-8.4.0/Apache-2.0.40 Technical related email can be sent to mod_tcl-dev@tcl.apache.org (including bugs). If your running mod_tcl on another platform besides Solaris with no problems send in an email and it will be added to the Tested Platforms list. |
|
mod_tcl includes a Tcl interpreter into an Apache web servers memory space, thus combining Tcl and Apache web server together. This allows Apache to run Tcl scripts natively without having to reload a Tcl interpreter every time the script is run. The Tcl scripts are cached in the Tcl interpreter until the script file modification time changes or Apache web server is restarted. Tcl scripts using mod_tcl execute much faster than traditional CGI scripts because they can avoid the initialization penalties that traditional CGI scripts incur each time they are executed. mod_tcl only needs to initialize an interpreter once at Apache web server startup. Additionally mod_tcl exports the Apache API which allows a programmer to have complete control over http requests that CGI scripts can not provide.
mod_tcl is an Apache module in its own right, but it can also be used as an interface for writing Apache modules in Tcl versus C. Existing Tcl packages whether written in C or Tcl can be easily integrated into mod_tcl scripts. This allows a large collection of existing Tcl packages to be used without having to rewrite functionality or incur a performance hit by using an alternative execution model like CGI.
Building and Installing Apache with mod_tcl
mod_tcl is configured using the Apache 2.0 configuration system. Normally a vanilla install of Apache doesnt require a rebuild of the configuration system, but since mod_tcl requires libraries not usually built into Apache it is necessary to rebuild the configure script using GNU autoconf. If the GNU autoconf tools are not installed on the system then they can be downloaded from a GNU distribution site, for more information check the GNU autoconf website http://www.gnu.org/software/autoconf/. Please note that GNU autoconf also requires a recent release of an m4 macro processor which can also be found at a GNU distribution site. The next step is to download the mod_tcl source from the Apache Tcl project web site at http://tcl.apache.org or from directly from Subversion (SVN). The following SVN commands will checkout the mod_tcl source from svn.apache.org, no sandbox is required as this will download all the source to the mod_tcl directory.
$ svn co http://svn.apache.org/repos/asf/tcl/modtcl/trunk mod_tclTo get the tagged version 1.0.1, please check out
$ svn co http://svn.apache.org/repos/asf/tcl/modtcl/tags/1.0.1 mod_tcl-1.0.1If mod_tcl is downloaded from the Apache Tcl project web site then the package must be un-archived and moved to the Apache 2.0 modules directory. If SVN is used the directory must named mod_tcl and moved to the Apache 2.0 modules directory. It is important to note that the directory that contains the mod_tcl source must be named mod_tcl otherwise the Apache configuration system will not recognize mod_tcl. The following example assumes the Apache 2.0 source distribution is located in the same directory where the mod_tcl source was acquired through SVN.
$ mv mod_tcl-1.0.1 httpd-2.0.42/modules/mod_tcl
Now the Apache configuration system is ready to be rebuilt and include mod_tcl. Change directory to the root level of the Apache 2.0 source and rebuild the configuration system.
$ cd httpd-2.0.42 $ autoconf $ autoheader
Running the configure script with the help flag will show that mod_tcl configuration macros have been assimilated into the Apache configuration system.
$ ./configure --help | grep tcl --disable-tcl embedded tcl interpreter --with-tcldir=DIR Tcl config tclConfig.sh
mod_tcl is enabled by default once the Apache configuration has been rebuilt. If it is necessary to disable mod_tcl then this may be accomplished with the --disable-tcl option passed to the configure script.
The --with-tcldir=DIR will specify a non-default location to find the tclConfig.sh file, usually located in the tcl directory in a library location. (ie /usr/local/lib/tcl8.4).
The next step is to configure the Apache build process by running the configure script. During configuration we will see status output, the mod_tcl configuration status output will look similar to the following.
checking whether to enable mod_tcl... yes (default) checking for tcl.h... yes checking for inttypes.h... yes checking for int_types.h... no checking for sys/mman.h... (cached) yes checking for asprintf... no checking for mmap... (cached) yes checking for tclConfig.sh in /usr/local/lib... yes checking for tcl version... 8.3
If the tcl.h header file was not found extra include paths may be required when compiling Apache 2.0, or a Tcl distribution may not be installed on the system. If Tcl is not installed on the system it can be downloaded from http://www.tcl.tk. Configuration will fail if the tclConfig.sh file is not found or the major Tcl version installed is less than 8.0. It is recommended that the latest Tcl version be used, note for 64-bit support Tcl 8.4 is required. If Tcl is installed and configuration was unable to find the tclConfig.sh file then the --with-tcldir=DIR configuration option should be used to help configuration locate the tclConfig.sh file. By default mod_tcl configuration assumes the tclConfig.sh will be found in the directories /usr/lib or /usr/local/lib.
Additional modifications to configuration can be made in the config.m4 file found in the mod_tcl directory. If any modifications have been made to the config.m4 file then autoconf and autoheader will have to be run again.
After configuration has completed the Apache web server can be compiled. Change directory to the root level of the Apache 2.0 source distribution and execute the following commands.
$ make $ make install
This will compile Apache 2.0 with mod_tcl and install the distribution in the location specified at configuration time. The Apache 2.0 binary will contain a statically linked mod_tcl module which may also statically link Tcl libraries depending on your Tcl installation.
Configuring mod_tcl in Apache Configure Files
In order to use mod_tcl in Apache 2.0 some mod_tcl configuration directives are required in the Apache 2.0 configuration file, usually called httpd.conf. mod_tcl is made active by activating one of the module hook calls. There are ten hook calls in total corresponding to the available hook calls in the Apache API. All hooks require an argument of the entire physical path to the file that contains the hook procedure except the content handler hook called Tcl_Hook_Handler. Every hook does require an argument specifying the name of the procedure to be called. mod_tcl configuration directives are valid within Apache <Directory> </Directory> or <Location> </Location> blocks.
|
Chances are the Tcl_Hook_Handler configuration directive will be the most commonly one used. This is the handler that actually delivers the content and does most of the work. This handler also does not require a file name argument passed to it, this is because many different script files may contain individual content handlers. If the other phases of request processing were allowed to operate this way the request process would be much more complex, and mixing different file types with mod_tcl scripts would be impossible.
In addition to the hook directives there are also configuration directives for pre setting variables in scripts. The Tcl_Var directive is used when we want to set scalar variables or array variables. Tcl_ListVar is used to create a list.
<Directory /> Tcl_Var my_number 7 Tcl_Var my_array my_value1 10 Tcl_Var my_array my_value2 20 Tcl_ListVar my_list 1 Tcl_ListVar my_list 2 Tcl_ListVar my_list 3 </Directory>
In the above example my_number is a scalar variable with value 7, my_array is an associative array with 2 elements, and my_list is a list with value {1,2,3}. Variables set from the configuration file are automatically set in the calling scripts namespace, so the Tcl keyword variable will be required when using these variables. These variables are only initialized once in a files namespace. If code within one of the handlers is called and modifies the variables then they will be permanently modified until Apache is restarted. Variables will remain persistent in the Tcl interpreter even if a script is reloaded because it was modified. The following example demonstrates a simple configuration setup for using mod_tcl in a virtual host directive.
<VirtualHost 127.0.0.1> ServerName any.host DocumentRoot "/any.host" <Directory /> Options FollowSymLinks AllowOverride None </Directory> <Directory /any.host> # allow files ending with the extenstion .tm to use mod_tcl as a content handler AddHandler tcl-handler tm Tcl_Hook_Handler content_handler </Directory> </VirtualHost>
This configuration example will allow any mixed files in the /any.host directory and will execute any script with a filename ending in .tm to be executed by mod_tcl. This allows us to mix html and mod_tcl scripts together in the same directory.
Once configuration is set up we are ready to start writing the actual mod_tcl script that will contain the necessary handlers. Using the previous configuration example we will assume that we are going to write a mod_tcl script called hello.tm in the /any.host directory.
namespace import -force ::apache::* proc content_handler { } { variable ::apache::OK ap_send_http_header rputs hello world. return $OK }
When this script is run it will print hello world in the clients browser. There are several items to pay attention to in this script. One the first line is a namespace import of everything in the ::apache namespace into the current namespace. This allows us to use the Apache API functions (ie. rputs) without having to prefix ::apache::. It is not necessary to import the Apache API like this but it will make it easier if the Apache API is referenced frequently. Even if the Apache API is imported it is still necessary to declare variables in procedures from other namespaces (ie. ::apache::OK). The ap_send_http_header function will send http headers to the client browser, even if we dont define any headers Apache will send default headers. The rputs command operates almost identically to the Tcl command puts, instead of writing to a file descriptor rputs writes to the clients browser. rputs can not write to different file descriptors. After every handler is run it must return with a value that signifies the outcome of the request phase. The seven most common return values are: OK, DECLINED, DONE, HTTP_INTERNAL_SERVER_ERROR, HTTP_BAD_REQUEST, HTTP_MOVED_TEMPORARILY, and HTTP_NOT_FOUND.
Now that we understand the basics of writing a mod_tcl script we can take the next step and explore the Apache API in mod_tcl. All Apache API functions are implemented using the Tcl_CreateObjCommand() Tcl API function, this is why Tcl 8.0 is required. Using Tcl objects instead of strings increases the efficiency of the request phases. The Apache API implementation in mod_tcl can be broken done as follows. All Apache API procedures are declared in the ::apache namespace.
|
There are also some utility procedures defined for interacting with large output, reading POST requests, and reading and setting variables in Apache request_rec structures. The first utility function is abort. The abort procedure accepts a string argument which will be displayed in the error message, abort returns nothing and will immediately abort processing of the handler and return a HTTP_INTERNAL_SERVER_ERROR. The read_post procedure will read POST requests, it accepts no arguments and returns nothing. read_post will set an array named pram in the local namespace with all the read data from the POST. There is also a special procedure called output which helps write large amounts of data to a client. The output procedure essentially calls rputs for each line, multiple lines must be contained within curly braces (like this: output {
}). The next two procedures read and write variables to the request_rec structure in the Apache API. To read request_rec variables we use the command r, to set request_rec variables we use the command r_set. All variables are readable but not all variables are writable.
|
The following script will illustrate portions of mod_tcl that will be most commonly used.
proc content_handler { } { variable pram variable env variable ::apache::OK variable ::apache::M_POST if { [r method_number] == $M_POST } { read_post } r_set content_type "text/html" ap_create_environment set env_list [array names env] set prm_list [array names pram] ap_send_http_header rputs "<HR><B>Environment</B><BR><BR>" foreach i $env_list { rputs "$i=$env($i)<BR>" } rputs "<HR><B>Posted Variables</B><BR><BR>" foreach i $prm_list { rputs "$i=$pram($i)<BR>" } rputs "<HR>" output { <CENTER> <FORM METHOD=POST ACTION=[r uri]> <INPUT TYPE=text NAME=user_input> <INPUT TYPE=submit> </FORM> <BR> [ap_get_server_version], [ap_get_server_built] </CENTER> } return $OK }
Looking at this script we see that the [r method_number] function is useful in determining the type of request being processed. M_POST is an Apache API constant that specifies a request as an http POST request type. There are several other request types defined in the Apache API also, the other most useful one is probably M_GET. If the request processed in the above script is a POST then we make a call to read_post to parse the POST data and store the results in the array pram. Next we initialize the environment with a call to [ap_create_environment], this will set up the env array with environment variables. Notice that Apache will add environment variables that correspond to CGI parameters, this is useful for emulating CGI functionality and allows porting of CGI scripts to be more flexible. The content_handler in the above script will essentially print environment variables and any pram variables that were set from a POST request. The remainder of the script uses the provided output procedure to send a block of HTML to the client, notice that procedure calls in output will work as expected.
mod_tcl is part of the Tcl Apache Project located at http://tcl.apache.org. Information about the Tcl Apache Project and other Apache modules using Tcl can be found here. Information on general Tcl topics and development is located at http://www.tcl.tk.