+++ /dev/null
-#!/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 = """<?xml version="1.0" encoding="US-ASCII"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
-<head>
-<title>%s</title>
-</head>
-<body>
-<h1>%s</h1>
-<p>%s</p>
-</body>
-</html>
-""" % (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("<!--#", p)
- if p2 < 0:
- sys.stdout.write(line[p:])
- break
- sys.stdout.write(line[p:p2])
- cmd, pars, p = parsecmd(line, p2 + 5)
- if cmd is not None:
- self.docmd(cmd, pars)
-
-if len(sys.argv) < 4:
- sys.stderr.write("usage: serve-ssi METHOD URL REST\n")
- sys.exit(1)
-method, url, rest = sys.argv[1:]
-path = os.getenv("REQ_X_ASH_FILE")
-if path is None:
- sys.stderr.write("serve-ssi: must be called with the X-Ash-File header\n")
- sys.exit(1)
-if rest != "":
- simpleerror(sys.stdout, 404, "Not Found", "The resource specified by the URL does not exist.")
- sys.exit(0)
-
-try:
- try:
- f = ssifile(open(path), url, path)
- except Exception:
- simpleerror(sys.stdout, 500, "Server Error", "The server could not access its data.")
- sys.exit(1)
- try:
- sys.stdout.write("HTTP/1.1 200 OK\n")
- sys.stdout.write("Content-Type: text/html\n")
- sys.stdout.write("\n")
- f.initvars(ssivars)
- f.process()
- finally:
- f.close()
-except IOError:
- # This is for catching EPIPE, when the client has closed the
- # connection. This shouldn't *really* be necessary since the
- # process should terminate with SIGPIPE, but apparently Python
- # ignores that.
- sys.exit(1)