###########################################################################
# Copyright (c) 1998, Jeffrey Glen Rennie
# All rights reserved.
###########################################################################
# GLOBALS

set ProxyBadRequestTemplate {HTTP/1.0 400 Bad Request
Content-Type: text/html

<html>
<head>
<title>Bad Request</title>
</head>
<body bgcolor="#f8f8f0" link="#000078" alink="#ff0022" vlink="#787878">
<h1><center><strong>Web <i><font color="red">Smacker</font></i></strong></center></h1>
<p>Your browser has issued a bad HTTP request.  Please contact
jeffrey.rennie@gte.net for support.
<br>And send him a copy of this:
<pre>
%header%
</pre>
</body>
</html>
}

proc ProxyHost {port} {
    dbg::puts socket [socket -server ProxyAccept $port]
}

proc ProxyAccept {sock addr port} {
    dbg::puts socket "Accept $sock from $addr port $port."
    set echo(addr,$sock) [list $addr $port]
    fconfigure $sock -buffering full -blocking 0 -translation { auto crlf } \
	    -eofchar {} -buffersize 1024
    header::ReadRequestHeader $sock ProxyAnalyzeRequestHeader
}

proc ProxyReturnErrorPage { sock result hdr } {
    global ProxyBadRequestTemplate
    if { $result == "PrematureEof" } {
	set header [header::Serialize hdr]
    } else {
	# $result == "NoHeader"
	set header $hdr
    }
    regsub -all %header% $ProxyBadRequestTemplate \
	    $header errorPage
    catch { 
	puts $sock $errorPage
	ProxyCloseSocket $sock ProxyReturnErrorPage
    }
}

proc ProxyAnalyzeRequestHeader {sock result hdr} {
    if { $result == "NoHeader" } {
	ProxyReturnErrorPage $sock $result $hdr
	return
    } elseif { $result == "PrematureEof" } {
	ProxyCloseSocket $sock ProxyAnalyzeRequestHeader
	return
    }
    # else
    header::RemoveOption hdr Proxy-Connection
    if { [header::ExistOption hdr Content-Length] && \
	    [header::GetOption hdr Content-Length] > 0 } {
	fileevent $sock readable [list ProxyReceivePostDoc $sock $hdr \
		[header::GetOption hdr Content-Length] {} ]
    } else {
	ProxyForwardRequest $sock $hdr
    }
}	

proc ProxyDoneRequest { sock wasClosed } {
    if !$wasClosed {
	if [ catch { 
	    # make sure the sock is read to deal with http headers:
	    fconfigure $sock -translation {auto crlf}
	} err] {
	    dbg::puts server $err
	    catch { ProxyCloseSocket $sock ProxyDoneRequest }
	} else {
	    header::ReadRequestHeader $sock ProxyAnalyzeRequestHeader
	}
    }
}

# args would be the query
proc ProxyForwardRequest { sock hdr args } {
    fileevent $sock readable {}
    if [llength $args] {
	chat::Request $hdr $sock ProxyDoneRequest [lindex $args 0]
    } else {
	chat::Request $hdr $sock ProxyDoneRequest
    }	
}

proc ProxyReceivePostDoc { sock hdr length query} {
    if {[eof $sock] || [catch {set line \
	    [read  $sock $length ]}]} {
	# end of file or abnormal connection drop
	ProxyCloseSocket $sock ReceivePostDoc
    } else {
	append query $line
	dbg::puts server "cl: $line"	
	incr length -[string length $line]
	if { $length <= 0 } {
	    dbg::puts server "Received Full content length."
	    fconfigure $sock -translation { auto crlf}
	    ProxyForwardRequest $sock $hdr $query
	} else {
	    # get ready for next block
	    fileevent $sock readable [list ProxyReceivePostDoc \
		    $sock $hdr $length $query]
	}
    }
}
    
proc ProxyCloseSocket {sock function args} {
    dbg::puts socket "Closing $sock in $function."    
    catch { close $sock }
}
###########################################################################
# Copyright (c) 1998, Jeffrey Glen Rennie
# All rights reserved.
###########################################################################
