From 6d94a5f6850e75a9d96e9a54845fea5ffe3ed024 Mon Sep 17 00:00:00 2001 From: Fredrik Tolf Date: Mon, 30 Aug 2010 16:49:04 +0200 Subject: [PATCH] Added a simple python program for processing SSI. --- python/serve-ssi | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100755 python/serve-ssi diff --git a/python/serve-ssi b/python/serve-ssi new file mode 100755 index 0000000..bbf7188 --- /dev/null +++ b/python/serve-ssi @@ -0,0 +1,166 @@ +#!/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("