Version 158 of TclHttpd

Updated 2011-10-05 16:59:23 by SEH

TclHttpd is a tcl based web server. The author is Brent Welch. It currently resides at sourceForge [L1 ], which also hosts its modestly active mailing list [L2 ].

 What: Tcl Httpd server
 Where: http://tclhttpd.sf.net/ 
 Description: A Tcl http web server.  Works out of the box as a web server,
        but is designed to be a Tcl application server.  
        Supports distributing HTML plus Tcl templates.
        Currently at 3.5.1.
 Updated: 05/2004
 Contact: See web site

More than a web server, TclHttpd is a platform for building Tcl applications with an HTTP interface to them. It so happens that it runs as a standalone web server "out of the box", but it is designed with extensibility in mind. You can find distributions at [L3 ] or [L4 ]. Included in the distribution is a copy of a book chapter (from 3rd edition of Practical Programming in Tcl and Tk) that describes the features of the server [L5 ].


New Release:

The 3.5.1 release (05/2004) fixes many bugs, adds new features and includes a Starkit distribution and a bundle distribution (batteries included.)

It can be found here:

CVS Snapshots: A nightly snapshot of tclhttpd CVS source is available as a tar.bz2 here: [L6 ] and in ZIP form here: [L7 ]. If you find a bug, it might be worth checking one of these out in case it's been fixed.

[NOTE: If the above URLs do not work, try using tclhttpd.cvs.sourceforge.net - sf.net sometimes changes their naming conventions]


Tclhttpd Pages:

Tclhttpd - Getting Started how to begin to use Tclhttpd

Tclhttpd Domains lists the kinds of 'domains' Tclhttpd supports.

Tclhttpd Examples for worked examples, gems, mini-applications using Tclhttpd.

TclHttpd Templates for hints and tips about the tclhttpd .tml template system.

TclHttpd: The .tml File explains the use of /.tml files

TclHttpd Needs for projects and flights of fancy about what would improve the already amazing TclHttpd.

TclHttpd Applications for testimonials and descriptions of applications built around Tclhttpd.

Tclhttpd Hints and Tips for questions, problems, etc.

Tclhttpd as a Unix service, Tclhttpd as a Windows service and Tclhttpd as a starkit show how to deploy Tclhttpd.

Starting Tclhttpd in a slave interpreter discusses embedding Tclhttpd into other applications, web-enabling them.

Starting Problems for specific problems starting tclhttpd

minimal tclhttpd discusses techniques for cutting down Tclhttpd to bare bones. There's also a 250-line form of Tclhttpd called mini [L8 ].

Mini-Tutorial: Content type and file extension - Tclhttpd and content type

aku's Low-level documentation (written in doctools) for httpd.tcl, the protocol engine.

Other macro processing s/w can be found under Template And Macro Processing.


When trying to run Tclhttpd under Windows XP I get the following error, no matter if I use the Starkit or the normal distribution:

    could't open "/tmp/tclhttpd.default": no such file or directory

WJR A quick fix is to create a tmp folder on the root of the drive where TclHttpd is installed (e.g. c:\tmp). This is a bug, on Windows tclhttpd.default should probably be put into the Windows equivalent (e.g. c:\temp).

I reported the bug.

CMcC This bug has been fixed for months, as noted in the sf bug report.

WJR Are you referring to bug ID 1030323? This problem still occurs in 3.5.1. Should I try the CVS version?

CMcC definitely ... there's a nightly snapshot at the top of this page.

Peter Newman 17 December 2004: This bug may have been removed (from the CVS) months ago, but it's still in the latest downloadable versions (source and tclkit, at least). And affects Windows 98SE (and presumably every other version of Windows,) too. It generates a fatal error, thus preventing the latest downloadable versions of TclHttpd from even starting (under Windows).

But you can easily fix it by making the changes shown on the sourceforge CVS in:-

 tclhttpd/lib/auth.tcl
     Revision 1.21
     Diff to previous 1.20
 and;
     Revision 1.20
     Diff to previous 1.19

The easiest way to do this to to just download Revision 1.21, and replace your existing auth.tcl with it.


dzach 2006-9-1 I can't get a .tml file to render a utf-8 page right using the Doc_Dynamic method of tclhttpd. The HTML part of the following test-utf8.tml file is valid XHTML, validated with the W3C validator:

 [Doc_Dynamic]
 <?xml version="1.0" encoding="UTF-8"?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
 <head>
   <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
   <title>utf-8 test</title>
 </head>
 <body xml:lang="el" lang="el">
 <p>
        Good morning in Greek:<br/>
        καλημέρα!<br/>
 <br/>
        Internationa Phonetic Association (IPA) phonetics<br/>
        language    'læŋgwidʒ
 </p>
 </body>
 </html>

When this template is served by tclhttpd, the greek and IPA parts appear garbage in the browser. If I take out the Doc_Dynamic line, and therefore allow tclhttpd to cache the html page, the browser shows the non ASCII portions correctly.

More to that: if I do an encoding convertto utf-8 with the page content, I get the correct display. So obviously, a conversion to utf-8 has to be made somewhere, before the result is sent to the client, when using the Doc_Dynamic template technics. I am looking for an answer in the code, but if anyone knows better...

(A day later) If my observations of the problem are correct and not a result of my particular tcl setup, it seems that the issue might be in the processing done in the slave interpreter. The place where the processed template is returned is the end of the TemplateInstantiate proc. By converting the contents to utf-8, my problem seems to be solved (not fully tested it though).

Look for the code:

    set dynamic [interp eval $interp {uplevel #0 {set page(dynamic)}}]
    if {!$dynamic} {

        # Cache the result

        catch {file delete -force $htmlfile}
        if {[catch {open  $htmlfile w} out]} {
            set dynamic 1
            Log $sock "Template" "no write permission"
        } else {
            puts -nonewline $out $html
            close $out
        }
    }
    return $html
 }

Substitute the return command with:

 #
 # return $html
 #
   return [encoding convertto utf-8 $html]
 }

This of course is a hack, and it propably works only for utf-8, but not for the numerous 8-bit encodings supported either by tcl or the browser. Anyway, in the absense of a proper solution, it may be useful to someone else too. Has anyone else been able to duplicate the problem with the test-utf8.tml given above?


User contributions


As one wag put it, "tclhttpd is the best tcl 7.4 app in existence."


a tclhttpd scripted document


RLH 2006-11-26: Is there any thought in seeing how the stuff coming in 8.5 can make TclHttpd better/faster?

This code continues to be updated, but the people on the maintenance team just haven't put together a recent "release" on the project page.

RLH How would one become one of the maintenance team or is that possible?

LV visit http://tclhttpd.sf.net/ , get the emails of the current maintainers, and email them, volunteering.


ARR 2007-06-23: There seems to be an authentication problem with IE7 on WinXP: I cannot login as webmaster with the pwd shown in console. I investigated and found changed behaviour in 'proc Digest_Get' in file 'digest.tcl'. Authentication data comes with no spaces to separate the entries and spaced \"values\", so I added one line just after 'upvar #0 Httpd$sock data':

   regsub -all {,} [subst -nocommands $parts] {, } parts

This seems to fix the problem. Anybody has seen this before? Can somebody add to CVS? I have no developer access yet.

RLH You can submit a bug report with the fix.


RLH 2007-06-23: On another note...I know that Wub is in the same league and the Wub developer was on the TclHttpd project as well. Is Wub going to supercede TclHttpd? Are patches and releases still going to be made for TclHttpd or should we look to Wub now?


MHo 2008-11-29: Here's one nasty thing I cannot track down:

I wrote the Tclhttpd Winservice. The starpack VFS contains an additional httproot. Here is the response of fetching http://localhost:8015/adminroot/images/ :

 Up to parent directory
 Blue.gif              35 bytes  Dec  1, 1999 08:40:28
 lake.gif           32588 bytes  Oct  7, 1998 03:11:52
 lake.map             192 bytes  Dec  1, 1999 08:40:28
 logo125.gif         1762 bytes  Nov 29, 1999 02:06:30
 ppt1.gif            2850 bytes  Oct  7, 1998 03:11:54
 ppt2.gif            3236 bytes  Oct  7, 1998 03:11:54
 ppt3.gif            3627 bytes  Oct  7, 1998 03:11:54
 ppt4.gif            3691 bytes  Oct  7, 1998 03:11:54
 ppt5.gif            2196 bytes  Oct  7, 1998 03:11:54
 pwrdLogo75.gif      1171 bytes  Oct  7, 1998 03:11:54
 pwrdLogo100.gif     1615 bytes  Oct  7, 1998 03:11:54
 pwrdLogo150.gif     2489 bytes  Oct  7, 1998 03:11:54
 pwrdLogo175.gif     2981 bytes  Oct  7, 1998 03:11:54
 pwrdLogo200.gif     3491 bytes  Oct  7, 1998 03:11:54
 Red.gif               35 bytes  Dec  1, 1999 08:40:28
 setup.gif           2360 bytes  Oct  7, 1998 03:11:56
 Space.gif             49 bytes  May 10, 2000 04:10:44
 tcl89.gif          16604 bytes  Nov 29, 1999 02:06:30
 tclp.gif            1294 bytes  Apr 19, 2000 03:02:40
 TclPro200.gif       4384 bytes  Nov 29, 1999 02:06:30

If I now try to fetch a single gif from that directory, some work and some don't! As far as I see, these don't work:

  • Blue.gif
  • ppt5.gif
  • Red.gif
  • setup.gif
  • Space.gif

The browser don't get the results back. I added some debugging statements within the tclhttpd-code here and there and noticed the following:

Sometimes, the proc HttpdCopyDone within httpd.tcl never gets triggered. That means, fcopy started from within Httpd_ReturnFile but never comes to an end...

That does not happen if the same files are requested from a httproot outside the VFS, so I think it must have something to do with the VFS layer... The error occurs with the 8.4.19 as well as with the 8.5.5 runtime... CAN SOMEONE HELP PLEASE?

George Peter Staplin Nov 29, 2008 - That sounds like it might be an fcopy bug. It could also be a socket issue. Are you by chance using the Windows socket layer? iocpsock is known to fix some issues that occur with the WinSock layer, by using a different Windows API. I personally think Microsoft may have left the WinSock layer a little broken, in order to break compatibility with the BSD socket layer that WinSock provides. Tcl is still using the WinSock layer. MHo: Yes, I did nothing special, so I'm using WinSock... addition: Just tested with Iocpsock 3.0. The behaviour is the same, so it likely has to do with fcopy or another fact I hadn't discovered yet...


stevel Dec 18, 2008 - A change in Safari's handling of cookies in MacOS X 10.5.6 / Safari 3.2.1 has broken Tclhttpd's cookie support. The problem is that Safari (unlike Firefox and IE) no longer trims trailing spaces in the cookie value, so a cookie like

    'mycookie=7721ab4ee9b3e95f4693940334493aa8 ; path=/ ; expires=Monday, 17-Dec-2018 16:00:00 GMT ;' 

has its value set to "7721ab4ee9b3e95f4693940334493aa8 " (note trailing space).

The workaround is to modify the tclhttpd/lib/httpd.tcl:Httpd_SetCookie proc to strip the space before the cookie is sent to the browser:

    proc Httpd_SetCookie {sock cookie {modify 0}} {
        upvar #0 Httpd$sock data 
        lappend data(set-cookie) [string map {{ ; } ";"} $cookie]     ;# changed
    }

This is the same problem that David Zolli reported as affecting tcllib::ncgi.to the MACTCL list (he provides a workaround for ncgi::setCookie in his posting).


nb Dec 18, 2008 - While on this, the following was needed in tcllib::ncgi module for GET/POST queries to work on FF 3.x

proc ::ncgi::nvlist {} {

    set query [query]
    set type  [type]
    #Quick hack by nikos to overcome Mozilla 3.x which appends charset=xxx to env(CONTENT_TYPE)
    # returning a list, e.g. application/x-www-form-urlencoded; charset=UTF-8
      if {[string match "*;" [lindex $query 0]]} {
        # set type "application/x-www-form-urlencoded"
        set type "[lindex $query 0]"
        set type "[lindex [split $type ";"] 0]"
        } else {
        }
    #end nikos
    switch -glob -- $type {
        "" -
        text/xml* -
        application/x-www-form-urlencoded* -
        application/x-www-urlencoded* {
            set result {}

I'm sure there's prolly a cleaner way to do it though...


RLH 2011-08-30 : Has anyone done a minimal setup? Meaning, taking out all the examples and "cruft" and just starting with a barebones TclHttpd?

The project files contain minihttpd.tcl, an httpd server in less than 300 lines of code. RLH -- Is that just the httpd server? I am talking about talking all the example code/sites out and when you start it just gives you a default "tclhttpd is running" page and you would create your app/apps from there.


Detailed instructions for enabling ssl for tclhttpd (doc file): [L9 ] Also see openssl for brief notes on same.

The notes at the openssl page didn't work for me, so here's a procedure extracted from the doc file linked above:

 0. create directories demoCA/newcerts and demoCA/private.
    Create a blank file demoCA/index.txt and a file demoCA/serial containing '01'
       touch demoCA/index.txt
       echo 01 > demoCA/serial

 1(a). generate a private key for your test CA
     openssl genrsa -out demoCA/private/cakey.pem

  1(b). build a certificate request
     openssl req -x509 -nodes -out demoCA/cacert.pem -key demoCA/private/cakey.pem -new

  You've now got a CA certificate "cacert.pem".
  It's "self-signed".
  Its private key is "private/cakey.pem".

 We'll now make a server key, certificate request,
 and we'll use the CA cert we just made to sign it
 and generate our final certificate.

 2. generate a server key
   openssl genrsa -out key1.pem

 3. generate a certificate request
   openssl req -nodes -out req.pem -key key1.pem -new

 4. generate the server certificate
   openssl ca -keyfile demoCA/private/cakey.pem -cert demoCA/cacert.pem -in req.pem

 Because I didn't use "-out", the cert was generated into
 demoCA/newcerts as 01.pem

 You've now got a server certificate "demoCA/newcerts/01.pem".
 Its private key is key1.pem.
 It's signed by your own CA.

 To set up tclhttpd, copy the key and the cert into the
 tclhttpd/certs subdirectory.  E.g., 
    mkdir certs
    cp key1.pem certs/skey.pem
    cp demoCA/newcerts/01.pem certs/server.pem