##// END OF EJS Templates
archives: fixed bugs with serving archives from non-ascii repos, and also deliver archives at much bigger reading blocks for faster downloads
super-admin -
r5135:aabb0aed default
parent child Browse files
Show More
@@ -38,7 +38,7 b' from rhodecode.lib import diffs, helpers'
38 from rhodecode.lib import audit_logger
38 from rhodecode.lib import audit_logger
39 from rhodecode.lib.hash_utils import sha1_safe
39 from rhodecode.lib.hash_utils import sha1_safe
40 from rhodecode.lib.rc_cache.archive_cache import get_archival_cache_store, get_archival_config, ReentrantLock
40 from rhodecode.lib.rc_cache.archive_cache import get_archival_cache_store, get_archival_config, ReentrantLock
41 from rhodecode.lib.str_utils import safe_bytes
41 from rhodecode.lib.str_utils import safe_bytes, convert_special_chars
42 from rhodecode.lib.view_utils import parse_path_ref
42 from rhodecode.lib.view_utils import parse_path_ref
43 from rhodecode.lib.exceptions import NonRelativePathError
43 from rhodecode.lib.exceptions import NonRelativePathError
44 from rhodecode.lib.codeblocks import (
44 from rhodecode.lib.codeblocks import (
@@ -63,17 +63,17 b' from rhodecode.model.db import Repositor'
63 log = logging.getLogger(__name__)
63 log = logging.getLogger(__name__)
64
64
65
65
66 def get_archive_name(db_repo_name, commit_sha, ext, subrepos=False, path_sha='', with_hash=True):
66 def get_archive_name(db_repo_id, db_repo_name, commit_sha, ext, subrepos=False, path_sha='', with_hash=True):
67 # original backward compat name of archive
67 # original backward compat name of archive
68 clean_name = safe_str(db_repo_name.replace('/', '_'))
68 clean_name = safe_str(convert_special_chars(db_repo_name).replace('/', '_'))
69
69
70 # e.g vcsserver-sub-1-abcfdef-archive-all.zip
70 # e.g vcsserver-id-abcd-sub-1-abcfdef-archive-all.zip
71 # vcsserver-sub-0-abcfdef-COMMIT_SHA-PATH_SHA.zip
71 # vcsserver-id-abcd-sub-0-abcfdef-COMMIT_SHA-PATH_SHA.zip
72
72 id_sha = sha1_safe(str(db_repo_id))[:4]
73 sub_repo = 'sub-1' if subrepos else 'sub-0'
73 sub_repo = 'sub-1' if subrepos else 'sub-0'
74 commit = commit_sha if with_hash else 'archive'
74 commit = commit_sha if with_hash else 'archive'
75 path_marker = (path_sha if with_hash else '') or 'all'
75 path_marker = (path_sha if with_hash else '') or 'all'
76 archive_name = f'{clean_name}-{sub_repo}-{commit}-{path_marker}{ext}'
76 archive_name = f'{clean_name}-id-{id_sha}-{sub_repo}-{commit}-{path_marker}{ext}'
77
77
78 return archive_name
78 return archive_name
79
79
@@ -396,7 +396,7 b' class RepoFilesView(RepoAppView):'
396
396
397 # used for cache etc, consistent unique archive name
397 # used for cache etc, consistent unique archive name
398 archive_name_key = get_archive_name(
398 archive_name_key = get_archive_name(
399 self.db_repo_name, commit_sha=commit.short_id, ext=ext, subrepos=subrepos,
399 self.db_repo.repo_id, self.db_repo_name, commit_sha=commit.short_id, ext=ext, subrepos=subrepos,
400 path_sha=path_sha, with_hash=True)
400 path_sha=path_sha, with_hash=True)
401
401
402 if not with_hash:
402 if not with_hash:
@@ -404,7 +404,7 b' class RepoFilesView(RepoAppView):'
404
404
405 # what end client gets served
405 # what end client gets served
406 response_archive_name = get_archive_name(
406 response_archive_name = get_archive_name(
407 self.db_repo_name, commit_sha=commit.short_id, ext=ext, subrepos=subrepos,
407 self.db_repo.repo_id, self.db_repo_name, commit_sha=commit.short_id, ext=ext, subrepos=subrepos,
408 path_sha=path_sha, with_hash=with_hash)
408 path_sha=path_sha, with_hash=with_hash)
409
409
410 # remove extension from our archive directory name
410 # remove extension from our archive directory name
@@ -444,9 +444,10 b' class RepoFilesView(RepoAppView):'
444 if not reader:
444 if not reader:
445 raise ValueError('archive cache reader is empty, failed to fetch file from distributed archive cache')
445 raise ValueError('archive cache reader is empty, failed to fetch file from distributed archive cache')
446
446
447 def archive_iterator(_reader):
447 def archive_iterator(_reader, block_size: int = 4096*512):
448 # 4096 * 64 = 64KB
448 while 1:
449 while 1:
449 data = _reader.read(1024)
450 data = _reader.read(block_size)
450 if not data:
451 if not data:
451 break
452 break
452 yield data
453 yield data
@@ -1222,7 +1222,7 b' class BaseCommit(object):'
1222 Creates an archive containing the contents of the repository.
1222 Creates an archive containing the contents of the repository.
1223
1223
1224 :param archive_name_key: unique key under this archive should be generated
1224 :param archive_name_key: unique key under this archive should be generated
1225 :param kind: one of following: ``"tbz2"``, ``"tgz"``, ``"zip"``.
1225 :param kind: one of the following: ``"tbz2"``, ``"tgz"``, ``"zip"``.
1226 :param archive_dir_name: name of root directory in archive.
1226 :param archive_dir_name: name of root directory in archive.
1227 Default is repository name and commit's short_id joined with dash:
1227 Default is repository name and commit's short_id joined with dash:
1228 ``"{repo_name}-{short_id}"``.
1228 ``"{repo_name}-{short_id}"``.
@@ -1238,8 +1238,7 b' class BaseCommit(object):'
1238 allowed_kinds = [x[0] for x in settings.ARCHIVE_SPECS]
1238 allowed_kinds = [x[0] for x in settings.ARCHIVE_SPECS]
1239 if kind not in allowed_kinds:
1239 if kind not in allowed_kinds:
1240 raise ImproperArchiveTypeError(
1240 raise ImproperArchiveTypeError(
1241 'Archive kind (%s) not supported use one of %s' %
1241 f'Archive kind ({kind}) not supported use one of {allowed_kinds}')
1242 (kind, allowed_kinds))
1243
1242
1244 archive_dir_name = self._validate_archive_prefix(archive_dir_name)
1243 archive_dir_name = self._validate_archive_prefix(archive_dir_name)
1245 mtime = mtime is not None or time.mktime(self.date.timetuple())
1244 mtime = mtime is not None or time.mktime(self.date.timetuple())
General Comments 0
You need to be logged in to leave comments. Login now