parent $connection_interfaces object $http_interface var $root dbref 'http_interface var $root child_index 3435 var $root fertile 1 var $root manager $http_interface var $root owned [$http_interface] var $root owners [$http_interface] var $root writable [] var $root readable ['parameters, 'methods, 'code] var $has_commands commands [["GET *", 'get_cmd]] var $has_commands shortcuts [] var $connection_interfaces connection 0 var $root inited 1 var $http_interface uri "" var $http_interface header #[] var $http_interface http_version "" var $http_interface method "" var $http_interface status 0 var $old_command_environment verb_cache #[] var $old_command_environment command_cache [["GET *", 'get_cmd]] var $old_command_environment shortcuts_cache [] method init_http_interface (> .perms(caller(), $root) <); status = 0; uri = ""; header = #[]; http_version = ""; method = ""; . method get_cmd arg cmd, line; if (status == 0) { if (!line) { line = "Invalid use of method GET."; .send_response($http.get_error(403, line)); return 'disconnect; } line = explode(line); if (listlen(line) > 1) http_version = line[2]; else http_version = "HTTP/1.0"; uri = line[1]; method = "GET"; status = 1; } else { line = "Method GET already received!"; .send_response($http.get_error(400, line)); return 'disconnect; } . method invalid_cmd arg line; var lines; if (status == 1) { // I had it set to be just ":" but I think spaces should be in them. line = explode(line, ": "); if (listlen(line) == 1) line = [@line, ""]; else if (listlen(line) > 2) line = [line[1], $list.to_string(sublist(line, 2))]; header = header.add_elem(line[1], line[2]); } else { line = ("Invalid method: \"" + line) + "\"."; .send_response($http.get_error(400, line)); return 'disconnect; } . method send_response arg body, [args]; var types, buffer, c; types = [@args, "text/html"][1]; switch (type(body)) { case 'list: buffer = $list.to_buffer(body); case 'buffer: buffer = body; } c = .connection(); c.send("HTTP/1.0 200 OK"); c.send("Server: ColdWeb/0.1"); c.send("Content-type: " + types); c.send("Content-length: " + tostr(buffer_len(buffer))); c.send(""); c.echo(buffer, 'buffer); .log_request(buffer_len(buffer)); . method error arg error, str; var lines, x; lines = (| errors[error] |) || ["Oops, server just broke."]; for x in (lines) strsub(x, "%s", str).send_response(lines); . method uninit_http_interface (> .perms(caller(), $root) <); uri = ""; header = #[]; http_version = ""; method = ""; . method null_cmd arg line; .process_http_method(); return (> pass(line) <); . method log_request arg content_length; var line, c, agent; // was going to have this be like the standard logfile, but decided // I didn't like that c = .connection(); line = c.address(); agent = (| ((.header())["User-Agent"])[1] |) || ""; line = (((((((line + " \"") + method) + " ") + uri) + " ") + http_version) + "\" ") + agent; $http_log.log(line); . method process_GET var path, output, object, line, bin, ctype; (> .perms(sender(), 'this) <); // Ok, we are going to interpret the URI in funky ways. path = explode(uri, "/"); ctype = "text/html"; if (!path) { output = ($login.build_html()) + ($http_root_file.retrieve_html()); } else if (((path[1])[1]) == "~") { object = (| $user_db.find(substr(path[1], 2)) |); output = (| object.http_request(method, sublist(path, 2)) |); } else if ((path[1]) == "objects") { object = (| $object.to_dbref(path[2]) |); output = (| object.generate_html(@sublist(path, 3)) |); } else if (match_begin("bin", path[1])) { if (listlen(path) > 2) line = $list.to_string(sublist(path, 3)); if ("?" in (path[2])) { line = substr(path[2], ("?" in (path[2])) + 1) + (line || ""); bin = substr(path[2], 1, ("?" in (path[2])) - 1); } else { bin = path[2]; } output = (| $http.(tosym("bin_" + bin))(line) |); } else { object = $http_root_file.find_file([$http_root_file.filename(), @path]); output = (| object.retrieve_html() |); ctype = (| object.content_type() |); } if (!output) { line = ("Unable to find " + uri) + "."; output = $http.get_error(404, line); } // intentionally add the tail here, we can slap tCD comments // at the end. if (ctype == "text/html") output = output + ["<hr size=4><a href=\"/\"><b>the Cold Dark</b></a></body>"]; else if (ctype == "text/plain") output = output + ["-------------", "the Cold Dark"]; .send_response(output, ctype); . method process_http_method (> .perms(sender(), 'this) <); .(tosym("process_" + method))(); . method header return header; .