## Some handy regular expressions.
R_URLESC = RX.compile('%([0-9a-fA-F]{2})')
R_URLBAD = RX.compile('[^-\\w,.!]')
-R_HTMLBAD = RX.compile('[&<>]')
+R_HTMLBAD = RX.compile('[&<>\'"]')
def urldecode(s):
"""Decode a single form-url-encoded string S."""
## Some standard character sequences, and HTML entity names for prettier
## versions.
-_quotify = U.StringSubst({
+html_quotify = U.StringSubst({
+ "<": '<',
+ ">": '>',
+ "&": '&',
"`": '‘',
"'": '’',
+ '"': '"',
"``": '“',
"''": '”',
"--": '–',
"---": '—'
})
-def html_quotify(s):
- """Return a pretty HTML version of S."""
- return _quotify(htmlescape(s))
###--------------------------------------------------------------------------
### Output machinery.
T.gmtime(U.NOW + maxage))
return '; '.join(['%s=%s' % (urlencode(name), urlencode(value))] +
[v is not True and '%s=%s' % (k, v) or k
- for k, v in attr.iteritems()])
+ for k, v in attr.iteritems() if v])
def action(*v, **kw):
"""
"""Build a URL for the static file NAME."""
return htmlescape(CFG.STATIC + '/' + name)
-@CTX.contextmanager
-def html(title, **kw):
- """
- Context manager for HTML output.
-
- Keyword arguments are output as HTTP headers (if no header has been written
- yet). A `<head>' element is written, and a `<body>' opened, before the
- context body is executed; the elements are closed off properly at the end.
- """
-
- kw = dict(kw, content_type = 'text/html')
- OUT.header(**kw)
-
- ## Write the HTML header.
- PRINT("""\
-<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN'
- 'http://www.w3c.org/TR/html4/strict.dtd'>
-<html>
-<head>
- <title>%(title)s</title>
- <link rel=stylesheet type='text/css' media=screen href='%(style)s'>
- <meta http-equiv='Content-Script-Type' content='text/javascript'>
- <script type='text/javascript' src='%(script)s'></script>
-</head>""" % dict(title = html_quotify(title),
- style = static('chpwd.css'),
- script = static('chpwd.js')))
-
- ## Write the body.
- PRINT('<body>')
- yield None
- PRINT('''\
-
-<div class=credits>
- <a href="%(about)s">Chopwood</a>, version %(version)s:
- copyright © 2012 Mark Wooding
-</div>
-
-</body>
-</html>''' % dict(about = static('about.html'),
- version = VERSION))
-
def redirect(where, **kw):
"""
Write a complete redirection to some other URL.
"""
~H: escape output suitable for inclusion in HTML.
- With `:', instead apply form-urlencoding.
+ With `:', additionally apply quotification.
"""
def _convert(me, arg):
if me.colonp: return html_quotify(arg)
if hook: hook()
if isinstance(e, U.ExpectedError) and not OUT.headerp:
page('error.fhtml',
- headers = dict(status = e.code),
+ header = dict(status = e.code),
title = 'Chopwood: error', error = e)
else:
exty, exval, extb = SYS.exc_info()
format_tmpl(TMPL['exception.fhtml'], toplevel = False)
else:
page('exception.fhtml',
- headers = dict(status = 500),
+ header = dict(status = 500),
title = 'Chopwood: internal error',
toplevel = True)
PARAM = []
PARAMDICT = {}
PATH = []
+SSLP = False
## Regular expressions for splitting apart query and cookie strings.
R_QSPLIT = RX.compile('[;&]')
`PATH'
The trailing `PATH_INFO' path, split at `/' markers, with any
trailing empty component removed.
+
+ `SSLP'
+ True if the client connection is carried over SSL or TLS.
"""
+ global SSLP
+
def getenv(var):
try: return ENV[var]
except KeyError: raise U.ExpectedError, (500, "No `%s' supplied" % var)
if pp and not pp[-1]: pp.pop()
PATH[:] = pp
+ ## Check the crypto for the connection.
+ if ENV.get('SSL_PROTOCOL'):
+ SSLP = True
+
###--------------------------------------------------------------------------
### CGI subcommands.