2002.09_Advanced Web Applications with Tclhttpd.pdf

(882 KB) Pobierz
Layout 1
PROGRAMMING
Tclhttpd
Delivery Service
A number of techniques are now
Programmed in Tcl,the Tclhttpd web server is an ideal platform for advanced
available for web applications in
Tcl. In addition to CGI scripts, Tcl
modules for Apache or fully featured
application servers, you might like to take
a look at Tclhttpd. The webserver is a 100
per cent Tcl code development with a
long history, and this is reflected in the
current version. The Tcl webserver’s
functions provide an ideal platform for
advanced web applications. This article
demonstrates various approaches for the
creation of HTML pages and also in the
processing of requests.
Tclhttpd’s origins go back to 175 lines
of Tcl that Brent Welch wrote in the mid
90s. The codebase has grown since to
encompass something in the region of
12,000 lines, and this does not include
the extensive Tcllib library. This stable
codebase supports speedy deployment in
various areas. Tclhttpd can:
• Serve static web sites
• Run Server Side Includes
• Link individual URLs, even whole
directories, or various MIME types with
Tcl scripts
• Embed Tcl code in HTML
• Read and write cookies
• Manage sessions
• Authenticate users
• Evaluate forms
• Upload files to servers
• Support email
The development activities were never
intended to rival the king of the hill,
Apache. If you are having to contend with
several hundred requests per second, Tcl
modules such as mod_tcl [5] or
mod_websh [6] for Apache are definitely
a better bet. But if you are looking to
develop web applications for small to
medium volume web sites, Tclhttpd will
provide you with a solid base from which
you can work.
web applications thatcan also profitfrom the ease and speed of development
thatTcl offers.Tcl library functions and numerous extensions are available
including a library thattakes the hard work outof generating HTML code.
BY CARSTEN ZERBST
of traffic. Other reference applications
include a global network for meteorologi-
cal data from airports or the Medusa
Project [4] that accesses a large-scale
database. But if you talk to the users, you
will normally find that Tcl has mainly
been used for internal projects.
Sourceforge has the Tclhttpd source
files [1]. There are two versions: the all-
inclusive variant tclhttpd-3.2-dist
including Tcl, Thread and Tcllib [3] and
the current version tclhttpd-3.3.1 . The
older package’s advantage is ease of
installation. The following steps are all
that you need to do to get a web server up
and running:
Suitable for
projects of all sizes
But Tclhttpd does not need to hide its
light under a bushel – after all it does
host http://www.tcl.tk and this website
has to cope with a considerable volume
# tar -xzf tclhttpd3.2-dist.tarU
.gz
# cd tclhttpd3.2-dist/tclhttpd3U
.2
# make
# make install
# cd bin
60
September 2002 www.linux-magazine.com
Web applications with the Tcl web server
593536479.013.png 593536479.014.png
Tclhttpd
PROGRAMMING
# wish httpd.tcl
Running with 256 file U
descriptor limit
httpd started on port 8015
# Do not create threads
Config threads 0
Config main [file join U
[Config home] httpdthread.tcl]
The Direct_Url /listing2 .html listing2
command assigns the URL http:// local-
host:8015/listing2.html to the listing2
procedure. The Tcl procedure creates and
returns the required page. The variables
available in the script, for example env ,
are interesting, as they are being used to
store information on the current client
connection. The html::tableFromArray
command formats the content of the
global variable producing the result
shown in Figure 1.
Just launch your browser and point it at
http://localhost:8015 to view the sample
files that show you some of the package’s
capabilities. You can configure the server
via the tclhttpd .rc file; the following is a
listing that contains an example of some
of the options available.
# Logfile: /usr/local/httpd/log
Config LogFile /usr/local/U
httpd/log
Config LogFlushMinutes 0
When you start out on a development
project, it makes sense to use the content
in the sample directory, to leverage the
control panel and statistics features. The
control panel reads variables from
browsers or reloads the libraries, and
both these functions are very useful for
when it comes to debugging.
Tclhttpd can create web page content
dynamically at runtime and it supports
various approaches to do so. The easiest
way to go is to configure a Direct_Url :
The server will then pass requests for the
URL to the configured Tcl procedure. In
contrast to a CGI script the server will not
spawn a new process but it will run the
procedure directly in its own server
process. This allows you to use variables
from the server for counters or to open
database connections.
# Sample configuration
# httpd running as user 500
# in group 100
Config uid 500
Config gid 100
Direct_Url /listing2.html U
listing2
proc listing2 {args} {
puts stderr $args
# httpd listening on port 8015,U
normal hostname
Config host [info hostname]
Config port 8015
set html "<html>"
append html "<body>"
append html [html::tableFromU
Array ::env "border=1" *]
append html "</body>U
</html>"
return $html
# Custom scripts in
# .../custom directory
Config library [file join U
[Config home] .. custom]
}
# HTML files in
# /usr/local/httpd/htdocs
Config docRoot /usr/local/U
httpd/htdocs
The script must be stored in the contrib
directory in order for the server to find it.
Tclhttpd reads all the scripts in this direc-
tory automatically at startup.
During the development phase the lib
directory is also useful. Scripts stored in
this directory still need to be loaded
explicitly in the main script, but this
allows you to reload them later from the
control panel with the Reload Source
function, which provides a facility for
on the fly code modification. If an error
is discovered in a script the Tclhttpd
displays the debugging information
directly as an HTML page for easy
viewing.
DirectUrl Dynamics
The next listing shows a simple example.
Figure 1:The procedure detailed in Listing†2 outputs the contentof the global Tcl variable ::env .The vari-
able contains entries thatyou should recognize from CGI scripts,such as HTTP_USER_AGENT .
ElegantTemplates
Templates are a more elegant solution
than using Direct Url and comprise an
HTML document with embedded Tcl
code. The Tcl elements are encapsulated
in brackets – the return value of the func-
tion that immediately precedes the
closing bracket is passed to the HTML
page. You can use the value of the vari-
able in the whole template and not only
in the Tcl elements.
If you want to work with templates,
you will need to place a copy of the .tml
file and the libtml directory taken from
www.linux-magazine.com September 2002
61
593536479.015.png 593536479.016.png 593536479.001.png
PROGRAMMING
Tclhttpd
the distribution in the htdocs directory.
The sample template in the next listing
first defines a variable, that contains the
value of the env in HTML code. Lower
down in the template, the content is then
integrated into the page using $later . The
last section of the template contains the
date of the last modification. We can see
that a template can therefore encompass
a varying mixture of scripts, variables
and HTML.
Tclhttpd automatically updates the
saved version if the template is newer
than the saved results, or if the browser
calls the template directly. As you can see
in the following listing, the [Doc_ U
Dynamic] can be used to suppress the
caching functionality.
Templates provide an easy migration
path that you can use to gradually
upgrade static web sites with dynamic
functions. In addition to simple counters,
navigation toolbars would be obvious
candidates, since a single procedure
could create them for the whole site.
htdocs/libtml/sunscript.tcl contains a
sample of source code from the former
Sunscript page.
set message "no project U
selected"
}
]
<hr>
$message
<form action=$page(url) U
method=POST>
Text: <input type=text
[html::formValue text]> <br>
Project: [html::radioSet U
project { } {
"Project 1" project1
"Project 2" project2
}] <p>
<input value="Send" U
type=submit>
</form> <p>
<html>
<head> <title> SimpleU
Template</title> </head>
<body>
A simple template.
[ set later "watch this"
html::tableFromArray U
::env "border=1" *
Interactive Templates
Web pages with user input are the next
hurdle for a web application to overcome.
The interactions of this kind basically
comprise of two elements: an HTML page
provides the user interface in the browser
and a script running on the server that
evaluates the input. It makes sense for a
template to create the form and evaluate
it, allowing the template in turn to return
a modified version of the formula in case
of input errors. In case of valid input, the
template would then transfer the browser
to a different page.
Input was:
[html::tableFromList U
[ncgi::nvlist] "border=1"]
</body>
</html>
]
<p>
$later
<hr>
Last change
[clock format [file mtime U
$::env(PATH_TRANSLATED)]]
</body>
</html>
The sample script in the listing above
shows how a template can edit a form.
Although the template is short, it pro-
vides heaps of functionality. First the
[Doc _Dynamic] command prevents the
form from caching the template, which
would make no sense at all.
The next Tcl block handles the data
input using a few functions from the Ncgi
package in Tcllib. For example,
ncgi::empty checks whether an entry for
the project field in the form exists. In this
case the request is passed via Doc_Redi-
Templates use the .tml file suffix and are
stored just like normal HTML documents
in htdocs. When a browser requests the
listing3.html, the server first actions the
listing3.tml template and then returns the
result. Tclhttpd addtionally writes the
result to listing3.html on the hard disk
and uses it for any further requests. This
kind of caching is particularly practical
for templates that either perform some
complex calculations or contain slow
database queries.
<html>
<head> <title>Entries<U
/title></head>
<body>
[Doc_Dynamic]
[ if {![ncgi::empty U
project] } {
Doc_Redirect [ncgi::valueU
project].html?[ncgi::query]
} else {
TABLE 1: INSTRUCTIONS FOR HTML AND CGI
Instruction
Meaning
HTML
html::h1 Title
Produces a heading,also "html::h2" and "html::h3"
html::tableFromArray ArrayName
Produces a HTML table from a Tcl array
html::checkbox Name Value
Produces a Checkbox
html::trxtInputName Parameter
Produces a textinput
Ncgi
ncgi::cookie Cookie Returns a listof values for Cookie
ncgi::setCookie - name Name -Value Value Sets a Cookie
ncgi::empty Name
Indicates whether an inputvalue is present
Figure 2:Mozilla displaying the contentof a cookie
thatoriginated in the template of the “cookie”list-
ing above.The cookie was setby the server at
192.168.42.150 ,is called test and contains the value 42 .
ncgi::value Key
Returns the CGI value identified by Key
ncgi::nvlist
Returns all the query as a name,value list
ncgi::query
Returns the raw query data
62
September 2002 www.linux-magazine.com
593536479.002.png 593536479.003.png 593536479.004.png 593536479.005.png
Tclhttpd
PROGRAMMING
Figure 3:The googbar looks like the Google home page,butin factitis a Tcl
program thatredirects search operations directly to Google.
Figure 5: dndspy (bottom) shows the MIME types and actions allowed with drag
objects.Grabbing a message (flying page) from Evolution (top).
Figure 4:The BWidgets demo application shows the capabilities of this
toolkit.The widgets are written in Tcl and only use Tk.
Data crumbs
Having to retype
data is clumsy, and
not all browsers
can or want to
store user input.
Although it is easy
to store data on the
server, it is by no means trivial to assign it
to a specific user. HTTP is stateless and
requests are normally independent of any
previous requests.
Cookies provide a solution to this
known problem: The server asks the
browser to store some data (a cookie) on
the client. If the user revisits the site, and
has not deleted the cookie meanwhile,
the server can read the cookie it asked the
browser to store.
The template in the next listing first
checks the browser for the answer cookie.
If the cookie exists, it outputs the value, if
not, the template attempts to write a
cookie. Apart from the server that sets the
cookie values the browser itself can also
read the cookie, as you can see in Figure
2. Cookies can often be troublesome,
especially from a legal point of view (data
protection and so on); they also pose a
security risk. You will want to try to avoid
using them as a building block of your
application logic.
if {[string length U
[Doc_Cookie answer]] > 0} {
set html "Cookie answer is U
[Doc_Cookie answer]"
} else {
Doc_SetCookie -name answer U
-value 42 -path $page(url)
set html "Set Cookie U
answer=42"
}]
</body>
</html>
rect to the HTML page for this project. If
this does not occur, a message is then
stored in the variable message and it is
written to the page by $message, which is
the message construct.
The middle section inside the template
contains a simple form, whose input can
be returned to the template by the use of
HTTP-POST . The form contains a text
input box and radio buttons, which have
been assigned to project1 and project2 ,
and are labeled Project 1 and Project 2 . At
the end of the script the user input is for-
matted. This is then output so that it can
be used for debugging purposes.
When a user first opens the listing4.html
page, no project has been selected. In this
case clicking on the Send button will
return the user to the same page. Any
entries in the text boxes are retained due
to html::formValue text . Users must first
select a project before the input validity
check can redirect them to another page.
The Html and Ncgi packages comprise
solutions for numerous tasks that involve
formulae and their evaluation. Table 1
contains some practical functions. The
complete documentation for the packages
is available in Tcllib[3].
Login for Web Applications
Although open networks are a good
thing, you might need to implement
access restrictions for part of your web
site. In addition to the .htaccess files you
will be familiar with from Apache,
Tclhttpd supports authentication by a Tcl
procedure. A file called .tclaccess , which
is stored in the individual directories,
takes care of this. You need to set the
variables realm and callback here.
set realm "tickle"
set callback aok?
proc aok? {sock realm user U
password} {
if {[string match $password U
tickle]} {
return 1
} else {
return 0
<html> <head> <title>U
Cookie</title> </head>
<body> <h1>Cookie</h1>
[ Doc_Dynamic
}
}
www.linux-magazine.com September 2002
63
593536479.006.png 593536479.007.png 593536479.008.png 593536479.009.png 593536479.010.png
PROGRAMMING
Tclhttpd
Figure 6:Toucan a GUI developer interface for Palm programs.The IDE and any software created with it
are based on Tcl.
additionally show you how to upload files
and use image maps. You can obtain
additional information, which is available
from [2]. Amongst the other interesting
snippets, you will note an excerpt from a
book by Brent Welch, Tclhttpd’s author.
Sourceforge also offers a mailing list that
provides competent answers to complex
issues, but still finds time to deal with
beginners’ questions.
In some cases you may not need to go
to all the trouble of developing a new
application yourself. The Infocetera[12]
site provides a complete Groupware
application, including a calendar, address
book, room planner, task planner, and
other modules. The whole application is
based on Tclhttpd.
Our next informative TCL article will
soon be appearing on your pages of Linux
Magazine from out of the murky depths
of server applications. We will be looking
into both Tk and the BWidget set. The
image in Figure 4 should serve to whet
your appetite for this widget. It provides
capable new widgets by using only the Tk
standard widgets and pure Tcl code.
The callback variable contains the
name of the Tcl procedure responsible for
authentication. The browser displays the
content of realm as a text during the login
dialog. This data is also passed as an
argument to the callback procedure. Our
example accepts users that supply the
password tickle . A real application would
access a user password entry in a file,
database or LDAP directory. After logging
in the user name is stored in the
::env(REMOTE_USER) variable.
Sessions are a more advanced variant.
Here, Tclhttpd uses its own interpreter for
the individual sessions. This provides for
data separation between the sessions,
and so retaining the data for each of the
individual sessions.
INFO
[1] Tclhttpd home page: http://sourceforge. U
net/projects/tclhttpd/
[2] Informationen on Tclhttpd: http://www. U
tcl.tk/software/tclhttpd/
[3] Home pages for Tcllib and BWidgets:
http://sourceforge.net/projects/tcllib/
[4] Medusa project: http://ciheam.maich. U
gr/medusa/
[5] Tcl Apache module: http://tcl.apache. U
org/mod_tcl/mod_tcl.html
[6] Websh: http://websh.com
[7] Googbar: http://www.geddy.hpg.ig.com. U
br/software/googbar/
[8] Toucan: http://home.attbi.com/ U
~maccody/
[9] Ora Tcl: http://oratcl.sourceforge.net
[10] Tcl XML: http://tclxml.sourceforge.net
[11] Tk DND: http://www.iit.demokritos.gr/ U
~petasis/
[12] Infocetera: http://www.infocetera.com
More Info
The capabilities described in this article
cover only a small portion of this web
server’s total functionality. The sample
files bundled with the Tclhttpd package
Tcl News
Nextrelease anticipated
Tcl 8.4 will be leaving beta in the Autumn.Although I have notnoticed any errors for a long time
now,the Tcl coreteam prefers to waitand deliver an absolutely perfectversion.A whole bunch of
new applications in and for Tcl are available rightnow.The BWidgets and additional GUI elements
such as Tree and Combobox – which will be featured in the nextissue of TCL – are now available in
version 1.4 [3].The demo in Figure 4 mightwhetyour appetite.
Ora Tcl and Tcl XML
There is also news on these two packages which were covered in our lastTCL article:The latestver-
sion of the Ora Tcl[9] database extensions supports the full range of Oracle 9i features and the Tcl
XML package on Sourceforge[10] now comprises xmlgen,providing a new approach to generating
XML and HTML.xmlgen provides a language map between Tcl and XML:Instead of using elements
and attributes,you can now work on a higher level with application objects.
Lots of Little Tools
Apartfrom all these server oriented treats there is news on several smaller tools.Toucan,a devel-
oper interface for Palm programs[8] requires only a minimal hardware platform.Both the
developer interface and any applications developed with itare based on Tcl (Figure 6).The Googbar
(Figure 3),which can launch Google searches[7] has an extremely small memory footprint.Tkdnd,a
drag & drop extension for Tk[11] needs even less space on screen.Itruns on the XDND protocol used
by Gnome and KDE applications and also on Windows. dndspy (Figure 5) is also included.This pro-
gram shows data traffic in the DND protocol
Carsten Zerbst
works for Atlantec
on the PDM ship
building system.He
is also interested in
Tcl/Tk usage and
applications.
64
September 2002 www.linux-magazine.com
593536479.011.png 593536479.012.png
Zgłoś jeśli naruszono regulamin