def validate(cls, validator_context): """ Validates the configuration for using BitTorrent for downloads. """ config = validator_context.config client = validator_context.http_client announce_url = config.get("BITTORRENT_ANNOUNCE_URL") if not announce_url: raise ConfigValidationException("Missing announce URL") # Ensure that the tracker is reachable and accepts requests signed with a registry key. params = { "info_hash": sha1("test").digest(), "peer_id": "-QUAY00-6wfG2wk6wWLc", "uploaded": 0, "downloaded": 0, "left": 0, "numwant": 0, "port": 80, } torrent_config = TorrentConfiguration.for_testing( validator_context.instance_keys, announce_url, validator_context.registry_title) encoded_jwt = jwt_from_infohash(torrent_config, params["info_hash"]) params["jwt"] = encoded_jwt resp = client.get(announce_url, timeout=5, params=params) logger.debug("Got tracker response: %s: %s", resp.status_code, resp.text) if resp.status_code == 404: raise ConfigValidationException( "Announce path not found; did you forget `/announce`?") if resp.status_code == 500: raise ConfigValidationException( "Did not get expected response from Tracker; " + "please check your settings") if resp.status_code == 200: if "invalid jwt" in resp.text: raise ConfigValidationException( "Could not authorize to Tracker; is your Tracker " + "properly configured?") if "failure reason" in resp.text: raise ConfigValidationException( "Could not validate signed announce request: " + resp.text) if "go_goroutines" in resp.text: raise ConfigValidationException( "Could not validate signed announce request: " + "provided port is used for Prometheus")
def _torrent_for_blob(blob, is_public): """ Returns a response containing the torrent file contents for the given blob. May abort with an error if the state is not valid (e.g. non-public, non-user request). """ # Make sure the storage has a size. if not blob.compressed_size: abort(404) # Lookup the torrent information for the storage. torrent_info = registry_model.get_torrent_info(blob) if torrent_info is None: abort(404) # Lookup the webseed path for the storage. webseed = storage.get_direct_download_url( blob.placements, blob.storage_path, expires_in=app.config["BITTORRENT_WEBSEED_LIFETIME"]) if webseed is None: # We cannot support webseeds for storages that cannot provide direct downloads. exact_abort(501, "Storage engine does not support seeding.") # Load the config for building torrents. torrent_config = TorrentConfiguration.from_app_config( instance_keys, app.config) # Build the filename for the torrent. if is_public: name = public_torrent_filename(blob.uuid) else: user = get_authenticated_user() if not user: abort(403) name = per_user_torrent_filename(torrent_config, user.uuid, blob.uuid) # Return the torrent file. torrent_file = make_torrent( torrent_config, name, webseed, blob.compressed_size, torrent_info.piece_length, torrent_info.pieces, ) headers = { "Content-Type": "application/x-bittorrent", "Content-Disposition": "attachment; filename={0}.torrent".format(name), } return make_response(torrent_file, 200, headers)
def validate(cls, validator_context): """ Validates the configuration for using BitTorrent for downloads. """ config = validator_context.config client = validator_context.http_client announce_url = config.get('BITTORRENT_ANNOUNCE_URL') if not announce_url: raise ConfigValidationException('Missing announce URL') # Ensure that the tracker is reachable and accepts requests signed with a registry key. params = { 'info_hash': sha1('test').digest(), 'peer_id': '-QUAY00-6wfG2wk6wWLc', 'uploaded': 0, 'downloaded': 0, 'left': 0, 'numwant': 0, 'port': 80, } torrent_config = TorrentConfiguration.for_testing( validator_context.instance_keys, announce_url, validator_context.registry_title) encoded_jwt = jwt_from_infohash(torrent_config, params['info_hash']) params['jwt'] = encoded_jwt resp = client.get(announce_url, timeout=5, params=params) logger.debug('Got tracker response: %s: %s', resp.status_code, resp.text) if resp.status_code == 404: raise ConfigValidationException( 'Announce path not found; did you forget `/announce`?') if resp.status_code == 500: raise ConfigValidationException( 'Did not get expected response from Tracker; ' + 'please check your settings') if resp.status_code == 200: if 'invalid jwt' in resp.text: raise ConfigValidationException( 'Could not authorize to Tracker; is your Tracker ' + 'properly configured?') if 'failure reason' in resp.text: raise ConfigValidationException( 'Could not validate signed announce request: ' + resp.text) if 'go_goroutines' in resp.text: raise ConfigValidationException( 'Could not validate signed announce request: ' + 'provided port is used for Prometheus')