Source

pypi / pypi.wsgi

#!/usr/bin/python
import sys
import os
prefix = os.path.dirname(__file__)
sys.path.insert(0, prefix)
import cStringIO
import webui
import store
import config
import re
from functools import partial

store.keep_conn = True

CONFIG_FILE = os.environ.get("PYPI_CONFIG", os.path.join(prefix, 'config.ini'))


class Request:

    def __init__(self, environ, start_response):
        self.start_response = start_response
        try:
            length = int(environ.get('CONTENT_LENGTH', 0))
        except ValueError:
            length = 0
        self.rfile = cStringIO.StringIO(environ['wsgi.input'].read(length))
        self.wfile = cStringIO.StringIO()
        self.config = config.Config(CONFIG_FILE)

    def send_response(self, code, message='no details available'):
        self.status = '%s %s' % (code, message)
        self.headers = []

    def send_header(self, keyword, value):
        self.headers.append((keyword, value))

    def set_content_type(self, content_type):
        self.send_header('Content-Type', content_type)

    def end_headers(self):
        self.start_response(self.status, self.headers)


class CacheControlMiddleware(object):

    def __init__(self, app):
        self.app = app

    def __call__(self, environ, start_response):

        def _start_response(status, headers, exc_info=None):
            script = environ.get("SCRIPT_NAME", None)
            if script in set(["/simple", "/serversig", "/packages"]):
                # Cache for a day
                headers += [("Cache-Control", "max-age=86400, public")]
            elif script in set(["/mirrors", "/security"]):
                # Cache these for a week
                headers += [("Cache-Control", "max-age=604800, public")]

            return start_response(status, headers, exc_info)

        return self.app(environ, _start_response)


def debug(environ, start_response):
    if environ['PATH_INFO'].startswith("/auth") and \
           "HTTP_AUTHORIZATION" not in environ:
        start_response("401 login",
                       [('WWW-Authenticate', 'Basic realm="foo"')])
        return
    start_response("200 ok", [('Content-type', 'text/plain')])
    environ = environ.items()
    environ.sort()
    for k, v in environ:
        yield "%s=%s\n" % (k, v)
    return


def application(environ, start_response):
    if "HTTP_AUTHORIZATION" in environ:
        environ["HTTP_CGI_AUTHORIZATION"] = environ["HTTP_AUTHORIZATION"]
    try:
        r = Request(environ, start_response)
        webui.WebUI(r, environ).run()
        return [r.wfile.getvalue()]
    except Exception, e:
        import traceback;traceback.print_exc()
        return ['Ooops, there was a problem (%s)' % e]
#application=debug


# Handle Caching at the WSGI layer
application = CacheControlMiddleware(application)


# pretend to be like the UWSGI configuration - set SCRIPT_NAME to the first
# part of the PATH_INFO if it's valid and remove that part from the PATH_INFO
def site_fake(app, environ, start_response):
    PATH_INFO = environ['PATH_INFO']
    m = re.match('^/(pypi|simple|daytime|serversig|mirrors|id|oauth|'
        'security|packages)(.*)', PATH_INFO)
    if not m:
        start_response("404 not found", [('Content-type', 'text/plain')])
        return ['Not Found: %s' % PATH_INFO]

    environ['SCRIPT_NAME'] = '/' + m.group(1)
    environ['PATH_INFO'] = m.group(2)

    return app(environ, start_response)


if __name__ == '__main__':
    # very simple wsgi server so we can play locally
    from wsgiref.simple_server import make_server
    httpd = make_server('', 8000, partial(site_fake, application))
    print "Serving on port 8000..."
    httpd.serve_forever()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.