#!/usr/bin/python # This program is quite incomplete. I might complete it with more # features as I need them. It will probably never be entirely # compliant with Apache's version due to architectural differences. import sys, os, time def htmlquote(text): ret = "" for c in text: if c == '&': ret += "&" elif c == '<': ret += "<" elif c == '>': ret += ">" elif c == '"': ret += """ else: ret += c return ret def simpleerror(out, code, title, msg): html = """ %s

%s

%s

""" % (title, title, htmlquote(msg)) out.write("HTTP/1.1 %d %s\n" % (code, title)) out.write("Content-Type: text/html\n") out.write("Content-Length: %d\n" % len(html)) out.write("\n") out.write(html) ssivars = {} def parsecmd(line, p): try: while line[p].isspace(): p += 1 cmd = "" while not line[p].isspace(): cmd += line[p] p += 1 pars = {} while True: while line[p].isspace(): p += 1 if line[p:p + 3] == "-->": return cmd, pars, p + 3 key = "" while line[p].isalnum(): key += line[p] p += 1 if key == "": return None, {}, p while line[p].isspace(): p += 1 if line[p] != '=': continue p += 1 while line[p].isspace(): p += 1 q = line[p] if q != '"' and q != "'" and q != '`': continue val = "" p += 1 while line[p] != q: val += line[p] p += 1 p += 1 pars[key] = val except IndexError: return None, {}, len(line) class ssifile(object): def __init__(self, s, url, path): self.s = s self.url = url self.path = path def close(self): self.s.close(); def initvars(self, vars): now = time.time() vars["DOCUMENT_NAME"] = os.path.basename(self.path) vars["DATE_GMT"] = time.asctime(time.gmtime(now)) vars["DATE_LOCAL"] = time.asctime(time.localtime(now)) vars["LAST_MODIFIED"] = time.asctime(time.localtime(os.stat(self.path).st_mtime)) def includefile(self, path): path = os.path.join(os.path.dirname(self.path), path) try: f = ssifile(open(path), url, path) except Exception: sys.stderr.write("serve-ssi: included file not found: %s\n" % path) return try: f.process() finally: f.close def docmd(self, cmd, pars): if cmd == "include": if "file" in pars: self.includefile(pars["file"]) elif "virtual" in pars: # XXX: For now, just include the file as-is. Change # when necessary. self.includefile(pars["virtual"]) elif cmd == "echo": enc = htmlquote if "encoding" in pars: if pars["encoding"] == "entity": enc = htmlquote if "var" in pars: if pars["var"] in ssivars: sys.stdout.write(enc(ssivars[pars["var"]])) else: sys.stderr.write("serve-ssi: unknown SSI command: %s\n" % cmd) def process(self): for line in self.s: p = 0 while True: p2 = line.find("