Exemplo n.º 1
0
 def gs_url_signer(self):
     """On demand instance of CloudStorageURLSigner object."""
     if not self._gs_url_signer:
         settings = config.settings()
         self._gs_url_signer = gcs.URLSigner(settings.gs_bucket,
                                             settings.gs_client_id_email,
                                             settings.gs_private_key)
     return self._gs_url_signer
Exemplo n.º 2
0
    def get(self, namespace, hash_key):  #pylint: disable=W0221
        logging.error('Unexpected old client')
        # Parse 'Range' header if it's present to extract initial offset.
        # Only support single continuous range from some |offset| to the end.
        offset = 0
        range_header = self.request.headers.get('range')
        if range_header:
            match = re.match(r'bytes=(\d+)-', range_header)
            if not match:
                return self.send_error('Unsupported byte range.\n\'%s\'.' %
                                       range_header,
                                       http_code=416)
            offset = int(match.group(1))

        memcache_entry = memcache.get(hash_key,
                                      namespace='table_%s' % namespace)
        if memcache_entry is not None:
            self.send_data(memcache_entry, filename=hash_key, offset=offset)
            stats.add_entry(stats.RETURN,
                            len(memcache_entry) - offset, 'memcache')
            return

        entry = model.get_entry_key(namespace, hash_key).get()
        if not entry:
            return self.send_error('Unable to retrieve the entry.',
                                   http_code=404)

        if entry.content is not None:
            self.send_data(entry.content, filename=hash_key, offset=offset)
            stats.add_entry(stats.RETURN,
                            len(entry.content) - offset, 'inline')
            return

        # Generate signed download URL.
        settings = config.settings()
        # TODO(maruel): The GS object may not exist anymore. Handle this.
        signer = gcs.URLSigner(settings.gs_bucket, settings.gs_client_id_email,
                               settings.gs_private_key)
        # The entry key is the GS filepath.
        signed_url = signer.get_download_url(entry.key.id())

        # Redirect client to this URL. If 'Range' header is used, client will
        # correctly pass it to Google Storage to fetch only subrange of file,
        # so update stats accordingly.
        self.redirect(signed_url)
        stats.add_entry(stats.RETURN, entry.compressed_size - offset,
                        'GS; %s' % entry.key.id())