#!../../src/xotclsh
# $Id: s.webserver.xotcl 1.8 01/03/23 22:00:52+01:00 neumann@somewhere.wu-wien.ac.at $
@ @File {
  description {
    This small demo program starts two different webservers:
    <ul>
    <li>Firstly, it provides a sample web server that povides the documents in 
    ../../src/doc (or the files specified with -root) at port 8086 
    (or at the port specified via the -port option) as unprotected resources.
    <p>
    <li>Secondly, it starts a second webserver with basic access control
    (it accepts test/test as user/password) on port 9096 (or on the
    port specified via -protected-port). If it receives an request
    for an resource named "exit", it terminates. For all other requests
    it returns actual information about the user and the issued request.
    </ul>
    To see, how it works, contact it e.g. from netscape.
  }
}

# We load the following packages:
#
package require xotcl::comm::httpd
#
# we set the default for document root to ../../src/doc and port to 8086
#
array set opts {-root ../../doc -port 8086 -protected-port 9096}
array set opts $argv

# now we can start the web-server instance with these settings
#
Httpd h1 -port $opts(-port) -root $opts(-root)
@ Httpd h1 {description "unprotected web server"}

# specialized worker, which executes tcl commands in web pages
@ Class SpecializedWorker { description {
  Specialized worker that can be passed to any webserver
}}
Class SpecializedWorker -superclass Httpd::Wrk
@ SpecializedWorker instproc respond {} { description {
  This method handles all responses from the webserver to the client.
  We implent here "exit", and we return the information about the  actual 
  request and  user in HTML format for all other requests.
  <p>This method is an example, how to access on the server side 
  request specific infomation.
}}
SpecializedWorker instproc respond {} {
  if {[[self] set resourceName] == "exit"} {
    set ::forever 1
    #[self] showVars
    #[self] set version 1.0;### ???? 
    #puts stderr HERE
  }
  # return for all other requests the same response
  foreach {a v} [[self] array get meta] {
    append m <tr><td><em>$a</em></td><td>$v</td></tr>\n
  }
  set content {
    <HTML><BODY>
    <h3>Request Info</h3>
    <table>
    <tr><td><em>method:</em></td><td>[[self] set method]</td></tr>
    <tr><td><em>resource:</em></td><td>[[self] set resourceName]</td></tr>
    <tr><td><em>user:</em></td><td>[[self] set user]</td></tr>
    <tr><td><em>version:</em></td><td>HTTP/[[self] set version]</td></tr>
    <tr><td><em>response port:</em></td><td>[[self] set port]</td></tr>
    <tr><td><em>request comes from:</em></td><td>[[self] set ipaddr]</td></tr>
    </table>
    <h3>Request Header Fields</h3>
    <table>$m</table>
    </BODY></HTML>
  }
  set c [subst $content]
  [self] replyCode 200
  [self]::c puts "Content-Type: text/html"
  [self]::c puts "Content-Length: [string length $c]\n"
  [self]::c puts-nonewline $c
  [self] close
}

@ Httpd h2 {
  description "Web server with basic authentication using the specialied worker"}

if {[info exists env(USER)]} {
  set USER $env(USER)
} elseif {[info exists env(USERNAME)]} {
  set USER $env(USERNAME)
} else {
  set USER unknown
}

Httpd h2 -port $opts(-protected-port) -root $opts(-root) \
    -httpdWrk SpecializedWorker \
    -mixin BasicAccessControl \
    -addRealmEntry test "u1 test $USER test"  -protectDir test "" {} 

#
# and finally call the event loop... 
#
vwait forever
