|
Written by Wojciech Kocjan
|
Many people already know that there is a wonderful web server written in pure Tcl called TclHttpd. It can be used to serve both files on your storage and be used as part of your server application to offer Web based user interface or offer WebServices. In this article we'll learn how to add Tcl to your application in less than 5 minutes.
Using a web server in your application has many benefits - you can use http or even SOAP as way to do client-server communication. You can add a web interface so that you have basic control over the application. Or simply do a web based application. In all cases, TclHttpd works just fine and might only need a few tweaks.
For this exercise we'll need tcllib and TclHttpd. Tcllib is pure Tcl so downloading a zip or tar.gz file should be enough. For Tclhttpd, please make sure to download the TclHttpd package instead of the TclHttpd bundle one.
Now, let's create a directory called mywebapp.vfs that we'll use to put all required files in. Also, create a subdirectory mywebapp.vfs/lib and copy the following:
- tcllib/base64 directory as mywebapp.vfs/lib/base64
- tcllib/cmdline directory as mywebapp.vfs/lib/cmdline
- tcllib/fileutil directory as mywebapp.vfs/lib/fileutil
- tcllib/log directory as mywebapp.vfs/lib/log
- tcllib/md5 directory as mywebapp.vfs/lib/md5
- tcllib/ncgi directory as mywebapp.vfs/lib/ncgi
- tcllib/uri directory as mywebapp.vfs/lib/uri
- tclhttpd/lib directory as mywebapp.vfs/lib/tclhttpd
- tclhttpd/lib/mime.types file as mywebapp.vfs/mime.types
That should cover all the libraries. Now let's create the main script that will initialize TclHttpd - mywebapp.vfs/main.tcl - let's begin with initialization of the packages:
Starkit and package initialization # initialize Starkit - if you're not using starkits/starpacks,
# the following two lines are not needed
package require starkit
starkit::startup
# required parts of the configuration
set ::Config(Auth) {}
set ::Config(docroot) [file join [file dirname [info script]] WWW]
# load all TclHttpd and related packages
package require md5 2
package require ncgi
package require httpd 1.6
package require httpd::version
package require httpd::utils
package require httpd::url
package require httpd::counter
package require httpd::doc
package require httpd::cgi
package require httpd::direct
package require httpd::redirect
package require httpd::mtype
package require httpd::auth
We now need to mimic part of Thread support and logging mechanisms. If you need threads or logging, you will need to tweak this part a bit. Merging the Log procedure with your logging might be the best way to proceed.
Mimic part of Thread and logging functionality proc ::Thread_Enabled {args} {return 0}
proc ::Thread_Respond {args} {return 0}
proc ::Log {sock reason args} {}
Finally, we need to read MIME types, initialize Httpd itself, file storage and create dummy handlers for all web pages:
Reading MIME definitions Mtype_ReadTypes [file join [file dirname [info script]] mime.types]
Httpd_Init
DirList_IndexFile "index.html"
Counter_Init 60
Doc_AddRoot / $::Config(docroot)
Doc_Root $::Config(docroot)
Url_PrefixInstall /debug ::dummyDebug
Url_PrefixInstall / ::dummyDebug
proc ::dummyDebug {sock suffix} {
Httpd_ReturnData $sock text/plain " "
}
And that concludes basic TclHttpd initialization. What remains now is to write some URL prefix handlers and set up http server.
Let's create a simple handler for /clock to return current date and time:
Handler that returns current time and date Url_PrefixInstall /clock showClock
proc showClock {sock suffix} {
Httpd_ReturnData $sock text/plain \
[clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S"]
}
Last, but not least, we also need to make TclHttpd actually listen on a port and enter the event loop. For the TCP port, let's choose 12345:
Start http server and enter event loop Httpd_Server 12345
vwait forever
Now, after wrapping it or after sourcing mywebapp.vfs/main.tcl, you should be able to navigate to
http://localhost:12345/clock and see current date and time.
Please note that if you want to use SSL, you'll probably need to initialize Tls package and make sure you can load it from your application.
In next article we'll cover a bit more complex issues like handling cookies, sessions and handling templates. |