Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/Tclhttpd+range+requests+and+single+interpreter+virtual+hosts+support?V=0
QUERY_STRINGV=0
CONTENT_TYPE
DOCUMENT_URI/revision/Tclhttpd+range+requests+and+single+interpreter+virtual+hosts+support
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.70.131.32
REMOTE_PORT14684
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR18.225.31.159
HTTP_CF_RAY87f9d931d95b8702-ORD
HTTP_X_FORWARDED_PROTOhttps
HTTP_CF_VISITOR{"scheme":"https"}
HTTP_ACCEPT*/*
HTTP_USER_AGENTMozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; [email protected])
HTTP_CF_CONNECTING_IP18.225.31.159
HTTP_CDN_LOOPcloudflare
HTTP_CF_IPCOUNTRYUS

Body


Error

Unknow state transition: TR -> LINE

-code

1

-level

0

-errorstack

INNER {returnImm {Unknow state transition: TR -> LINE} {}} CALL {my render_wikit {Tclhttpd range requests and single interpreter virtual hosts support} The\ following\ patch\ adds\ partial\ range\ requests\ support.\ Additionally\ a\ virtual\ hosts\ implementation\ is\ provided,\ it's\ a\ little\ bit\ more\ flexible\ than\ original\ one,\ doesn't\ require\ multiple\ interps,\ eats\ less\ memory,\ but,\ of\ course,\ is\ a\ little\ less\ secure.\n\n`diff\ -r\ -u\ tclhttpd3.5.1-dist.orig/tclhttpd3.5.1/lib/doc.tcl\ tclhttpd3.5.1-dist/tclhttpd3.5.1/lib/doc.tcl\n---\ tclhttpd3.5.1-dist.orig/tclhttpd3.5.1/lib/doc.tcl\ \ \ \ \ \ \ \ 2004-05-19\ 07:36:37.000000000\ +0300\n+++\ tclhttpd3.5.1-dist/tclhttpd3.5.1/lib/doc.tcl\ \ \ \ \ \ \ \ 2009-09-20\ 15:47:40.000000000\ +0300\n@@\ -28,6\ +28,7\ @@\n\ package\ require\ httpd::dirlist\n\ package\ require\ httpd::doc_error\n\ package\ require\ httpd::cookie\n+package\ require\ httpd::vhost\n\ \n\ #\ Doc_Root\ --\n\ #\n@@\ -271,9\ +272,9\ @@\n\ \ \ \ \ #\ into\ account\ other\ document\ roots.\n\ \n\ \ \ \ \ if\ \{\[info\ exist\ Doc(root,\$data(prefix))\]\}\ \{\n-\ \ \ \ \ \ \ \ set\ directory\ \$Doc(root,\$data(prefix))\n+\ \ \ \ \ \ \ \ set\ directory\ \[file\ join\ \$Doc(root,\$data(prefix))\ \[lindex\ \$data(vhost)\ 1\]\]\n\ \ \ \ \ \}\ else\ \{\n-\ \ \ \ \ \ \ \ set\ directory\ \[file\ join\ \$Doc(root,/)\ \[string\ trimleft\ \$data(prefix)\ /\]\]\n+\ \ \ \ \ \ \ \ set\ directory\ \[file\ join\ \$Doc(root,/)\ \[lindex\ \$data(vhost)\ 1\]\ \[string\ trimleft\ \$data(prefix)\ /\]\]\n\ \ \ \ \ \}\n\ \n\ \ \ \ \ #\ Look\ for\ .htaccess\ and\ .tclaccess\ files\ along\ the\ path\n@@\ -348,7\ +349,7\ @@\n\ \ \ \ \ #\ pathnames\ outside\ the\ URL\ tree.\ \ We\ trim\ left\ the\ /\ and\ ~\n\ \ \ \ \ #\ to\ prevent\ those\ attacks.\n\ \n-\ \ \ \ set\ path\ \[file\ join\ \$directory\ \[string\ trimleft\ \$suffix\ /~\]\]\n+\ \ \ \ set\ path\ \[file\ join\ \$directory\ \[lindex\ \$data(vhost)\ 1\]\ \[string\ trimleft\ \$suffix\ /~\]\]\n\ \ \ \ \ set\ path\ \[DocPathNormalize\ \$path\]\n\ \ \ \ \ set\ data(path)\ \$path\ \ \ \ \ \ \ \ \;#\ record\ this\ path\ for\ not\ found\ handling\n\ \ndiff\ -r\ -u\ tclhttpd3.5.1-dist.orig/tclhttpd3.5.1/lib/httpd.tcl\ tclhttpd3.5.1-dist/tclhttpd3.5.1/lib/httpd.tcl\n---\ tclhttpd3.5.1-dist.orig/tclhttpd3.5.1/lib/httpd.tcl\ \ \ \ \ \ \ \ 2009-07-26\ 20:25:55.000000000\ +0300\n+++\ tclhttpd3.5.1-dist/tclhttpd3.5.1/lib/httpd.tcl\ \ \ \ \ \ \ \ 2009-09-20\ 16:00:18.000000000\ +0300\n@@\ -25,7\ +25,6\ @@\n\ #\ RCS:\ @(#)\ \$Id:\ httpd.tcl,v\ 1.85\ 2004/04/29\ 01:34:16\ coldstore\ Exp\ \$\n\ \n\ package\ provide\ httpd\ 1.7\n-\n\ #\ initialize\ all\ the\ global\ data\n\ \n\ #\ Location\ of\ this\ package\n@@\ -35,6\ +34,7\ @@\n\ array\ set\ Httpd_Errors\ \{\n\ \ \ \ \ 200\ \{Data\ follows\}\n\ \ \ \ \ 204\ \{No\ Content\}\n+\ \ \ \ 206\ \{Partial\ content\}\n\ \ \ \ \ 302\ \{Found\}\n\ \ \ \ \ 304\ \{Not\ Modified\}\n\ \ \ \ \ 400\ \{Bad\ Request\}\n@@\ -614,6\ +614,7\ @@\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ data(uri)\ is\ the\ complete\ URI\n\ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ data(uri)\ \$data(url)\n+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ data(vhost)\ \[list\ *\ .\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$data(query)\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ append\ data(uri)\ ?\$data(query)\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n@@\ -694,7\ +695,10\ @@\n\ \ \ \ \ \ \ \ \ \ \ \ \ variable\ virtual\n\ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[string\ compare\ host\ \$key\]\}\ \{return\}\n\ \ \ \ \ \ \ \ \ \ \ \ \ set\ host\ \[lindex\ \[split\ \[string\ tolower\ \$value\]\ :\]\ 0\]\n-\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[catch\ \{set\ virtual(\$host)\}\ i\]\}\ \{return\}\n+\ \ \ \ \ \ \ \ \ \ \ \ set\ data(vhost)\ \[VHost_Match\ \$host\]\n+\ \ \ \ \ \ \ \ \ \ \ \ return\n+\n+\ \ \ \ \ \ \ \ \ \ \ \ #\ old\ implementation\ follows\n\ \n\ \ \ \ \ \ \ \ \ \ \ \ \ #\ Transfer\ \$sock\ to\ interp\ \$i\n\ \ \ \ \ \ \ \ \ \ \ \ \ fileevent\ \$sock\ readable\ \{\}\n@@\ -722,7\ +729,7\ @@\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ data(count)\ \$data(mime,content-length)\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$data(version)\ >=\ 1.1\ &&\ \[info\ exists\ data(mime,expect)\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$data(mime,expect)\ ==\ \"100-continue\"\}\ \{\n-\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ \$sock\ \"100\ Continue\ HTTP/1.1\\n\"\n+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ \$sock\ \"HTTP/1.1\ 100\ Continue\\n\"\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ flush\ \$sock\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Httpd_Error\ \$sock\ 419\ \$data(mime,expect)\n@@\ -1213,12\ +1220,20\ @@\n\ \ \ \ \ append\ reply\ \"HTTP/\$data(version)\ \$code\ \[HttpdErrorString\ \$code\]\"\ \\n\n\ \ \ \ \ append\ reply\ \"Date:\ \[HttpdDate\ \[clock\ seconds\]\]\"\ \\n\n\ \ \ \ \ append\ reply\ \"Server:\ \$Httpd(server)\\n\"\n+\ \ \ \ append\ reply\ \"Accept-Ranges:\ bytes\\n\"\n\ \n\ \ \ \ \ if\ \{\$close\}\ \{\n\ \ \ \ \ \ \ \ \ append\ reply\ \"Connection:\ Close\"\ \\n\n\ \ \ \ \ \}\ elseif\ \{\$data(version)\ ==\ 1.0\ &&\ !\$close\}\ \{\n\ \ \ \ \ \ \ \ \ append\ reply\ \"Connection:\ Keep-Alive\"\ \\n\n\ \ \ \ \ \}\n+\ \ \ \ if\ \{\[info\ exists\ data(partial)\]\}\ \{\n+\ \ \ \ \ \ \ \ set\ c_start\ \[lindex\ \$data(partial)\ 0\]\n+\ \ \ \ \ \ \ \ set\ c_end\ \[lindex\ \$data(partial)\ 1\]\n+\ \ \ \ \ \ \ \ set\ c_length\ \[lindex\ \$data(partial)\ 2\]\n+\ \ \ \ \ \ \ \ set\ content_range\ \"bytes\ \$c_start-\$c_end/\$c_length\"\n+\ \ \ \ \ \ \ \ append\ reply\ \"Content-Range:\ \$content_range\"\ \\n\n+\ \ \ \ \}\n\ \ \ \ \ append\ reply\ \"Content-Type:\ \$type\"\ \\n\n\ \ \ \ \ if\ \{\[string\ length\ \$size\]\}\ \{\n\ \ \ \ \ \ \ \ \ append\ reply\ \"Content-Length:\ \$size\"\ \\n\n@@\ -1315,6\ +1330,59\ @@\n\ \ \ \ \ \}\n\ \}\n\ \n+#\ Range\ parsing\ procedures\;\ not\ fully\ implemented\ yet\ :-(\n+\n+proc\ Httpd_ParseSubrange\ \{subrange\}\ \{\n+\ \ \ \ if\ \{\[regexp\ \{^(\[0-9\]*)-(\[0-9\]*)\$\}\ \$subrange\ dummy\ from\ to\]\}\ \{\n+\ \ \ \ \ \ \ \ if\ \{\"x\$from\"\ !=\ \"x\"\ &&\ \"x\$to\"\ !=\ \"x\"\}\ then\ \{\n+\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$from\ >\ \$to\}\ \{\n+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ from\ \{\}\n+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ to\ \{\}\n+\ \ \ \ \ \ \ \ \ \ \ \ \}\n+\ \ \ \ \ \ \ \ \}\n+\ \ \ \ \}\ else\ \{\n+\ \ \ \ \ \ \ \ set\ from\ \{\}\n+\ \ \ \ \ \ \ \ set\ to\ \{\}\n+\ \ \ \ \}\n+\ \ \ \ return\ \[list\ \$from\ \$to\]\n+\}\n+\n+proc\ Httpd_AddSubrange\ \{summary\ max\ subrange\}\ \{\n+\ \ \ \ set\ parsed\ \[Httpd_ParseSubrange\ \$subrange\]\n+\ \ \ \ if\ \{\[llength\ \$subrange\]\ ==\ 0\}\ \{\n+\ \ \ \ \ \ \ \ \ \ \ \ return\ \$summary\n+\ \ \ \ \}\n+\ \ \ \ #\ TODO:\ iterate\ existing\ subranges\n+\ \ \ \ set\ from\ \[lindex\ \$parsed\ 0\]\n+\ \ \ \ set\ to\ \ \ \[lindex\ \$parsed\ 1\]\n+\ \ \ \ if\ \{\"x\$from\"==\"x\"\ &&\ \"x\$from\"\ !=\ \"x\$to\"\}\ \{\n+\ \ \ \ \ \ \ \ set\ nto\ \[expr\ \{\$max-1\}\]\n+\ \ \ \ \ \ \ \ set\ nfrom\ \[expr\ \{\$nto-\$to+1\}\]\n+\ \ \ \ \ \ \ \ set\ parsed\ \[list\ \$nfrom\ \$nto\]\n+\ \ \ \ \}\n+\ \ \ \ if\ \{\"x\$to\"==\"x\"\ &&\ \"x\$from\"\ !=\ \"x\$to\"\}\ \{\n+\ \ \ \ \ \ \ \ set\ to\ \[expr\ \{\$max-1\}\]\n+\ \ \ \ \ \ \ \ set\ parsed\ \[list\ \$from\ \$to\]\n+\ \ \ \ \}\n+\ \ \ \ if\ \{\"x\$to\"!=\"x\"\ &&\ \"x\$from\"!=\"x\"\}\ \{\n+\ \ \ \ \ \ \ \ lappend\ summary\ \$parsed\n+\ \ \ \ \}\n+\ \ \ \ return\ \$summary\n+\}\n+\n+proc\ Httpd_ParseRange\ \{max\ range\}\ \{\n+\ \ \ \ set\ summary\ \[list\]\n+\ \ \ \ if\ \{\[regexp\ \{bytes=(.*)\}\ \$range\ dummy\ ranges\]\}\ \{\n+\ \ \ \ \ \ \ \ while\ \{\[string\ length\ \$ranges\]\ !=\ 0\}\ \{\n+\ \ \ \ \ \ \ \ \ \ \ \ regexp\ \{(\[^,\]*)(,(.*))?\}\ \$ranges\ dummy0\ subrange\ dummy\ other\n+\ \ \ \ \ \ \ \ \ \ \ \ set\ summary\ \[Httpd_AddSubrange\ \$summary\ \$max\ \$subrange\]\n+\ \ \ \ \ \ \ \ \ \ \ \ set\ ranges\ \$other\n+\ \ \ \ \ \ \ \ \}\n+\ \ \ \ \}\n+\ \ \ \ return\ \$summary\n+\}\n+\n+\n\ #\ Httpd_ReturnFile\n\ #\ \ \ \ \ \ \ \ Return\ a\ file.\n\ #\n@@\ -1355,10\ +1423,20\ @@\n\ \ \ \ \ #\ side\ accounting\ information.\n\ \n\ \ \ \ \ incr\ data(file_size)\ -\$offset\n+\ \ \ \ \n+\ \ \ \ if\ \{\[info\ exists\ data(mime,range)\]\}\ \{\n+\ \ \ \ \ \ \ \ set\ ranges\ \[Httpd_ParseRange\ \$data(file_size)\ \$data(mime,range)\]\n+\ \ \ \ \ \ \ \ set\ c_start\ \[lindex\ \$ranges\ 0\ 0\]\n+\ \ \ \ \ \ \ \ set\ c_end\ \[lindex\ \$ranges\ 0\ 1\]\n+\ \ \ \ \ \ \ \ set\ c_length\ \$data(file_size)\n+\ \ \ \ \ \ \ \ set\ data(partial)\ \[list\ \$c_start\ \$c_end\ \$c_length\]\n+\ \ \ \ \ \ \ \ incr\ offset\ \[expr\ \{\$c_start-1\}\]\n+\ \ \ \ \ \ \ \ set\ data(code)\ 206\n+\ \ \ \ \}\n\ \n\ \ \ \ \ if\ \{\[catch\ \{\n\ \ \ \ \ \ \ \ \ set\ close\ \[HttpdCloseP\ \$sock\]\n-\ \ \ \ \ \ \ \ HttpdRespondHeader\ \$sock\ \$type\ \$close\ \$data(file_size)\ 200\n+\ \ \ \ \ \ \ \ HttpdRespondHeader\ \$sock\ \$type\ \$close\ \$data(file_size)\ \$data(code)\n\ \ \ \ \ \ \ \ \ HttpdSetCookie\ \$sock\n\ \ \ \ \ \ \ \ \ puts\ \$sock\ \"Last-Modified:\ \[HttpdDate\ \[file\ mtime\ \$path\]\]\"\n\ \ \ \ \ \ \ \ \ puts\ \$sock\ \"\"\n@@\ -1371,7\ +1449,11\ @@\n\ \ \ \ \ \ \ \ \ \ \ \ \ fconfigure\ \$sock\ -translation\ binary\ -blocking\ \$Httpd(sockblock)\n\ \ \ \ \ \ \ \ \ \ \ \ \ set\ data(infile)\ \$in\n\ \ \ \ \ \ \ \ \ \ \ \ \ Httpd_Suspend\ \$sock\ 0\n-\ \ \ \ \ \ \ \ \ \ \ \ fcopy\ \$in\ \$sock\ -command\ \[list\ HttpdCopyDone\ \$in\ \$sock\ \$close\]\n+\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$data(code)==200\}\ \{\n+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fcopy\ \$in\ \$sock\ -command\ \[list\ HttpdCopyDone\ \$in\ \$sock\ \$close\]\n+\ \ \ \ \ \ \ \ \ \ \ \ \}\ else\ \{\n+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fcopy\ \$in\ \$sock\ -size\ \[expr\ \{\$c_end-\$c_start+1\}\]\ -command\ \[list\ HttpdCopyDone\ \$in\ \$sock\ \$close\]\n+\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ Httpd_SockClose\ \$sock\ \$close\n\ \ \ \ \ \ \ \ \ \}\ndiff\ -r\ -u\ tclhttpd3.5.1-dist.orig/tclhttpd3.5.1/lib/pkgIndex.tcl\ tclhttpd3.5.1-dist/tclhttpd3.5.1/lib/pkgIndex.tcl\n---\ tclhttpd3.5.1-dist.orig/tclhttpd3.5.1/lib/pkgIndex.tcl\ \ \ \ \ \ \ \ 2004-03-23\ 11:35:15.000000000\ +0200\n+++\ tclhttpd3.5.1-dist/tclhttpd3.5.1/lib/pkgIndex.tcl\ \ \ \ \ \ \ \ 2009-09-20\ 14:52:33.000000000\ +0300\n@@\ -45,5\ +45,6\ @@\n\ \ \ \ \ \ \ \ \ package\ ifneeded\ httpd::url\ 1.2\ \\\[list\ source\ \\\[file\ join\ \[list\ \$dir\]\ url.tcl\\\]\\\]\n\ \ \ \ \ \ \ \ \ package\ ifneeded\ httpd::utils\ 1.0\ \\\[list\ source\ \\\[file\ join\ \[list\ \$dir\]\ utils.tcl\\\]\\\]\n\ \ \ \ \ \ \ \ \ package\ ifneeded\ httpd::version\ 3.5\ \\\[list\ source\ \\\[file\ join\ \[list\ \$dir\]\ version.tcl\\\]\\\]\n+\ \ \ \ \ \ \ \ package\ ifneeded\ httpd::vhost\ 0.1\ \\\[list\ source\ \\\[file\ join\ \[list\ \$dir\]\ vhost.tcl\\\]\\\]\n\ \ \ \ \ \ \ \ \ package\ ifneeded\ tclcrypt\ 1.0\ \\\[list\ source\ \\\[file\ join\ \[list\ \$dir\]\ tclcrypt.tcl\\\]\\\]\n\ \"\ndiff\ -r\ -u\ tclhttpd3.5.1-dist.orig/tclhttpd3.5.1/lib/version.tcl\ tclhttpd3.5.1-dist/tclhttpd3.5.1/lib/version.tcl\n---\ tclhttpd3.5.1-dist.orig/tclhttpd3.5.1/lib/version.tcl\ \ \ \ \ \ \ \ 2004-05-27\ 21:00:52.000000000\ +0300\n+++\ tclhttpd3.5.1-dist/tclhttpd3.5.1/lib/version.tcl\ \ \ \ \ \ \ \ 2009-09-20\ 14:43:56.000000000\ +0300\n@@\ -1,5\ +1,5\ @@\n\ package\ provide\ httpd::version\ 3.5\n\ proc\ Httpd_Version\ \{\}\ \{\n\ \ \ \ \ global\ Httpd\n-\ \ \ \ set\ Httpd(version)\ \ \ \ \ \ \ \ \"3.5.1\ May\ 27,\ 2004\"\n+\ \ \ \ set\ Httpd(version)\ \ \ \ \ \ \ \ \"3.5.1-bdt\ September\ 20,\ 2009\"\n\ \}\ndiff\ -r\ -u\ tclhttpd3.5.1-dist.orig/tclhttpd3.5.1/bin/tclhttpd.rc\ tclhttpd3.5.1-dist/tclhttpd3.5.1/bin/tclhttpd.rc\n---\ tclhttpd3.5.1-dist.orig/tclhttpd3.5.1/bin/tclhttpd.rc\ \ \ \ \ \ \ \ 2009-07-26\ 21:03:55.000000000\ +0300\n+++\ tclhttpd3.5.1-dist/tclhttpd3.5.1/bin/tclhttpd.rc\ \ \ \ \ \ \ \ 2009-09-20\ 16:08:55.000000000\ +0300\n@@\ -40,7\ +40,7\ @@\n\ \ \ \ \ \}\n\ \}\n\ \n-\n+Config\ vhost\ \[list\ \[list\ *host1.org\ host1\ host1-htdocs\]\ \[list\ *\ *\ .\]\]\n\ \n\ #\ main\ -\ Main\ per-thread\ startup\ script.\n\ #\ The\ old\ way\ to\ customize\ the\ server\ was\ to\ modify\ this\ file\ directly.\n---\ /dev/null\ \ \ \ \ \ \ \ 2009-09-18\ 17:04:13.511138139\ +0300\n+++\ tclhttpd3.5.1-dist/tclhttpd3.5.1/lib/vhost.tcl\ \ \ \ \ \ \ \ 2009-09-20\ 16:08:16.000000000\ +0300\n@@\ -0,0\ +1,27\ @@\n+#\ vhost.tcl\n+\n+#\ Virtual\ hosts\ implementation\n+\n+package\ provide\ httpd::vhost\ 0.1\n+\n+set\ vhosts\ \[list\]\n+#\ \[list\ *\ \{return\ \[list\ *\ .\]\}\]\n+\n+proc\ VHost_Add\ \{glob\ name\ dir\}\ \{\n+\ \ \ \ global\ vhosts\n+\ \ \ \ #\ set\ vhosts\ \[linsert\ \$vhosts\ 0\ \$glob\ \[list\ return\ \[list\ \$name\ \$dir\]\]\]\n+\ \ \ \ lappend\ vhosts\ \$glob\ \[list\ return\ \[list\ \$name\ \$dir\]\]\n+\}\n+\n+proc\ VHost_Match\ \{host\}\ \{\n+\ \ \ \ global\ vhosts\n+\ \ \ \ switch\ -glob\ \$host\ \$vhosts\n+\}\n+\n+if\ \{\[cget\ vhost\]==\{\}\}\ \{\n+\ \ \ \ VHost_Add\ *\ *\ .\n+\}\ else\ \{\n+\ \ \ \ foreach\ vh\ \[cget\ vhost\]\ \{\n+\ \ \ \ \ \ \ \ VHost_Add\ \[lindex\ \$vh\ 0\]\ \[lindex\ \$vh\ 1\]\ \[lindex\ \$vh\ 2\]\n+\ \ \ \ \}\n+\}`\n\n\n<<categories>>TclHttpd regexp2} CALL {my render {Tclhttpd range requests and single interpreter virtual hosts support} The\ following\ patch\ adds\ partial\ range\ requests\ support.\ Additionally\ a\ virtual\ hosts\ implementation\ is\ provided,\ it's\ a\ little\ bit\ more\ flexible\ than\ original\ one,\ doesn't\ require\ multiple\ interps,\ eats\ less\ memory,\ but,\ of\ course,\ is\ a\ little\ less\ secure.\n\n`diff\ -r\ -u\ tclhttpd3.5.1-dist.orig/tclhttpd3.5.1/lib/doc.tcl\ tclhttpd3.5.1-dist/tclhttpd3.5.1/lib/doc.tcl\n---\ tclhttpd3.5.1-dist.orig/tclhttpd3.5.1/lib/doc.tcl\ \ \ \ \ \ \ \ 2004-05-19\ 07:36:37.000000000\ +0300\n+++\ tclhttpd3.5.1-dist/tclhttpd3.5.1/lib/doc.tcl\ \ \ \ \ \ \ \ 2009-09-20\ 15:47:40.000000000\ +0300\n@@\ -28,6\ +28,7\ @@\n\ package\ require\ httpd::dirlist\n\ package\ require\ httpd::doc_error\n\ package\ require\ httpd::cookie\n+package\ require\ httpd::vhost\n\ \n\ #\ Doc_Root\ --\n\ #\n@@\ -271,9\ +272,9\ @@\n\ \ \ \ \ #\ into\ account\ other\ document\ roots.\n\ \n\ \ \ \ \ if\ \{\[info\ exist\ Doc(root,\$data(prefix))\]\}\ \{\n-\ \ \ \ \ \ \ \ set\ directory\ \$Doc(root,\$data(prefix))\n+\ \ \ \ \ \ \ \ set\ directory\ \[file\ join\ \$Doc(root,\$data(prefix))\ \[lindex\ \$data(vhost)\ 1\]\]\n\ \ \ \ \ \}\ else\ \{\n-\ \ \ \ \ \ \ \ set\ directory\ \[file\ join\ \$Doc(root,/)\ \[string\ trimleft\ \$data(prefix)\ /\]\]\n+\ \ \ \ \ \ \ \ set\ directory\ \[file\ join\ \$Doc(root,/)\ \[lindex\ \$data(vhost)\ 1\]\ \[string\ trimleft\ \$data(prefix)\ /\]\]\n\ \ \ \ \ \}\n\ \n\ \ \ \ \ #\ Look\ for\ .htaccess\ and\ .tclaccess\ files\ along\ the\ path\n@@\ -348,7\ +349,7\ @@\n\ \ \ \ \ #\ pathnames\ outside\ the\ URL\ tree.\ \ We\ trim\ left\ the\ /\ and\ ~\n\ \ \ \ \ #\ to\ prevent\ those\ attacks.\n\ \n-\ \ \ \ set\ path\ \[file\ join\ \$directory\ \[string\ trimleft\ \$suffix\ /~\]\]\n+\ \ \ \ set\ path\ \[file\ join\ \$directory\ \[lindex\ \$data(vhost)\ 1\]\ \[string\ trimleft\ \$suffix\ /~\]\]\n\ \ \ \ \ set\ path\ \[DocPathNormalize\ \$path\]\n\ \ \ \ \ set\ data(path)\ \$path\ \ \ \ \ \ \ \ \;#\ record\ this\ path\ for\ not\ found\ handling\n\ \ndiff\ -r\ -u\ tclhttpd3.5.1-dist.orig/tclhttpd3.5.1/lib/httpd.tcl\ tclhttpd3.5.1-dist/tclhttpd3.5.1/lib/httpd.tcl\n---\ tclhttpd3.5.1-dist.orig/tclhttpd3.5.1/lib/httpd.tcl\ \ \ \ \ \ \ \ 2009-07-26\ 20:25:55.000000000\ +0300\n+++\ tclhttpd3.5.1-dist/tclhttpd3.5.1/lib/httpd.tcl\ \ \ \ \ \ \ \ 2009-09-20\ 16:00:18.000000000\ +0300\n@@\ -25,7\ +25,6\ @@\n\ #\ RCS:\ @(#)\ \$Id:\ httpd.tcl,v\ 1.85\ 2004/04/29\ 01:34:16\ coldstore\ Exp\ \$\n\ \n\ package\ provide\ httpd\ 1.7\n-\n\ #\ initialize\ all\ the\ global\ data\n\ \n\ #\ Location\ of\ this\ package\n@@\ -35,6\ +34,7\ @@\n\ array\ set\ Httpd_Errors\ \{\n\ \ \ \ \ 200\ \{Data\ follows\}\n\ \ \ \ \ 204\ \{No\ Content\}\n+\ \ \ \ 206\ \{Partial\ content\}\n\ \ \ \ \ 302\ \{Found\}\n\ \ \ \ \ 304\ \{Not\ Modified\}\n\ \ \ \ \ 400\ \{Bad\ Request\}\n@@\ -614,6\ +614,7\ @@\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ #\ data(uri)\ is\ the\ complete\ URI\n\ \n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ data(uri)\ \$data(url)\n+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ data(vhost)\ \[list\ *\ .\]\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[string\ length\ \$data(query)\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ append\ data(uri)\ ?\$data(query)\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\n@@\ -694,7\ +695,10\ @@\n\ \ \ \ \ \ \ \ \ \ \ \ \ variable\ virtual\n\ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[string\ compare\ host\ \$key\]\}\ \{return\}\n\ \ \ \ \ \ \ \ \ \ \ \ \ set\ host\ \[lindex\ \[split\ \[string\ tolower\ \$value\]\ :\]\ 0\]\n-\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\[catch\ \{set\ virtual(\$host)\}\ i\]\}\ \{return\}\n+\ \ \ \ \ \ \ \ \ \ \ \ set\ data(vhost)\ \[VHost_Match\ \$host\]\n+\ \ \ \ \ \ \ \ \ \ \ \ return\n+\n+\ \ \ \ \ \ \ \ \ \ \ \ #\ old\ implementation\ follows\n\ \n\ \ \ \ \ \ \ \ \ \ \ \ \ #\ Transfer\ \$sock\ to\ interp\ \$i\n\ \ \ \ \ \ \ \ \ \ \ \ \ fileevent\ \$sock\ readable\ \{\}\n@@\ -722,7\ +729,7\ @@\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ data(count)\ \$data(mime,content-length)\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$data(version)\ >=\ 1.1\ &&\ \[info\ exists\ data(mime,expect)\]\}\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$data(mime,expect)\ ==\ \"100-continue\"\}\ \{\n-\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ \$sock\ \"100\ Continue\ HTTP/1.1\\n\"\n+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ puts\ \$sock\ \"HTTP/1.1\ 100\ Continue\\n\"\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ flush\ \$sock\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ Httpd_Error\ \$sock\ 419\ \$data(mime,expect)\n@@\ -1213,12\ +1220,20\ @@\n\ \ \ \ \ append\ reply\ \"HTTP/\$data(version)\ \$code\ \[HttpdErrorString\ \$code\]\"\ \\n\n\ \ \ \ \ append\ reply\ \"Date:\ \[HttpdDate\ \[clock\ seconds\]\]\"\ \\n\n\ \ \ \ \ append\ reply\ \"Server:\ \$Httpd(server)\\n\"\n+\ \ \ \ append\ reply\ \"Accept-Ranges:\ bytes\\n\"\n\ \n\ \ \ \ \ if\ \{\$close\}\ \{\n\ \ \ \ \ \ \ \ \ append\ reply\ \"Connection:\ Close\"\ \\n\n\ \ \ \ \ \}\ elseif\ \{\$data(version)\ ==\ 1.0\ &&\ !\$close\}\ \{\n\ \ \ \ \ \ \ \ \ append\ reply\ \"Connection:\ Keep-Alive\"\ \\n\n\ \ \ \ \ \}\n+\ \ \ \ if\ \{\[info\ exists\ data(partial)\]\}\ \{\n+\ \ \ \ \ \ \ \ set\ c_start\ \[lindex\ \$data(partial)\ 0\]\n+\ \ \ \ \ \ \ \ set\ c_end\ \[lindex\ \$data(partial)\ 1\]\n+\ \ \ \ \ \ \ \ set\ c_length\ \[lindex\ \$data(partial)\ 2\]\n+\ \ \ \ \ \ \ \ set\ content_range\ \"bytes\ \$c_start-\$c_end/\$c_length\"\n+\ \ \ \ \ \ \ \ append\ reply\ \"Content-Range:\ \$content_range\"\ \\n\n+\ \ \ \ \}\n\ \ \ \ \ append\ reply\ \"Content-Type:\ \$type\"\ \\n\n\ \ \ \ \ if\ \{\[string\ length\ \$size\]\}\ \{\n\ \ \ \ \ \ \ \ \ append\ reply\ \"Content-Length:\ \$size\"\ \\n\n@@\ -1315,6\ +1330,59\ @@\n\ \ \ \ \ \}\n\ \}\n\ \n+#\ Range\ parsing\ procedures\;\ not\ fully\ implemented\ yet\ :-(\n+\n+proc\ Httpd_ParseSubrange\ \{subrange\}\ \{\n+\ \ \ \ if\ \{\[regexp\ \{^(\[0-9\]*)-(\[0-9\]*)\$\}\ \$subrange\ dummy\ from\ to\]\}\ \{\n+\ \ \ \ \ \ \ \ if\ \{\"x\$from\"\ !=\ \"x\"\ &&\ \"x\$to\"\ !=\ \"x\"\}\ then\ \{\n+\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$from\ >\ \$to\}\ \{\n+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ from\ \{\}\n+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ set\ to\ \{\}\n+\ \ \ \ \ \ \ \ \ \ \ \ \}\n+\ \ \ \ \ \ \ \ \}\n+\ \ \ \ \}\ else\ \{\n+\ \ \ \ \ \ \ \ set\ from\ \{\}\n+\ \ \ \ \ \ \ \ set\ to\ \{\}\n+\ \ \ \ \}\n+\ \ \ \ return\ \[list\ \$from\ \$to\]\n+\}\n+\n+proc\ Httpd_AddSubrange\ \{summary\ max\ subrange\}\ \{\n+\ \ \ \ set\ parsed\ \[Httpd_ParseSubrange\ \$subrange\]\n+\ \ \ \ if\ \{\[llength\ \$subrange\]\ ==\ 0\}\ \{\n+\ \ \ \ \ \ \ \ \ \ \ \ return\ \$summary\n+\ \ \ \ \}\n+\ \ \ \ #\ TODO:\ iterate\ existing\ subranges\n+\ \ \ \ set\ from\ \[lindex\ \$parsed\ 0\]\n+\ \ \ \ set\ to\ \ \ \[lindex\ \$parsed\ 1\]\n+\ \ \ \ if\ \{\"x\$from\"==\"x\"\ &&\ \"x\$from\"\ !=\ \"x\$to\"\}\ \{\n+\ \ \ \ \ \ \ \ set\ nto\ \[expr\ \{\$max-1\}\]\n+\ \ \ \ \ \ \ \ set\ nfrom\ \[expr\ \{\$nto-\$to+1\}\]\n+\ \ \ \ \ \ \ \ set\ parsed\ \[list\ \$nfrom\ \$nto\]\n+\ \ \ \ \}\n+\ \ \ \ if\ \{\"x\$to\"==\"x\"\ &&\ \"x\$from\"\ !=\ \"x\$to\"\}\ \{\n+\ \ \ \ \ \ \ \ set\ to\ \[expr\ \{\$max-1\}\]\n+\ \ \ \ \ \ \ \ set\ parsed\ \[list\ \$from\ \$to\]\n+\ \ \ \ \}\n+\ \ \ \ if\ \{\"x\$to\"!=\"x\"\ &&\ \"x\$from\"!=\"x\"\}\ \{\n+\ \ \ \ \ \ \ \ lappend\ summary\ \$parsed\n+\ \ \ \ \}\n+\ \ \ \ return\ \$summary\n+\}\n+\n+proc\ Httpd_ParseRange\ \{max\ range\}\ \{\n+\ \ \ \ set\ summary\ \[list\]\n+\ \ \ \ if\ \{\[regexp\ \{bytes=(.*)\}\ \$range\ dummy\ ranges\]\}\ \{\n+\ \ \ \ \ \ \ \ while\ \{\[string\ length\ \$ranges\]\ !=\ 0\}\ \{\n+\ \ \ \ \ \ \ \ \ \ \ \ regexp\ \{(\[^,\]*)(,(.*))?\}\ \$ranges\ dummy0\ subrange\ dummy\ other\n+\ \ \ \ \ \ \ \ \ \ \ \ set\ summary\ \[Httpd_AddSubrange\ \$summary\ \$max\ \$subrange\]\n+\ \ \ \ \ \ \ \ \ \ \ \ set\ ranges\ \$other\n+\ \ \ \ \ \ \ \ \}\n+\ \ \ \ \}\n+\ \ \ \ return\ \$summary\n+\}\n+\n+\n\ #\ Httpd_ReturnFile\n\ #\ \ \ \ \ \ \ \ Return\ a\ file.\n\ #\n@@\ -1355,10\ +1423,20\ @@\n\ \ \ \ \ #\ side\ accounting\ information.\n\ \n\ \ \ \ \ incr\ data(file_size)\ -\$offset\n+\ \ \ \ \n+\ \ \ \ if\ \{\[info\ exists\ data(mime,range)\]\}\ \{\n+\ \ \ \ \ \ \ \ set\ ranges\ \[Httpd_ParseRange\ \$data(file_size)\ \$data(mime,range)\]\n+\ \ \ \ \ \ \ \ set\ c_start\ \[lindex\ \$ranges\ 0\ 0\]\n+\ \ \ \ \ \ \ \ set\ c_end\ \[lindex\ \$ranges\ 0\ 1\]\n+\ \ \ \ \ \ \ \ set\ c_length\ \$data(file_size)\n+\ \ \ \ \ \ \ \ set\ data(partial)\ \[list\ \$c_start\ \$c_end\ \$c_length\]\n+\ \ \ \ \ \ \ \ incr\ offset\ \[expr\ \{\$c_start-1\}\]\n+\ \ \ \ \ \ \ \ set\ data(code)\ 206\n+\ \ \ \ \}\n\ \n\ \ \ \ \ if\ \{\[catch\ \{\n\ \ \ \ \ \ \ \ \ set\ close\ \[HttpdCloseP\ \$sock\]\n-\ \ \ \ \ \ \ \ HttpdRespondHeader\ \$sock\ \$type\ \$close\ \$data(file_size)\ 200\n+\ \ \ \ \ \ \ \ HttpdRespondHeader\ \$sock\ \$type\ \$close\ \$data(file_size)\ \$data(code)\n\ \ \ \ \ \ \ \ \ HttpdSetCookie\ \$sock\n\ \ \ \ \ \ \ \ \ puts\ \$sock\ \"Last-Modified:\ \[HttpdDate\ \[file\ mtime\ \$path\]\]\"\n\ \ \ \ \ \ \ \ \ puts\ \$sock\ \"\"\n@@\ -1371,7\ +1449,11\ @@\n\ \ \ \ \ \ \ \ \ \ \ \ \ fconfigure\ \$sock\ -translation\ binary\ -blocking\ \$Httpd(sockblock)\n\ \ \ \ \ \ \ \ \ \ \ \ \ set\ data(infile)\ \$in\n\ \ \ \ \ \ \ \ \ \ \ \ \ Httpd_Suspend\ \$sock\ 0\n-\ \ \ \ \ \ \ \ \ \ \ \ fcopy\ \$in\ \$sock\ -command\ \[list\ HttpdCopyDone\ \$in\ \$sock\ \$close\]\n+\ \ \ \ \ \ \ \ \ \ \ \ if\ \{\$data(code)==200\}\ \{\n+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fcopy\ \$in\ \$sock\ -command\ \[list\ HttpdCopyDone\ \$in\ \$sock\ \$close\]\n+\ \ \ \ \ \ \ \ \ \ \ \ \}\ else\ \{\n+\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ fcopy\ \$in\ \$sock\ -size\ \[expr\ \{\$c_end-\$c_start+1\}\]\ -command\ \[list\ HttpdCopyDone\ \$in\ \$sock\ \$close\]\n+\ \ \ \ \ \ \ \ \ \ \ \ \}\n\ \ \ \ \ \ \ \ \ \}\ else\ \{\n\ \ \ \ \ \ \ \ \ \ \ \ \ Httpd_SockClose\ \$sock\ \$close\n\ \ \ \ \ \ \ \ \ \}\ndiff\ -r\ -u\ tclhttpd3.5.1-dist.orig/tclhttpd3.5.1/lib/pkgIndex.tcl\ tclhttpd3.5.1-dist/tclhttpd3.5.1/lib/pkgIndex.tcl\n---\ tclhttpd3.5.1-dist.orig/tclhttpd3.5.1/lib/pkgIndex.tcl\ \ \ \ \ \ \ \ 2004-03-23\ 11:35:15.000000000\ +0200\n+++\ tclhttpd3.5.1-dist/tclhttpd3.5.1/lib/pkgIndex.tcl\ \ \ \ \ \ \ \ 2009-09-20\ 14:52:33.000000000\ +0300\n@@\ -45,5\ +45,6\ @@\n\ \ \ \ \ \ \ \ \ package\ ifneeded\ httpd::url\ 1.2\ \\\[list\ source\ \\\[file\ join\ \[list\ \$dir\]\ url.tcl\\\]\\\]\n\ \ \ \ \ \ \ \ \ package\ ifneeded\ httpd::utils\ 1.0\ \\\[list\ source\ \\\[file\ join\ \[list\ \$dir\]\ utils.tcl\\\]\\\]\n\ \ \ \ \ \ \ \ \ package\ ifneeded\ httpd::version\ 3.5\ \\\[list\ source\ \\\[file\ join\ \[list\ \$dir\]\ version.tcl\\\]\\\]\n+\ \ \ \ \ \ \ \ package\ ifneeded\ httpd::vhost\ 0.1\ \\\[list\ source\ \\\[file\ join\ \[list\ \$dir\]\ vhost.tcl\\\]\\\]\n\ \ \ \ \ \ \ \ \ package\ ifneeded\ tclcrypt\ 1.0\ \\\[list\ source\ \\\[file\ join\ \[list\ \$dir\]\ tclcrypt.tcl\\\]\\\]\n\ \"\ndiff\ -r\ -u\ tclhttpd3.5.1-dist.orig/tclhttpd3.5.1/lib/version.tcl\ tclhttpd3.5.1-dist/tclhttpd3.5.1/lib/version.tcl\n---\ tclhttpd3.5.1-dist.orig/tclhttpd3.5.1/lib/version.tcl\ \ \ \ \ \ \ \ 2004-05-27\ 21:00:52.000000000\ +0300\n+++\ tclhttpd3.5.1-dist/tclhttpd3.5.1/lib/version.tcl\ \ \ \ \ \ \ \ 2009-09-20\ 14:43:56.000000000\ +0300\n@@\ -1,5\ +1,5\ @@\n\ package\ provide\ httpd::version\ 3.5\n\ proc\ Httpd_Version\ \{\}\ \{\n\ \ \ \ \ global\ Httpd\n-\ \ \ \ set\ Httpd(version)\ \ \ \ \ \ \ \ \"3.5.1\ May\ 27,\ 2004\"\n+\ \ \ \ set\ Httpd(version)\ \ \ \ \ \ \ \ \"3.5.1-bdt\ September\ 20,\ 2009\"\n\ \}\ndiff\ -r\ -u\ tclhttpd3.5.1-dist.orig/tclhttpd3.5.1/bin/tclhttpd.rc\ tclhttpd3.5.1-dist/tclhttpd3.5.1/bin/tclhttpd.rc\n---\ tclhttpd3.5.1-dist.orig/tclhttpd3.5.1/bin/tclhttpd.rc\ \ \ \ \ \ \ \ 2009-07-26\ 21:03:55.000000000\ +0300\n+++\ tclhttpd3.5.1-dist/tclhttpd3.5.1/bin/tclhttpd.rc\ \ \ \ \ \ \ \ 2009-09-20\ 16:08:55.000000000\ +0300\n@@\ -40,7\ +40,7\ @@\n\ \ \ \ \ \}\n\ \}\n\ \n-\n+Config\ vhost\ \[list\ \[list\ *host1.org\ host1\ host1-htdocs\]\ \[list\ *\ *\ .\]\]\n\ \n\ #\ main\ -\ Main\ per-thread\ startup\ script.\n\ #\ The\ old\ way\ to\ customize\ the\ server\ was\ to\ modify\ this\ file\ directly.\n---\ /dev/null\ \ \ \ \ \ \ \ 2009-09-18\ 17:04:13.511138139\ +0300\n+++\ tclhttpd3.5.1-dist/tclhttpd3.5.1/lib/vhost.tcl\ \ \ \ \ \ \ \ 2009-09-20\ 16:08:16.000000000\ +0300\n@@\ -0,0\ +1,27\ @@\n+#\ vhost.tcl\n+\n+#\ Virtual\ hosts\ implementation\n+\n+package\ provide\ httpd::vhost\ 0.1\n+\n+set\ vhosts\ \[list\]\n+#\ \[list\ *\ \{return\ \[list\ *\ .\]\}\]\n+\n+proc\ VHost_Add\ \{glob\ name\ dir\}\ \{\n+\ \ \ \ global\ vhosts\n+\ \ \ \ #\ set\ vhosts\ \[linsert\ \$vhosts\ 0\ \$glob\ \[list\ return\ \[list\ \$name\ \$dir\]\]\]\n+\ \ \ \ lappend\ vhosts\ \$glob\ \[list\ return\ \[list\ \$name\ \$dir\]\]\n+\}\n+\n+proc\ VHost_Match\ \{host\}\ \{\n+\ \ \ \ global\ vhosts\n+\ \ \ \ switch\ -glob\ \$host\ \$vhosts\n+\}\n+\n+if\ \{\[cget\ vhost\]==\{\}\}\ \{\n+\ \ \ \ VHost_Add\ *\ *\ .\n+\}\ else\ \{\n+\ \ \ \ foreach\ vh\ \[cget\ vhost\]\ \{\n+\ \ \ \ \ \ \ \ VHost_Add\ \[lindex\ \$vh\ 0\]\ \[lindex\ \$vh\ 1\]\ \[lindex\ \$vh\ 2\]\n+\ \ \ \ \}\n+\}`\n\n\n<<categories>>TclHttpd} CALL {my revision {Tclhttpd range requests and single interpreter virtual hosts support}} CALL {::oo::Obj6773655 process revision/Tclhttpd+range+requests+and+single+interpreter+virtual+hosts+support} CALL {::oo::Obj6773653 process}

-errorcode

NONE

-errorinfo

Unknow state transition: TR -> LINE
    while executing
"error $msg"
    (class "::Wiki" method "render_wikit" line 6)
    invoked from within
"my render_$default_markup $N $C $mkup_rendering_engine"
    (class "::Wiki" method "render" line 8)
    invoked from within
"my render $name $C"
    (class "::Wiki" method "revision" line 31)
    invoked from within
"my revision $page"
    (class "::Wiki" method "process" line 56)
    invoked from within
"$server process [string trim $uri /]"

-errorline

4