Skip to content
Commits on Source (5)
......@@ -7,7 +7,8 @@ import re
import security_db
from web_support import *
import json
from datetime import datetime
import time
import email.utils
if __name__ == "__main__":
if len(sys.argv) not in (3, 5):
......@@ -1298,8 +1299,8 @@ Debian bug number.'''),
self.json_generation_interval seconds ago """
if self.json_timestamp: # we've generated the JSON at least once
delta = datetime.now() - self.json_timestamp
if delta.total_seconds() <= self.json_generation_interval:
delta = time.time() - self.json_timestamp
if delta <= self.json_generation_interval:
# not expired yet, serve the cached data
return self.json_data
......@@ -1450,15 +1451,16 @@ Debian bug number.'''),
# store the JSON dump in memory, and update the generation
# timestamp before returning
self.json_data = json.dumps(data, separators=(',', ':'))
self.json_timestamp = datetime.now()
new_data = json.dumps(data, separators=(',', ':'))
if new_data != self.json_data:
self.json_data = new_data
self.json_timestamp = time.time()
return self.json_data
def page_json(self, path, params, url):
# FIXME: we want to send along a Last-Modified header, whose
# value will be:
# self.json_timestamp.strftime("%a, %d %b %Y %H:%M:%S ") + TZ
return BinaryResult(self._get_json(),'application/octet-stream')
result = BinaryResult(self._get_json(),'application/json')
result.headers['Last-Modified'] = email.utils.formatdate(self.json_timestamp, usegmt=True)
return result
def page_debsecan(self, path, params, url):
obj = '/'.join(path)
......
......@@ -604,67 +604,65 @@ class PathRouter:
raise InvalidPath
return (result, ())
class Result:
class Result(object):
"""Base class for result objects."""
def __init__(self):
self.status = 500
self.headers = {}
def flatten(self, write):
pass
for k, v in self.headers.items():
write("%s: %s\n" % (k, v))
write("\n")
def flatten_later(self):
"""Flattens this result.
Returns a closure which sends the result using a
BaseHTTPRequestHandler object passed as argument."""
pass
def later(req):
req.send_response(self.status)
for k, v in self.headers.items():
req.send_header(k, v)
req.end_headers()
return later
class RedirectResult(Result):
"""Permanently redirects the browser to a new URL."""
def __init__(self, url, permanent=True):
super(RedirectResult, self).__init__()
if permanent:
self.status = 301
else:
self.status = 302
self.url = str(url)
def flatten(self, write):
write("Status: %d\nLocation: %s\n\n" % (self.status, self.url))
def flatten_later(self):
def later(req):
req.send_response(self.status)
req.send_header('Location', self.url)
req.end_headers()
return later
self.headers['Location'] = str(url)
class HTMLResult(Result):
"""An object of this class combines a status code with HTML contents."""
def __init__(self, contents, doctype='', status=200):
super(HTMLResult, self).__init__()
self.contents = contents
self.status = status
self.doctype = doctype
self.headers['Content-Type'] = 'text/html; charset=UTF-8'
def flatten(self, write):
"""Invokes write for the response header and all HTML data.
Includes the doctype declaration."""
if self.status <> 200:
write("Status: %d\n" % self.status)
write("Content-Type: text/html\n\n%s\n" % self.doctype)
super(HTMLResult, self).flatten(write)
write("%s\n" % self.doctype)
self.contents.flatten(write)
def flatten_later(self):
headers_later = super(HTMLResult, self).flatten_later()
buf = cStringIO.StringIO()
buf.write(self.doctype)
buf.write('\n')
self.contents.flatten(buf.write)
buf = buf.getvalue()
def later(req):
req.send_response(self.status)
req.send_header('Content-Type', 'text/html; charset=UTF-8')
req.end_headers()
headers_later(req)
req.wfile.write(buf)
return later
......@@ -672,22 +670,20 @@ class BinaryResult(Result):
"""An object of this class combines a status code with HTML contents."""
def __init__(self, contents,
mimetype='application/octet-stream', status=200):
super(BinaryResult, self).__init__()
self.contents = contents
self.status = status
self.mimetype = mimetype
self.headers['Content-Type'] = mimetype
def flatten(self, write):
"""Invokes write for the response header and the binary data."""
if self.status <> 200:
write("Status: %d\n" % self.status)
write("Content-Type: %s\n\n" % self.mimetype)
super(BinaryResult, self).flatten(write)
write(self.contents)
def flatten_later(self):
headers_later = super(BinaryResult, self).flatten_later()
def later(req):
req.send_response(self.status)
req.send_header('Content-Type', self.mimetype)
req.end_headers()
headers_later(req)
req.wfile.write(self.contents)
return later
......@@ -888,12 +884,11 @@ def __test():
== '<span class="red">green</span>'
assert TD(A("http://www.example.net/", "example")).toString() \
== '<td><a href="http://www.example.net/">example</a></td>'
assert make_pre(['a', 'b']).toString() == '<pre>a\nb\n</pre>'
#assert make_pre(['a', 'b']).toString() == '<pre>a\nb\n</pre>'
s = cStringIO.StringIO()
RedirectResult(u.scriptRelativeFull("123")).flatten(s.write)
assert s.getvalue() == '''Status: 301
Location: http://localhost.localdomain/cgi-bin/test.cgi/123
assert s.getvalue() == '''Location: http://localhost.localdomain/cgi-bin/test.cgi/123
'''
......