tclhttpd Examples

This page will try to collect code examples to ease the beginners to fully exploit one of Tcl's pearls, TclHTTPD, a pure-Tcl HTTPD server. Long code snippets should probably get their own pages.


Created a drop-in module for tclhttpd session templates -- CMcC

The tclhttpd Indirect domain combines Doc and Direct domains. (For a concrete example Hosting mailman with tclhttpd)


A tclhttpd XML server based on Sleepycat's dbxml library


Added to link to all Cookies related pages.


Setting a Cookie

To set a cookie, first use Doc_SetCookie. The following is an example of a function setting a cookie:

  Direct_Url /login login
  proc login { {username none} {password none} } {

    set expire [clock format [clock scan {+1 hour}] \
                -format "%A, %d-%b-%Y %H:%M:%S GMT" -gmt 1]

    Doc_SetCookie -name username -value $username -expires $expire \
                  -path {/} -domain {yourdomain.com}  

    # Just output parameters; for debugging
    set html [html::head "Login" ]
    append html "Username: $username <BR>\n"
    append html "Password: $password <BR>\n"
    return $html
  }

NOTE: Current problem is that the cookies added this way don't seem to last long, even without expiration set. If the browser is restarted, the cookie goes away. Seen in both IE & Netscape. Comments welcomed.

2002-01-29 Acacio Cruz


Retrieving a Cookie

To retrieve a saved cookie, use Doc_Cookie. The following is an example of simple .tml form that can be used as a login form:

  [ Doc_Dynamic
    html::head "Login form" ]

  <FORM action=/login method=post>
  <table>
    <tr>
      <td>Username</td>
      <td><input name=username value="[Doc_Cookie username]"></td>
    </tr>
    <tr>
      <td>Password</td>
      <td><input name=password></td>
    </tr>
    <tr>
      <td><input type=submit></td>
    </tr>
  </table>
  </FORM>
  </HTML>

2002-01-29 Acacio Cruz


Wanted examples

2002-01-29 Acacio Cruz

2004-04-15 WJR - Skeletal session management code can be found on the TclHttpd: The .tml File page. It creates a client-side cookie containing the session ID. The cookie is used to tie the client to their session and their session variables. I've found this to be easier to manage than passing the session ID through the URL.


Doc_Cookie vs Httpd_Cookie

Doc_Cookie sets cookies which will be returned (via Httpd_Cookie) if, and only if, the procedure setting them is either in a Direct domain, or called via DocTemplate (ie: a .tml file.)

2002-07-31 CMcC


File Upload

This is a File Upload example.

2002-10-22 Michael Hankinson


TV I've got a tclhttpd with some additions and changes running now for half a year, with probably easily more then 95% or 24/7 uptime on a standard consumer connection, which works fine, as it has before, except not all is clear or asit probably is most desirable. Uninterupted uptime seems bounded by windows (XP) to a few weeks or so, depending on what I do, of course (want to run linux for instance..), but not because of leak or stack problems it seems, everything is fine, with say 10000 hits/week or so.

[ DG -- I'm doing some tests using iocpsock and have seen one of our XP servers do 72K hits per day. In theory, 8.6M hits per day are possible if it ran flat-out. ]

You'll need to be very aware that certain functions, like the cgi examples, expecially combined with the upload feature can be quite a potential security hazard for hackers who know the server.

Basically, remove all parts of the standard distribution with the errors and cgi's and dangerous scripts, and if you think it important, the reset button on the traffic page.

I'll make a page with a straightforward enough server application script based on the tclhttpd 3.4.1 standard distribution, I'll need to go through my files a bit to get that together for those who want a running server easily.

Anyone know why the file filter box on the document hits page doesn't seem to work right?

example Direct_Url:

 ###  Fortune page
 proc serve_fortune {} {
   return "<html><h2>Fortune Page</h2>\n<P>An automatically generated fortune \n<P><pre>[exec /cygwin/bin/fortune]</pre></html>"
 }
 Direct_Url /fortune serve_fortune

Use that in the httpd.tcl file before the last section somewhere, maybe source it in to get the equivalent of this page: http://www.theover.org/fortune.html . You'll need cygwin.

(This in my not too humble opinion was not a remark without use, who thinks they can singlehandedly decide otherwise and break the reasonable code on these wikis and remove it?)

chrstphrchvz 2019-01-25 repaired link to fortune page on TV's site


Starter Code for easy image deployment Image Server starter code for tclhttpd 2002-10-24 art morel


formkit uses tclhttpd templates (tml pages) and metakit to store and retrieve web form information.

June 26, 2003: a session enabled example of formkit is available at [L1 ]


Username/Password Database for Tclhttpd is an example using the session module in Tclhttpd. It requires Metakit.


Chapter "Static page access in Tclhttpd" in Wikit configuration shows how to use the static-page-approach from the wikit with the Tclhttpd-server (5/7/2003 Stefan Vogel).


I've put up some session demo code into the CVS HEAD under sampleapps/session/ which gives some brief examples on the use of sessions in tclhttpd. These examples don't exploit sessions' ability to run in their own interpreters, but only the use of sessions to maintain persistent state.

The examples demonstrate new session facilities: persistent sessions (state saved in a file), session id in cookies and long MD5 session IDs.


I've written a binding that lets you run OpenACS code from inside tclhttpd.

http://www.jsequeira.com/projects/portable.nsd/

The documentation could use some work, but it's a pretty powerful combination. The shim code provides examples of cookies and Direct URLs. (7oct2003 JJS)


You want to administrate some metakit-database-files with a web-interface in Tclhttpd? Simply have a look at Webadmin for Metakit with Tclhttpd.

A nearly complete webadministration-interface for metakits in only around 600 LoC (implemented as a Direct-URL). Tclhttpd is simply cool :-) (10/22/2003 Stefan Vogel)


CMcC 20040613 - Here's a little proc you can add to your custom directory to allow the automatic scaling of .jpg files. It also caches the generated files in /tmp/

    proc Doc_image/jpeg {path suffix sock} {
        upvar #0 Httpd$sock data

        if {$data(query) == {}} {
            # there are no parameters - return the original
            Httpd_ReturnFile $sock image/jpeg $path
        } else {
            # get parameters
            ncgi::reset $data(query) application/x-www-urlencoded
            ncgi::parse
            ::ncgi::setDefaultValue scale 100
            set scale [ncgi::value scale]

            if {$scale == "100"} {
                # we want full scale - return the original
                Httpd_ReturnFile $sock image/jpeg $path
            }

            # construct the necessary pathnames
            set file [file tail $path]
            set icache /tmp/tclhttpd-icache/
            set image [file join $icache ${scale}-$file]
            file mkdir $icache

            # use the image cache or generate an image into the cache
            if {![file exists $image]} {
                if {[catch {exec convert -geometry ${scale}% $path $image} result]} {
                    error "file: $file image: $image -> $result"
                }
            }

            # return the cached image
            Httpd_ReturnFile $sock image/jpeg $image
        }
    }

schlenk Here is a little example how to find out the users prefered language settings and react by switching locales for mclocale..., put it in a tml and try switching your preferences to de-de

 <html>
 [ 
   Doc_Dynamic
   package require msgcat
   # set the locale 
   set old [msgcat::mclocale]
   msgcat::mcset de "User set language preference" "Der Nutzer hat eine Sprachpr&auml;ferenz gesetzt"

   array unset headers
   array set headers [Httpd_DumpHeaders [Httpd_CurrentSocket]]
   if {[info exists headers(accept-language)]} {
     set items [split $headers(accept-language) {,;}]
     set out "User languages<br>\n"
     set ll [list]
     set langs [list]
     foreach item $items {                
        if {[string match "q=*" $item]} {
            set weight [string range $item 2 end]
            lappend langs [list $weight $ll]
            set ll [list]
        } else {
            lappend ll $item
        }
     }
     set langs [lsort -index 0 -real -decreasing $langs]
     append out "<table>"
     foreach row $langs {
        foreach {weight lang} $row {
            append out "<tr><td>$weight</td><td>$lang</td></tr>\n"       
        }
     }
     append out "</table>"
     # if we want to use msgcat we have to convert the lang into a format useful for
     # msgcat and use msgcat::mclocale $lang to set it
     # this simply assumes the browser sends appropriate lang info
     set prefered [lindex $langs 0 1 0]
     set mcpref [string map {- _} $prefered]
     msgcat::mclocale $mcpref
     # now use msgcat::mc for outputting text
     append out "<h2>[msgcat::mc "User set language preference"] : $mcpref</h2>" 

   } else {
     set out "User has set no language preference"
   }
   #reset the locale to the old setting
   msgcat::mclocale $old
   set out

 ]

 </html>

tclhttpd 2ch-forums