diff options
author | Donald Stufft <donald@stufft.io> | 2013-06-20 13:22:15 -0400 |
---|---|---|
committer | Donald Stufft <donald@stufft.io> | 2013-06-20 13:22:15 -0400 |
commit | 6b01d0eb8cac4155ab29f422ce2da45fa72b2485 (patch) | |
tree | 71c67692b30382571677c7f3d1df706a25c953cd /webui.py | |
parent | e092422c96650dcec0e5cd4dd52e04fc56caf077 (diff) | |
parent | db3713079be3f55d9bac3b7a18f17a13efaed6ac (diff) | |
download | decorator-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.py | 46 |
1 files changed, 42 insertions, 4 deletions
@@ -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: |