Posted to tcl by mjanssen at Mon Jul 02 16:16:39 GMT 2007view pretty
package require html namespace eval scgi { proc listen {port} { socket -server [namespace code connect] $port } proc connect {sock ip port} { fconfigure $sock -blocking 0 -translation {binary crlf} fileevent $sock readable [namespace code [list read_length $sock]] } proc read_length {sock} { set length {} while 1 { set c [read $sock 1] if {[eof $sock]} { close $sock return } if {$c eq ":"} { fileevent $sock readable [namespace code [list read_headers $sock $length {}]] return } append length $c } } proc read_headers {sock length read_data} { append read_data [read $sock] # do we have enough data for the headers yet? if {[string length $read_data] < $length+1} { fileevent $sock readable [namespace code [list read_headers $sock $length $read_data]] return } else { set headers [string range $read_data 0 $length-1] set headers [lrange [split $headers \0] 0 end-1] set body [string range $read_data $length+1 end] set content_length [dict get $headers CONTENT_LENGTH] if {[string length $body] < $content_length} { fileevent $sock readable [namespace code [list read_body $sock $headers $content_length $body]] return } else { handle_request $sock $headers $body } } } proc read_body {sock headers content_length body} { append body [read $sock] if {[string length $body] < $content_length} { fileevent $sock readable [namespace code [list read_body $sock $headers $content_length $body]] return } else { handle_request $sock $headers $body } } proc handle_request {sock headers body} { array set Headers $headers parray Headers puts $sock "Status: 200 OK" puts $sock "Content-Type: text/html" puts $sock "" puts $sock "<HTML>" puts $sock "<BODY>" puts $sock [::html::tableFromArray Headers] puts $sock "</BODY>" puts $sock "<H3>Body</H3>" puts $sock "<PRE>$body</PRE>" puts $sock {<FORM METHOD="post" ACTION="/scgi">} foreach pair [split [dict get $headers QUERY_STRING] &] { lassign [split $pair =] key val puts $sock "$key: [::html::textInput $key $val]<BR>" } puts $sock "<BR>" puts $sock {<INPUT TYPE="submit" VALUE="Try with post">} puts $sock "</FORM>" puts $sock "</HTML>" close $sock } } scgi::listen 9999 vwait forever