Toadhttpd

Toadhttpd is an effort to extend the Httpd (tcllib) module into a fully functioning web server, in the style of Tclhttpd. The project actually started as version 4.0 of Tclhttpd, but it became readily apparent that the new coroutine and Tcloo based dispatch engine was completely irreconcilable with the old interpreter/procs named just so method of the old system. Rather than put out an incompatible new version, hypnotoad decided it was better to just roll it out as a new project.

Principle development is published as a fossil repository: https://chiselapp.com/user/hypnotoad/repository/toadhttpd/index

Toadhttpd is designed to install a complete snapshot of all of the code it depends on into a file location. In that way a production environment can support multiple version of Toadhttpd running different generations of the software.

To install an instance of Toadhttpd:

# Clone and upack the fossil sources
# Feel free to adjust the paths to your liking
mkdir -p ~/tcl/fossil/
fossil clone https://chiselapp.com/user/hypnotoad/repository/toadhttpd ~/tcl/fossil/toadhttpd.fos
mkdir -p ~/tcl/sandbox/toadhttpd
cd ~/tcl/sandbox/toadhttpd
fossil open ~/tcl/fossil/toadhttpd.fos

# Make a directory to host your content from
tclsh ~/tcl/sandbox/toadhttpd/make.tcl install ~/www/mysite
cd ~/www/mysite
ls
htdocs                httpd.tcl        log                modules                plugin                var
ls htdocs
hello.tml

To run the webserver:

tclsh httpd.tcl

If the file config.tcl is present in your directory, it will be read as a script during startup.

The default is to host the htdocs directory next to the httpd script as static content. However, like tclhttpd, you can embed template files that Tcl will perform substitutions on. The installer automatically drops in htdocs/hello.tml:

[my html_header {Hello World!}]
Your Server is running.
<p>
The time is now [clock format [clock seconds]]
[my html_footer]

You'll note the my statements in the template. The substitution is being performed inside the namespace of an httpd::reply instance. You can access information from the request via the my request method, and alter the outgoing headers via my reply. To institute a 301 redirect:

[my html_header {File has moved}]
The file your were looking for [my request get REQUEST_URI] has moved. You will be redirected to: 
[### Manually generate a 303 reply
set location /some/other/url
my reply set Status 303
my reply set LOCATION $location
return $location]
a moment.
<p>
The time is now [clock format [clock seconds]]
[my html_footer]

Sqlite based Logs and cache are accessible in the logs/ directory.

> ls log/
cache.sqlite        log.sqlite
> sqlite3 log/log.sqlite 
SQLite version 3.24.0 2018-06-04 19:24:41
Enter ".help" for usage hints.
sqlite> .tables
blackhole          debug              log                session          
blackhole_journal  journal            log_info           session_info     
sqlite> .schema log
CREATE TABLE log (
time  'UNIXTIME' DEFAULT (now()),
REMOTE_ADDR  'IPADDR',
REMOTE_HOST  'HOSTNAME',
REFERER  'URI',
USER_AGENT  'STRING',
HTTP_HOST  'HOSTNAME',
REQUEST_URI  'URI',
SESSION  'UUID' REFERENCES session DEFAULT(guuid()),
COOKIE  'STRING',
rowid INTEGER PRIMARY KEY AUTOINCREMENT,
uuid STRING UNIQUE
);
sqlite> select * from log;
1537370493|127.0.0.1|127.0.0.1|http://localhost:8015/|Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Safari/605.1.15|localhost:8015|/hello.tml|||5|d71a0fb6-0208-43f5-b468-58c797b3c901
sqlite> 

Servers Running Toadhttpd

http://www.etoyoc.com