mirror of
https://github.com/pypiserver/pypiserver
synced 2025-02-22 19:19:37 +01:00
FIX #53: Append MD5 url-fragments on package links.
- TC only for digest-method.
This commit is contained in:
parent
91a9e5aa4a
commit
85e51d5a48
@ -282,15 +282,16 @@ def simple(prefix=""):
|
||||
if not fp.endswith("/"):
|
||||
fp += "/"
|
||||
|
||||
files = [x.relfn for x in sorted(core.find_packages(
|
||||
packages(), prefix=prefix), key=lambda x: (x.parsed_version, x.relfn))]
|
||||
files = sorted(core.find_packages(packages(), prefix=prefix),
|
||||
key=lambda x: (x.parsed_version, x.relfn))
|
||||
if not files:
|
||||
if config.redirect_to_fallback:
|
||||
return redirect("%s/%s/" % (config.fallback_url.rstrip("/"), prefix))
|
||||
return HTTPError(404)
|
||||
|
||||
links = [(os.path.basename(f), urljoin(fp, "../../packages/%s" %
|
||||
f.replace("\\", "/"))) for f in files]
|
||||
links = [(os.path.basename(f.relfn),
|
||||
urljoin(fp, "../../packages/%s#%s" % (f.relfn_unix(), f.hash())))
|
||||
for f in files]
|
||||
tmpl = """\
|
||||
<html>
|
||||
<head>
|
||||
@ -314,9 +315,12 @@ def list_packages():
|
||||
if not fp.endswith("/"):
|
||||
fp += "/"
|
||||
|
||||
files = [x.relfn for x in sorted(core.find_packages(packages()),
|
||||
key=lambda x: (os.path.dirname(x.relfn), x.pkgname, x.parsed_version))]
|
||||
links = [(f.replace("\\", "/"), urljoin(fp, f)) for f in files]
|
||||
files = sorted(core.find_packages(packages()),
|
||||
key=lambda x: (os.path.dirname(x.relfn),
|
||||
x.pkgname,
|
||||
x.parsed_version))
|
||||
links = [(f.relfn_unix(), '%s#%s' % (urljoin(fp, f.relfn), f.hash()))
|
||||
for f in files]
|
||||
tmpl = """\
|
||||
<html>
|
||||
<head>
|
||||
@ -337,7 +341,7 @@ def list_packages():
|
||||
def server_static(filename):
|
||||
entries = core.find_packages(packages())
|
||||
for x in entries:
|
||||
f = x.relfn.replace("\\", "/")
|
||||
f = x.relfn_unix()
|
||||
if f == filename:
|
||||
response = static_file(
|
||||
filename, root=x.root, mimetype=mimetypes.guess_type(filename)[0])
|
||||
|
@ -3,9 +3,11 @@
|
||||
|
||||
import os
|
||||
import re
|
||||
import mimetypes
|
||||
import warnings
|
||||
import logging
|
||||
import warnings
|
||||
import mimetypes
|
||||
import hashlib
|
||||
|
||||
|
||||
warnings.filterwarnings("ignore", "Python 2.5 support may be dropped in future versions of Bottle")
|
||||
mimetypes.add_type("application/octet-stream", ".egg")
|
||||
@ -107,6 +109,12 @@ class PkgFile(object):
|
||||
self.__class__.__name__,
|
||||
", ".join(["%s=%r" % (k, v) for k, v in sorted(self.__dict__.items())]))
|
||||
|
||||
def relfn_unix(self):
|
||||
return self.relfn.replace("\\", "/")
|
||||
|
||||
def hash(self, hash_algo='md5'):
|
||||
return '%s=%.32s' % (hash_algo, digest_file(self.fn, hash_algo))
|
||||
|
||||
|
||||
def listdir(root):
|
||||
root = os.path.abspath(root)
|
||||
@ -169,3 +177,19 @@ def store(root, filename, save_method):
|
||||
|
||||
log.info("Stored package: %s", filename)
|
||||
return True
|
||||
|
||||
def digest_file(fpath, hash_algo):
|
||||
"""
|
||||
Reads and digests a file according to specified hashing-algorith.
|
||||
|
||||
:param str sha256: any algo contained in :mod:`hashlib`
|
||||
:return: <hash_algo>=<hex_digest>
|
||||
|
||||
From http://stackoverflow.com/a/21565932/548792
|
||||
"""
|
||||
blocksize = 2**16
|
||||
digester = getattr(hashlib, hash_algo)()
|
||||
with open(fpath, 'rb') as f:
|
||||
for block in iter(lambda: f.read(blocksize), b''):
|
||||
digester.update(block)
|
||||
return digester.hexdigest()[:32]
|
||||
|
@ -233,7 +233,7 @@ def test_nonroot_simple_index(root, testpriv):
|
||||
resp = testpriv.get(path)
|
||||
links = resp.html("a")
|
||||
assert len(links) == 1
|
||||
assert links[0]["href"] == "/priv/packages/foobar-1.0.zip"
|
||||
assert links[0]["href"].startswith("/priv/packages/foobar-1.0.zip#")
|
||||
|
||||
|
||||
def test_nonroot_simple_packages(root, testpriv):
|
||||
@ -243,7 +243,7 @@ def test_nonroot_simple_packages(root, testpriv):
|
||||
resp = testpriv.get(path)
|
||||
links = resp.html("a")
|
||||
assert len(links) == 1
|
||||
assert links[0]["href"] == "/priv/packages/foobar-1.0.zip"
|
||||
assert links[0]["href"].startswith("/priv/packages/foobar-1.0.zip#")
|
||||
|
||||
|
||||
def test_root_no_relative_paths(testpriv):
|
||||
|
@ -55,3 +55,13 @@ def test_listdir_bad_name(tmpdir):
|
||||
tmpdir.join("foo.whl").ensure()
|
||||
res = list(core.listdir(tmpdir.strpath))
|
||||
assert res == []
|
||||
|
||||
hashes = [
|
||||
('sha256', 'e3b0c44298fc1c149afbf4c8996fb924'), # empty-sha256
|
||||
('md5', 'd41d8cd98f00b204e9800998ecf8427e'), # empty-md5
|
||||
]
|
||||
@pytest.mark.parametrize(("algo", "digest"), hashes)
|
||||
def test_hashfile(tmpdir, algo, digest):
|
||||
f = tmpdir.join("empty")
|
||||
f.ensure()
|
||||
assert core.digest_file(f.strpath, algo) == digest
|
||||
|
Loading…
Reference in New Issue
Block a user