Version 6 of Starting Tclhttpd in a slave interpreter

Updated 2003-04-11 18:31:42

One simple way to embed tclhttpd into an tcl application is to just create a slave interpreter and load tclhttpd inside the slave. This is easy and works quite well and moves all problems with colliding names etc out of the way.

  # example code

  # StartEmbeddedHttpd
  # path is the path to the tclhttpd bin/httpd.tcl file
  # args are commandline args to pass to tclhttpd

  proc StartEmbeddedHttpd {path args} {

    set httpd [interp create] 

    # set tclhttpd command line options
    $httpd eval "set argc [llength $args]"
    set cmdargv "set argv [list $args ]"
    $httpd eval $cmdargv

    # now load the server and start it
    set cmd [list source $path]

    # the server does not return, it enters [vwait forever] , so we have to use the after 0 trick
    # errors have to be handled by bgerror

    after 0 $httpd eval $cmd

    return $httpd
  } 

  proc ShutdownEmbeddedHttpd {interp} {
    $interp eval Httpd_Shutdown
  }

  proc DestroyEmbeddedHttpd {interp} {
    $interp delete
  }

Usage example:

 % StartEmbeddedHttpd /tclhttpd/bin/httpd.tcl -port 9001
 interp1

 # now we can even access our own server via http 
 % package require http
 2.4.2
 % set tok [http::geturl http://localhost:9001/]
 ::http::1

It is even possible to start multiple servers if they use different ports.


TV Is another interpreter always or possibly a seperate thread in tcl (sorry to say last time I didn't read in enough to know ny heart or doc)? Otherwise one part of such application might hang the other. And beware than when you are on the internet, which is good and desirable of course, anyone can access the server, and there ARE certain riscs in running httpd out of the box... And fun, of course.


Jacob Levy Nice! I should note that this depends on the event loop being active.

To answer TV's question -- interpreters can below to the same or to another thread. If you use the thread extension, the other thread will run an interpreter that belongs only to it. The interpreters returned from "interp create" always belong to the same thread as the invoking interpreter.