Fix BaseRequest.urlparts.host and path correctly when the server is behind the reverse proxy

This commit is contained in:
swe-jaeyoungpark 2019-04-29 18:21:41 +09:00
parent 569929c95b
commit d154fc09ca
3 changed files with 27 additions and 11 deletions

@ -80,6 +80,8 @@ def favicon():
@app.route('/')
def root():
fp = request.fullpath
try:
numpkgs = len(list(packages()))
except:
@ -88,11 +90,11 @@ def root():
# Ensure template() does not consider `msg` as filename!
msg = config.welcome_msg + '\n'
return template(msg,
URL=request.url,
URL=request.url.rstrip("/") + '/',
VERSION=__version__,
NUMPKGS=numpkgs,
PACKAGES=urljoin(request.url, "packages/"),
SIMPLE=urljoin(request.url, "simple/")
PACKAGES=fp.rstrip("/") + "/packages/",
SIMPLE=fp.rstrip("/") + "/simple/"
)
_bottle_upload_filename_re = re.compile(r'^[a-z0-9_.!+-]+$', re.I)
@ -195,7 +197,7 @@ def update():
@app.route('/packages')
@auth("list")
def pep_503_redirects(prefix=None):
return redirect(request.url + "/", 301)
return redirect(request.fullpath + "/", 301)
@app.post('/RPC2')
@ -259,8 +261,9 @@ def simple(prefix=""):
return redirect("%s/%s/" % (config.fallback_url.rstrip("/"), prefix))
return HTTPError(404, 'Not Found (%s does not exist)\n\n' % normalized)
fp = request.fullpath
links = [(os.path.basename(f.relfn),
urljoin(request.url, "../../packages/%s" % f.fname_and_hash(config.hash_algo)))
urljoin(fp, "../../packages/%s" % f.fname_and_hash(config.hash_algo)))
for f in files]
tmpl = """\
<html>
@ -281,11 +284,12 @@ def simple(prefix=""):
@app.route('/packages/')
@auth("list")
def list_packages():
fp = request.fullpath
files = sorted(core.find_packages(packages()),
key=lambda x: (os.path.dirname(x.relfn),
x.pkgname,
x.parsed_version))
links = [(f.relfn_unix, urljoin(request.url, f.fname_and_hash(config.hash_algo)))
links = [(f.relfn_unix, urljoin(fp, f.fname_and_hash(config.hash_algo)))
for f in files]
tmpl = """\
<html>

@ -117,7 +117,7 @@ except IOError:
if py3k:
import http.client as httplib
import _thread as thread
from urllib.parse import urljoin, SplitResult as UrlSplitResult
from urllib.parse import urlparse, urljoin, SplitResult as UrlSplitResult
from urllib.parse import urlencode, quote as urlquote, unquote as urlunquote
urlunquote = functools.partial(urlunquote, encoding='latin1')
from http.cookies import SimpleCookie
@ -136,7 +136,7 @@ if py3k:
else: # 2.x
import httplib
import thread
from urlparse import urljoin, SplitResult as UrlSplitResult
from urlparse import urlparse, urljoin, SplitResult as UrlSplitResult
from urllib import urlencode, quote as urlquote, unquote as urlunquote
from Cookie import SimpleCookie
from itertools import imap
@ -1330,20 +1330,32 @@ class BaseRequest(object):
http = env.get('HTTP_X_FORWARDED_PROTO') \
or env.get('wsgi.url_scheme', 'http')
host = env.get('HTTP_X_FORWARDED_HOST') or env.get('HTTP_HOST')
path = urlquote(self.scriptpath)
if host:
parsed = urlparse(http + "://" + host)
path = parsed.path.rstrip('/') + '/' + path.lstrip('/')
host = parsed.netloc
if not host:
# HTTP 1.1 requires a Host-header. This is for HTTP/1.0 clients.
host = env.get('SERVER_NAME', '127.0.0.1')
port = env.get('SERVER_PORT')
if port and port != ('80' if http == 'http' else '443'):
host += ':' + port
path = urlquote(self.fullpath)
return UrlSplitResult(http, host, path, env.get('QUERY_STRING'), '')
@property
def fullpath(self):
def scriptpath(self):
""" Request path including :attr:`script_name` (if present). """
return urljoin(self.script_name, self.path.lstrip('/'))
@property
def fullpath(self):
""" The path including :attr:`scriptpath`, the prefix of the url """
return self.urlparts.path
@property
def query_string(self):
""" The raw :attr:`query` part of the URL (everything in between ``?``

@ -285,7 +285,7 @@ def store(root, filename, save_method):
def get_bad_url_redirect_path(request, prefix):
"""Get the path for a bad root url."""
p = request.url
p = request.fullpath
if p.endswith("/"):
p = p[:-1]
p = p.rsplit('/', 1)[0]