// ------------------------------------------------------------------
// Object $http
parent $daemon
object $http
var $http header #[]
var $http method ""
var $http http ""
var $http status 0
var $http URI ""
var $http bytes 0
var $http ctype ""
var $http full 0
method initialize
(| pass() |);
header = #[];
method = "";
http = "HTTP/1.0";
status = 200;
URI = "";
ctype = $sys.htmlv();
full = 1;
.
method set_status
arg status;
set_var('status, status);
.
method process_header
arg line, i;
var n, v;
if (!method) {
status = 400;
return .respond($sys.response(400, "No Method Specified!"));
}
n = substr(line, 1, i - 1);
if (line[i + 1] == " ")
i = i + 1;
v = substr(line, i + 1);
header = header.add_elem(n, v);
.
method process_method
arg line;
line = explode(line);
if (!(line[1] in $sys.methods())) {
status = 405;
return .respond($sys.response(status,
"Method: \"" + line[1] + "\"."));
}
method = line[1];
line = delete(line, 1);
if (!line) {
status = 400;
return .respond($sys.response(status, "No URI specified!"));
}
URI = line[1];
if (listlen(line) > 1) {
http = line[2];
} else {
http = "HTTP/0.9";
full = 0;
}
.
method handle_method
if (!method) {
status = 400;
return .respond($sys.response(status, "No Method specified!"));
}
.(tosym("method_" + method))();
.
method process_line;
arg line;
var i;
if (i = (":" in line)) {
.process_header(line, i);
} else if (line) {
// if return's false, it is a simple request, do not wait for CR
.process_method(line);
if (!full) {
if (method != "GET") {
status = 400;
.respond($sys.response(status, "Invalid HTTP/0.9 method."));
} else
.handle_method();
}
} else {
.handle_method();
}
.
method log_request
var line;
line = .host() + " - - [" + timestamp() + "] \"" + method + " " +
URI + " " + http + "\" " + tostr(status) + " " + tostr(bytes);
if ((| header["User-Agent"] |))
line = line + ";; " + header["User-Agent"].to_string();
.lwrite(line);
.
method send_header
if (full)
.send([http + " " + tostr(status),
"Server: ColdWeb/0.2",
"Content-type: " + ctype,
"Content-length: " + tostr(bytes),
""]);
.
method respond
arg body;
if (type(body) != 'buffer)
body = buffer_from_strings(body);
bytes = buffer_len(body);
.send_header();
echo(body);
.close();
.log_request();
.
method respond_with_file
arg fstat;
bytes = fstat[2];
.send_header();
echo_file(URI);
.close();
.log_request();
.
method find_filename
var file, actual, stat, ifiles, i;
stat = (| stat_file(URI) |);
if (!stat) {
ifiles = ["home.html", "index.html", "welcome.html"];
file = URI;
actual = URI;
if (file[strlen(file)] != "/")
file = file + "/";
while (!stat && ifiles) {
URI = file + ifiles[1];
stat = (| stat_file(URI) |);
ifiles = delete(ifiles, 1);
}
if (!stat) {
URI = actual;
status = 404;
.respond($sys.response(status,
"Unable to find URL " + toliteral(URI) + "."));
return 0;
}
}
if (i = URI.rindex(".")) {
switch (substr(URI, i + 1)) {
case "txt":
ctype = "text/plain";
case "gif":
ctype = "image/gif";
}
}
return stat;
.
method method_GET
var stat;
if (!stat = .find_filename())
return;
.respond_with_file(stat);
.
method method_HEAD
var stat;
if (!(stat = .find_filename()))
return;
bytes = stat[2];
.send_header();
.close();
.log_request();
.respond_with_file(stat);
.