Merge branch 'master' of fludd.seatribe.se:/usr/local/src/ashd
[ashd.git] / python3 / serve-ssi
CommitLineData
0b6f220f
FT
1#!/usr/bin/python3
2
3import sys, os, io, logging
4import ashd.ssi, ashd.wsgiutil
5
6def simpleerror(out, code, title, msg):
7 html = """<?xml version="1.0" encoding="US-ASCII"?>
8<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
9<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
10<head>
11<title>%s</title>
12</head>
13<body>
14<h1>%s</h1>
15<p>%s</p>
16</body>
17</html>
18""" % (title, title, ashd.wsgiutil.htmlquote(msg))
19 out.write("HTTP/1.1 %d %s\n" % (code, title))
20 out.write("Content-Type: text/html\n")
21 out.write("Content-Length: %d\n" % len(html))
22 out.write("\n")
23 out.write(html)
24
25if len(sys.argv) < 4:
26 sys.stderr.write("usage: serve-ssi METHOD URL REST\n")
27 sys.exit(1)
28method, url, rest = sys.argv[1:]
29path = os.getenv("REQ_X_ASH_FILE")
30if path is None:
31 simpleerror(sys.stdout, 500, "Server Error", "The server is erroneously configured.")
32 sys.stderr.write("serve-ssi: must be called with the X-Ash-File header\n")
33 sys.exit(1)
34if rest != "":
35 simpleerror(sys.stdout, 404, "Not Found", "The resource specified by the URL does not exist.")
36 sys.exit(0)
37
38class encwrap(io.TextIOWrapper):
39 def close(self):
40 pass
41
42logging.basicConfig(format="serve-ssi: %(message)s")
43try:
44 try:
45 f = ashd.ssi.getfile(path)
46 except Exception as e:
47 sys.stderr.write("server-ssi: %s\n" % e)
48 simpleerror(sys.stdout, 500, "Server Error", "The server could not access its data.")
49 sys.exit(1)
50 sys.stdout.write("HTTP/1.1 200 OK\n")
51 sys.stdout.write("Content-Type: text/html; charset=UTF-8\n")
52 sys.stdout.write("\n")
53 sys.stdout.flush()
54 wrap = encwrap(sys.stdout.buffer, encoding="utf8")
55 f.process(ashd.ssi.context(wrap, f))
56 wrap.flush()
57except IOError:
58 # This is for catching EPIPE, when the client has closed the
59 # connection. This shouldn't *really* be necessary since the
60 # process should terminate with SIGPIPE, but apparently Python
61 # ignores that.
62 sys.exit(1)