From 6f6c82a217c96413c0a1135d221dffa135f37978 Mon Sep 17 00:00:00 2001 From: Jimmy Zelinskie Date: Wed, 30 Dec 2015 16:16:23 -0500 Subject: [PATCH] implement torrent verb --- endpoints/verbs.py | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/endpoints/verbs.py b/endpoints/verbs.py index c0bb5fc27..f1cfcba37 100644 --- a/endpoints/verbs.py +++ b/endpoints/verbs.py @@ -4,7 +4,7 @@ import hashlib from flask import redirect, Blueprint, abort, send_file, make_response -from app import app, signer +from app import app, signer, storage from auth.auth import process_auth from auth.permissions import ReadRepositoryPermission from data import model, database @@ -16,6 +16,7 @@ from util.registry.queuefile import QueueFile from util.registry.queueprocess import QueueProcess from formats.squashed import SquashedDockerImage from formats.aci import ACIImage +from endpoints.v2.blob import BASE_BLOB_ROUTE, blob_fetch verbs = Blueprint('verbs', __name__) @@ -275,3 +276,30 @@ def get_aci_image(server, namespace, repository, tag, os, arch): def get_squashed_tag(namespace, repository, tag): return _repo_verb(namespace, repository, tag, 'squash', SquashedDockerImage()) + +@anon_protect +@verbs.route('/torrent'+BASE_BLOB_ROUTE, methods=['GET']) +@process_auth +def get_tag_torrent(namespace, repository, digest): + permission = ReadRepositoryPermission(namespace, repository) + if not permission.can() and not model.repository.repository_is_public(namespace, repository): + abort(403) + + try: + blob = model.blob.get_repo_blob_by_digest(namespace, repository, digest) + except model.BlobDoesNotExist: + abort(404) + + path = model.storage.get_layer_path(blob) + webseed = storage.get_direct_download_url(blob.locations, path) + if webseed is None: + # We cannot support webseeds for storages that cannot provide direct downloads. + abort(501) + + torrent_info = model.storage.get_torrent_info(blob) + torrent_file = make_torrent(namespace, repository, digest, webseed, + torrent_info.piece_length, torrent_info.pieces) + + torrent_file = None + return make_response((torrent_file, 200, {'Content-Type': 'application/x-bittorrent', + 'Content-Length': len(torrent_file)}))