summaryrefslogtreecommitdiff
path: root/webui.py
diff options
context:
space:
mode:
authorDonald Stufft <donald@stufft.io>2013-06-20 13:22:15 -0400
committerDonald Stufft <donald@stufft.io>2013-06-20 13:22:15 -0400
commit6b01d0eb8cac4155ab29f422ce2da45fa72b2485 (patch)
tree71c67692b30382571677c7f3d1df706a25c953cd /webui.py
parente092422c96650dcec0e5cd4dd52e04fc56caf077 (diff)
parentdb3713079be3f55d9bac3b7a18f17a13efaed6ac (diff)
downloaddecorator-6b01d0eb8cac4155ab29f422ce2da45fa72b2485.tar.gz
Merged in ctheune/pypi-fix-mirroring (pull request #1)
Fix packages downloading to include LAST SERIAL header
Diffstat (limited to 'webui.py')
-rw-r--r--webui.py46
1 files changed, 42 insertions, 4 deletions
diff --git a/webui.py b/webui.py
index c4262dc..bef4dff 100644
--- a/webui.py
+++ b/webui.py
@@ -65,6 +65,8 @@ safe_username = re.compile(r'^[A-Za-z0-9._]+$')
safe_email = re.compile(r'^[a-zA-Z0-9._+@-]+$')
botre = re.compile(r'^$|brains|yeti|myie2|findlinks|ia_archiver|psycheclone|badass|crawler|slurp|spider|bot|scooter|infoseek|looksmart|jeeves', re.I)
+packages_path_to_package_name = re.compile(
+ '^/([0-9\.]+|any|source)/./([a-zA-Z0-9][a-zA-Z0-9_\-\.]*)')
class NotFound(Exception):
pass
@@ -500,7 +502,6 @@ class WebUI:
(cssclass, cssclass, self.link_action(action_name), desc))
return links
-
def inner_run(self):
''' Figure out what the request is, and farm off to the appropriate
handler.
@@ -511,6 +512,8 @@ class WebUI:
return self.run_simple()
if script_name and script_name == self.config.simple_sign_script:
return self.run_simple_sign()
+ if script_name == '/packages':
+ return self.packages()
if script_name == '/mirrors':
return self.mirrors()
if script_name == '/security':
@@ -752,6 +755,10 @@ class WebUI:
self.handler.set_content_type('text/html; charset=utf-8')
self.handler.send_header('Content-Length', str(len(html)))
self.handler.send_header("Surrogate-Key", "simple")
+ # XXX not quite sure whether this is the right thing for empty
+ # mirrors, but anyway.
+ serial = self.store.changelog_last_serial() or 0
+ self.handler.send_header("X-PYPI-LAST-SERIAL", str(serial))
self.handler.end_headers()
self.wfile.write(html)
return
@@ -776,9 +783,8 @@ class WebUI:
def run_simple_sign(self):
path = self.env.get('PATH_INFO')
- if not path.endswith('/'):
- raise Redirect, self.config.simple_sign_script+path+'/'
- path = path[1:-1]
+ # Helper to support this working with simple WSGI main script.
+ path = path.strip('/')
if '/' in path:
raise NotFound, path
html = self.simple_body(path)
@@ -796,6 +802,38 @@ class WebUI:
self.handler.end_headers()
self.wfile.write(sig)
+ def packages(self):
+ path = self.env.get('PATH_INFO')
+
+ # I expect that nginx will do the right thing if it doesn't find the
+ # actual file when resolving the X-accel headers.
+ self.handler.send_response(200, 'OK')
+
+ package = packages_path_to_package_name.match(path)
+ if package:
+ # Make sure that we associate the delivered file with the serial this
+ # is valid for. Intended to support mirrors to more easily achieve
+ # consistency with files that are newer than they may expect.
+ package = package.group(2)
+ serial = self.store.last_serial_for_package(package)
+ self.handler.send_header("X-PYPI-LAST-SERIAL", str(serial))
+
+ # we expect nginx to have configured a location named
+ # '/packages_raw/...' that aliases the original path correctly, see
+ # http://wiki.nginx.org/X-accel and http://wiki.nginx.org/XSendfile for
+ # details.
+ # Sample: (note the missing slash on the alias!)
+ # location /packages_raw {
+ # alias /path/to/packages/dir;
+ # add_header X-PYPI-LAST-SERIAL $upstream_http_x_pypi_last_serial;
+ # internal;
+ # autoindex on;
+ # }
+ # I tested this using regular http upstreams, so no guarantee this works with uwsgi.
+ self.handler.send_header("X-Accel-Redirect", "/packages_raw" + path)
+
+ self.handler.end_headers()
+
def run_id(self):
path = self.env.get('PATH_INFO')
if not path: