#
# Software from the book "Inferno Programming with Limbo"
# published by John Wiley & Sons, January 2003.
#
# p. Stanley-Marbell <pip@gemusehaken.org>
#
implement SimpleHTTPD;
include "sys.m";
include "draw.m";
sys : Sys;
Connection : import Sys;
SimpleHTTPD : module
{
init : fn(nil : ref Draw->Context, nil : list of string);
};
init(nil : ref Draw->Context, nil : list of string)
{
sys = load Sys Sys->PATH;
# First, announce the service. This creates a line directory
# and conn.cfd will be open on the ctl file
(n, conn) := sys->announce("tcp!*!1984");
if (n < 0)
{
sys->print("SimpleHTTPD - announce failed : %r\n");
exit;
}
# Now, listen for incoming connections, spawn new thread
# for each incoming connection.
while (1)
{
listen(conn);
}
}
listen(conn : Connection)
{
buf := array [sys->ATOMICIO] of byte;
(ok, c) := sys->listen(conn);
if (ok < 0)
{
sys->print("SimpleHTTPD - listen failed : %r\n");
exit;
}
# Create a new thread to handle this connection
rfd := sys->open(conn.dir + "/remote", Sys->OREAD);
# The client IP is not yet set at this point. The following will
# therefore show the client IP as 0.0.0.0!0:
n := sys->read(rfd, buf, len buf);
sys->print("SimpleHTTPD : Got new connection from (incomplete) %s\n",
string buf[:n]);
spawn hdlrthread(c);
}
hdlrthread(conn : Connection)
{
buf := array [sys->ATOMICIO] of byte;
# The connections data file is not opened by default,
# must explicitly do so to accept the new connection
rdfd := sys->open(conn.dir + "/data", Sys->OREAD);
wdfd := sys->open(conn.dir + "/data", Sys->OWRITE);
rfd := sys->open(conn.dir + "/remote", Sys->OREAD);
# The client IP is now available, once we have accepted connection.
# The following will print the actual client IP address:
n := sys->read(rfd, buf, len buf);
sys->print("SimpleHTTPD : Got new connection from %s\n",
string buf[:n]);
while (sys->read(rdfd, buf, len buf) >= 0)
{
sys->write(wdfd,
array of byte "<HTML><BODY>Hello!</BODY></HTML>\n",
len "<HTML><BODY>Hello!</BODY></HTML>\n");
return;
}
}
|