diff --git a/README.rst b/README.rst index 79c107ca..0c3d80ed 100755 --- a/README.rst +++ b/README.rst @@ -33,6 +33,19 @@ Then you can launch the server using the pypi.wsgi script:: PyPI will be available in your browser at http://localhost:8000 +You can use the `--port` option to change the port, in particular some browsers +do not accept TLS connections except on port 443 and 8443. Alternatively you +can also set the environment variable +``PYPI_LEGACY_ALLOW_NO_TLS_FOR_TESTING_PURPOSE_ONLY`` to ``1`` for local +testing and have PyPI legacy accept non-TLS connections. Use this if you see +the following message when accessing your local PyPI: + +.. : + + Forbidden + + Must access using HTTPS instead of HTTP + Database Setup -------------- diff --git a/pypi.wsgi b/pypi.wsgi index 77b3ca32..df8d428d 100755 --- a/pypi.wsgi +++ b/pypi.wsgi @@ -120,7 +120,7 @@ def application(environ, start_response): r = Request(environ, start_response) webui.WebUI(r, environ).run() return [r.wfile.getvalue()] - except Exception, e: + except Exception as e: import traceback;traceback.print_exc() return ['Ooops, there was a problem (%s)' % e] #application=debug @@ -152,7 +152,12 @@ def site_fake(app, environ, start_response): if __name__ == '__main__': # very simple wsgi server so we can play locally + + import argparse + parser = argparse.ArgumentParser() + parser.add_argument("--port", help="port to listen on", type=int, default=8000) + args = parser.parse_args() from wsgiref.simple_server import make_server - httpd = make_server('', 8000, partial(site_fake, application)) - print "Serving on port 8000..." + httpd = make_server('', args.port, partial(site_fake, application)) + print("Serving on port %s..." % args.port) httpd.serve_forever() diff --git a/store.py b/store.py index 92e5e36b..8b845c6d 100755 --- a/store.py +++ b/store.py @@ -1,14 +1,14 @@ ''' Implements a store of disutils PKG-INFO entries, keyed off name, version. ''' + +from __future__ import print_function + import sys, os, re, time, hashlib, random, types, math, stat, errno import logging, string, datetime, calendar, binascii, urllib, urllib2, cgi import posixpath from collections import defaultdict import cPickle as pickle -try: - import psycopg2 -except ImportError: - pass +import psycopg2 try: import sqlite3 sqlite3_cursor = sqlite3.Cursor @@ -2845,5 +2845,5 @@ def get_description_urls(html): store.update_upload_times() store.commit() else: - print "UNKNOWN COMMAND", sys.argv[2] + print("UNKNOWN COMMAND", sys.argv[2]) store.close() diff --git a/webui.py b/webui.py index dfc7cc4c..4d2ed0b3 100644 --- a/webui.py +++ b/webui.py @@ -1,4 +1,5 @@ # import defusedxml before anything else +from __future__ import print_function import defusedxml import defusedxml.xmlrpc defusedxml.xmlrpc.monkey_patch() @@ -257,14 +258,18 @@ def decode_form(form): d[k] = transmute(v) return d +if os.environ.get('PYPI_LEGACY_ALLOW_NO_TLS_FOR_TESTING_PURPOSE_ONLY', 'False') == '1': + def must_tls(fn): + return fn +else: -def must_tls(fn): - @functools.wraps(fn) - def wrapped(self, *args, **kwargs): - if self.env.get('HTTP_X_FORWARDED_PROTO') != 'https': - raise Forbidden("Must access using HTTPS instead of HTTP") - return fn(self, *args, **kwargs) - return wrapped + def must_tls(fn): + @functools.wraps(fn) + def wrapped(self, *args, **kwargs): + if self.env.get('HTTP_X_FORWARDED_PROTO') != 'https': + raise Forbidden("Must access using HTTPS instead of HTTP") + return fn(self, *args, **kwargs) + return wrapped class MultiWriteFS(fs.multifs.MultiFS): @@ -415,17 +420,20 @@ def __init__(self, handler, env): self.usercookie = None self.failed = None # error message if initialization already produced a failure + self.package_bucket = None + if self.config.database_aws_access_key_id and self.config.database_aws_secret_access_key: + self.s3conn = boto.s3.connect_to_region( + "us-west-2", + aws_access_key_id=self.config.database_aws_access_key_id, + aws_secret_access_key=self.config.database_aws_secret_access_key, + ) - self.s3conn = boto.s3.connect_to_region( - "us-west-2", - aws_access_key_id=self.config.database_aws_access_key_id, - aws_secret_access_key=self.config.database_aws_secret_access_key, - ) - - self.package_bucket = self.s3conn.get_bucket( - self.config.database_files_bucket, - validate=False, - ) + self.package_bucket = self.s3conn.get_bucket( + self.config.database_files_bucket, + validate=False, + ) + else: + print("AWS database not fully configured. Getting the package files will be unavailable.", file=sys.stderr) if self.config.database_docs_bucket is not None: self.docs_fs = NoDirS3FS( @@ -434,7 +442,10 @@ def __init__(self, handler, env): aws_secret_key=self.config.database_aws_secret_access_key, ) else: - self.docs_fs = fs.osfs.OSFS(self.config.database_docs_dir) + try: + self.docs_fs = fs.osfs.OSFS(self.config.database_docs_dir) + except Exception as e: + import pdb; pdb.set_trace() # XMLRPC request or not? if self.env.get('CONTENT_TYPE') != 'text/xml':