new object $http: $libraries; var $http codes = #[[200, "Ok"], [201, "Created"], [202, "Accepted"], [203, "Provisional Information"], [204, "No Content"], [300, "Multiple Choices"], [301, "Moved Permanently"], [302, "Moved Temporarily"], [303, "See Other"], [304, "Not Modified"], [400, "Bad Request"], [401, "Unauthorized"], [402, "Payment Required"], [403, "Forbidden"], [404, "Not Found"], [405, "Method Not Allowed"], [406, "None Acceptable"], [407, "Proxy Authentication Required"], [408, "Request Timeout"], [409, "Conflict"], [410, "Gone"], [500, "Internal Server Error"], [501, "Not Implemented"], [502, "Bad Gateway"], [503, "Service Unavailable"], [504, "Gateway Timeout"]]; var $http errors = #[[400, ["<head><title>400 Bad Request</title></head>", "<body>", "<center><h1>400 Bad Request</h1></center>", "%s", "</body>"]], [403, ["<head><title>403 Permission Denied</title></head>", "<body>", "<center><h1>403 Permission Denied</h1></center>", "%s", "</body>"]], [404, ["<head><title>404 Not Found</title></head>", "<center><h1>404 Not Found</h1></center>", "%s", "</body>"]]]; var $http gateways = #[["describe", "describe?target=the_pit"], ["see", "see?target=the_pit"], ["who", "who"], ["display", "display?target=http"], ["list_method", "list_method?target=%24http.list_method"], ["help", "help?node=help_coldcore"], ["object", "object?target=http"]]; var $http html_version = "text/html"; var $http http_methods = ["GET"]; var $http page_head = []; var $root created_on = 796268969; var $root flags = ['methods, 'code, 'variables, 'core]; var $root inited = 1; var $root managed = [$http]; var $root manager = $http; public method ._show_header_objs() { arg objs, what; var o, line; if ((objs.length()) > 1) { line = (("<b>" + what) + "s</b>: ") + (.make_object_href(objs[1])); for o in (objs.subrange(2)) line += ", " + (.make_object_href(o)); line += "<br>"; } else if ((objs.length()) == 1) { line = (("<b>" + what) + "</b>: ") + (.make_object_href(objs[1])); } else { line = ("<b>" + what) + "</b>: (none)<br>"; } return line; }; public method ._show_methods() { arg obj; var methods, types, m, t, out; types = #[]; for m in (obj.methods()) types = types.add_elem(obj.method_access(m), [m] + (obj.method_info(m))); // hard-listing the types guarantee's their order out = []; for t in (['root, 'driver, 'public, 'protected, 'private]) { if (!(types.contains(t))) continue; out += [(tostr(t).capitalize()) + " methods:"]; for m in (types[t]) out += [strfmt("%5l %4r " + (.make_method_href([obj, m[1], m[2]])), $object_lib.parse_method_flags(m[7]), m[5])]; } return out; }; public method ._show_variables() { arg obj; var parent, out, v; out = []; for parent in (obj.data()) { if (valid(parent[1])) { out += [(parent[1]) + " variables:"]; if ((parent[1]).has_flag('variables, this())) { for v in (parent[2]) out += [((" " + (v[1])) + ": ") + toliteral(v[2])]; } else { out += [" ** Permission Denied **"]; } } else { out += [($object_lib.get_name(parent[1])) + " variables:"]; for v in (parent[2]) out += [((" " + (v[1])) + ": ") + toliteral(v[2])]; } refresh(); } return out; }; public method .bin_describe() { arg path, info, header; var obj, desc, flags, detail, page, body, name; obj = (| (info['args])["target"] |); if (!obj) return [400, .response(400, "Must specify a target object")]; obj = (| $object_lib.to_dbref(obj) |) || (| $user_db.search(obj) |); if (!obj) return [404, .response(404, ("Unable to find object \"" + ((info['args])["target"])) + "\"")]; detail = (| (info['args])["detail"] |); if (detail) { detail = $http.decode(detail); name = ((obj.name()) + ": ") + detail; catch any body = (<$ctext_frob, [[(<$format, ["subj", [["level", "2"]], [detail.capitalize()], 'do_subj]>)], #[['this, obj]]]>).append(obj.get_detail(detail)); with body = $http.response(404, ("No such detail '" + detail) + "'"); } else { name = obj.name(); body = obj.get_description(#[['actor, $no_one]]); } return [200, .build_page(body, name)]; }; public method .bin_display() { arg path, info, header; var out, obj, what, args; args = info['args]; obj = (| args["target"] |); if (!obj) return [400, .response(400, "Must specify a target object")]; obj = (| $object_lib.to_dbref(obj) |); if (!obj) return [404, .response(404, ("Unable to find object \"" + (args["target"])) + "\"")]; what = []; if ((| args["vars"] |)) what = setadd(what, 'vars); if ((| args["methods"] |)) what = setadd(what, 'methods); return [200, .show_object(obj, what)]; }; public method .bin_help() { arg path, info, header; var node, head, tail, cout, list, n, out, name; node = (| (info['args])["node"] |); if (!node) node = "help_coldcore"; catch ~namenf node = (> $object_lib.to_dbref(node) <); with return [404, .response(404, "Unable to find help node: " + ((info['args])["node"]))]; head = strings_to_buf([("<head><title>Help: " + (node.node_name())) + "</title></head>", page_body, ("<h2 align=center>" + (node.html_node_name('top))) + "</h2><hr size=1 noshade>"]); cout = $parse_lib.filter_ctext(node.body(), #[['formatter, $html_format], ['node, tostr(node)]]); tail = "<p><hr size=1 noshade><p align=center>"; if (node.group()) { out = ""; for n in (((node.parents())[1]).children()) { if (n.nolist()) continue; name = (n.name()).word(1, "|"); if (n == node) out += ((out ? "| " : "") + name) + " "; else if (n.holder()) out += (((out ? "| " : "") + "<i>") + name) + "</i> "; else out += (((((out ? "| " : "") + "<a href=\"/bin/help?node=") + n) + "\">") + name) + "</a> "; } if (out) tail += out; } tail = str_to_buf(tail + "\n"); switch (type(cout)) { case 'string: cout = [cout]; case 'frob: cout = `[]; } return [200, (head + cout) + tail]; }; public method .bin_list_method() { arg path, info, header; var ref, str_ref, name, obj, code, anc, out, line, x; ref = (| (info['args])["target"] |); if (!ref) return [400, .response(400, "Must specify a target method reference")]; catch any { ref = $parse_lib.ref($http.decode(ref), $foundation); name = (> tosym(ref[4]) <); obj = ref[3]; anc = obj.find_method(name); code = map x in (anc.list_method(name)) to (x.html_escape()); str_ref = ((obj + ".") + name) + "()"; out = [("<head><title>" + str_ref) + "</title></head>", page_body, ("<center><h1>" + str_ref) + "</h1></center>", "<hr size=1 noshade><pre>", @code, "</pre>"]; } with { switch (error()) { case ~type: return [400, ((("Invalid method reference " + obj) + ".") + name) + "()"]; case ~methodnf: line = ((obj + ".") + name) + "()"; return [400, .response(400, line + " not found.")]; default: return [400, .response(400, (traceback()[1])[2])]; } } return [200, out]; }; public method .bin_object() { arg path, info, header; var out, obj, o, line, objs, m; obj = (| (info['args])["target"] |); if (!obj) return [400, .response(400, "Must specify a target object")]; obj = (| $object_lib.to_dbref(obj) |); if (!obj) return [404, .response(404, ("Unable to find object \"" + ((info['args])["target"])) + "\"")]; out = [("<head><title>" + (obj.namef('xref))) + "</title></head>", page_body, ("<h1 align=center>" + (.make_display_href(obj, "&methods"))) + "</h1>"]; line = "<p align=center><b>Parent(s)</b>: " + ((| .make_object_href((obj.parents())[1]) |) || "(none)"); for o in ((| (obj.parents()).subrange(2) |) || []) line += ", " + (.make_object_href(o)); out += [line + "</p>", "<pre>"]; objs = obj.children(); if (obj) { out += ["<p align=center><b>Children:</b></p>", "Name Perms Size Manager"]; for o in (objs) { m = o.manager(); if (!valid(o)) m = toliteral(m); else m = .make_object_href(m); out += [((((((((("<a href=\"/bin/object?target=" + (o.objname())) + "\">") + pad(o.namef('xref), 36)) + "</a>") + " ") + (($object_lib.see_perms(o, ["", ""])).pad(5))) + " ") + (((o.size()).to_english()).pad(8))) + " ") + m]; } } return [200, out + ["</pre>"]]; }; public method .bin_see() { arg @args; return [400, .response(400, "VRML support is pending completion, sorry!")]; }; public method .bin_who() { arg @args; var who, namel, names, times, idle, realm, x, cols, out, output, line; out = [("<head><title>Connected users to " + ($motd.server_name())) + "</title></head>", page_body, ("<center><h2>Connected users to <i>" + ($motd.server_name())) + "</i></h2></center></head><body><pre>"]; who = $user_db.connected(); names = who.mmap('hname); namel = []; for x in (who.mmap('name)) namel += [x.length()]; cols = (namel.max()) + 1; if (cols < 5) cols = 5; times = who.mmap('connected_time); cols = [cols, (times.element_maxlength()) + 1]; if ((cols[2]) < 7) cols = [cols[1], 7]; idle = who.mmap('idle_time); cols += [(idle.element_maxlength()) + 1]; if ((cols[3]) < 5) cols = cols.replace(3, 5); realm = who.mmap('realm_name, "text/html"); out += [((((("<hr size=1 noshade><b>" + ("Name".pad(cols[1]))) + " ") + ("On for".pad(cols[2]))) + " ") + ("Idle".pad(cols[3]))) + " Location", ((((("----".pad(cols[1])) + " ") + ("------".pad(cols[2]))) + " ") + ("----".pad(cols[3]))) + " --------</b>"]; for x in [1 .. who.length()] { line = ((("<b>" + (names[x])) + "</b>") + ("".pad((cols[1]) - (namel[x])))) + " "; line = (((line + "<i>") + (times[x])) + ("".pad((cols[2]) - ((times[x]).length())))) + " "; line = (((line + (idle[x])) + "</i>") + ("".pad((cols[3]) - ((idle[x]).length())))) + " "; line += realm[x]; out += [line]; } return [200, out]; }; public method .build_page() { arg what, name; var out; return (((`[60, 104, 101, 97, 100, 62, 60, 116, 105, 116, 108, 101, 62] + str_to_buf(name)) + `[60, 47, 116, 105, 116, 108, 101, 62, 60, 47, 104, 101, 97, 100, 62]) + str_to_buf(page_body)) + (.process_text(what)); }; public method .decode(): native; public method .encode(): native; public method .gateways() { return gateways; }; public method .html_version() { return html_version; }; public method .http_methods() { return http_methods; }; public method .list_gateways() { var out, line, gate; out = ["<ul>"]; for gate in (gateways) { line = ((("<li><b><a href=\"/bin/" + (gate[2])) + "\">") + (gate[1])) + "</a></b>"; out += [line]; } return out + ["</ul>"]; }; public method .make_display_href() { arg obj, @args; args = args ? (args.join("")) : ""; return (((("<a href=\"/bin/display?target=" + (obj.objname())) + args) + "\">") + (obj.namef('xref))) + "</a>"; }; public method .make_href() { arg obj, @args; var line, oname, method, name; oname = obj.objname(); if (listlen(args)) name = args[1]; else name = ("<code>$" + oname) + "</code>"; if (listlen(args) > 1) method = args[2]; else method = "/bin/show?target=" + oname; return ((("<a href=\"" + method) + "\">") + name) + "</a>"; }; public method .make_method_href() { arg m; return ((((((("<a href=\"/bin/list_method?target=%%24" + ((m[1]).objname())) + ".") + (m[2])) + "()\">.") + (m[2])) + "(") + (m[3])) + ")</a>"; }; public method .make_obj_show_href() { arg obj, @name; var line, oname; name = name ? name : (("<code>" + obj) + "</code>"); return ((("<a href=\"/bin/show?target=" + (obj.objname())) + "\">") + name) + "</a>"; }; public method .make_object_href() { arg obj; return ((("<code><a href=\"/bin/object?target=" + (obj.objname())) + "\">") + (obj.namef('xref))) + "</a></code>"; }; public method .page_body() { return page_body; }; public method .page_head() { return page_head; }; public method .page_tail() { arg @args; var tail; tail = ("<hr size=1 noshade><a href=\"/\"><b>" + ($motd.server_name())) + "</b></a>"; if (args) return str_to_buf(tail); return [tail]; }; public method .process_bin_request() { arg @path; var gate, who; if (!path) { return ["text/html", .list_gateways()]; } else { gate = path[1]; path = path.subrange(2); if ("?" in gate) { path = [gate.subrange(("?" in gate) + 1), @path]; gate = gate.subrange(1, ("?" in gate) - 1); } if (!(gate in (gateways.keys()))) return ["text/html", .get_error(400, ("Unknown gateway \"" + gate) + "\".")]; return ["text/html", .(tosym("bin_" + gate))(@path)]; } }; public method .process_text() { arg what; var out, l, b; switch (type(what)) { case 'frob: return $parse_lib.filter_ctext(what, #[['formatter, $html_format]]); case 'list: out = `[]; for l in (what) out += .process_text(l); return out; case 'string: // "<br>" == `[60, 98, 114, 62] return str_to_buf(what) + `[60, 98, 114, 62, 13, 10]; } }; public method .response() { arg code, message; var name, x; if (!(name = (| codes[code] |))) return .response(500, "We had a booboo! Invalid code: " + tostr(code)); if (type(message) == 'string) message = [("<p align=center>" + message) + "</p>"]; return [((("<head><title>" + tostr(code)) + " ") + name) + "</title></head>", page_body, ((("<h1 align=center>" + tostr(code)) + " ") + name) + "</h1>", "<hr size=1 noshade>", @message, @.page_tail()]; }; public method .show_object() { arg obj, what; var out; out = [("<head><title>ColdC Object Display of " + obj) + "</title></head>", page_body, ("<h1>" + obj) + "</h1>", ("<b>Perms</b>: " + (((.flags()).prefix("+")).join())) + "<br>", ("<b>Size</b>: " + ((obj.size()).to_english())) + " bytes (on disk)<br>", ("<b>Manager</b>: " + (.make_object_href(obj))) + "<br>", ._show_header_objs(obj.writers('literal), "Writer"), ._show_header_objs(obj.parents(), "Parent")]; if (obj.has_ancestor($located)) out += [("<b>Location</b>: " + (.make_object_href(obj.location()))) + "<br>"]; out += ["<p><pre>"]; if ('methods in what) { if (!(obj.has_flag('methods, this()))) out += [" ** No permission to list methods **"]; else out += ._show_methods(obj); } else { out += [(((((" <h3><a href=\"/bin/display?target=" + obj) + "&") + ((['methods] + what).join("=yes&"))) + "=yes\">Display Methods on ") + obj) + "</a></h3>"]; } if ('vars in what) { if (!(obj.has_flag('vars, this()))) out += [" ** No permission to show variables **"]; else out += ._show_variables(obj); } else { out += [(((((" <h3><a href=\"/bin/display?target=" + obj) + "&") + ((what + ['vars]).join("=yes&"))) + "=yes\">Display Variables on ") + obj) + "</a></h3>"]; } return out + ["</pre>"]; };