1
0
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:
ankostis on tokoti 2015-12-20 01:42:44 +02:00
parent 91a9e5aa4a
commit 85e51d5a48
4 changed files with 50 additions and 12 deletions

@ -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