<commit_before>import datetime
import functools
import logging
import tarfile
import time

import flask
import simplejson as json

import checksums
import storage
import toolkit

from .app import app
from .app import cfg
import layers

import storage.local
store = storage.load()
logger = logging.getLogger(__name__)


def require_completion(f):
    """This make sure that the image push correctly finished."""
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        if store.exists(store.image_mark_path(kwargs['image_id'])):
            return toolkit.api_error('Image is being uploaded, retry later')
        return f(*args, **kwargs)
    return wrapper


def set_cache_headers(f):
    """Returns HTTP headers suitable for caching."""
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        # Set TTL to 1 year by default
        ttl = 31536000
        expires = datetime.datetime.fromtimestamp(int(time.time()) + ttl)
        expires = expires.strftime('%a, %d %b %Y %H:%M:%S GMT')
        headers = {
            'Cache-Control': 'public, max-age={0}'.format(ttl),
            'Expires': expires,
            'Last-Modified': 'Thu, 01 Jan 1970 00:00:00 GMT',
        }
        if 'If-Modified-Since' in flask.request.headers:
            return flask.Response(status=304, headers=headers)
        kwargs['headers'] = headers
        # Prevent the Cookie to be sent when the object is cacheable
        flask.session.modified = False
        return f(*args, **kwargs)
    return wrapper


def _get_image_layer(image_id, headers=None):
    if headers is None:
        headers = {}
    try:
        accel_uri_prefix = cfg.nginx_x_accel_redirect
        path = store.image_layer_path(image_id)
        if accel_uri_prefix:
            if isinstance(store, storage.local.LocalStorage):
                accel_uri = '/'.join([accel_uri_prefix, path])
                headers['X-Accel-Redirect'] = accel_uri
                logger.debug('send accelerated {0} ({1})'.format(
                    accel_uri, headers))
                return flask.Response('', headers=headers)
            else:
                logger.warn('nginx_x_accel_redirect config set,'
                            ' but storage is not LocalStorage')
        return flask.Response(store.stream_read(path), headers=headers)
    except IOError:
        return toolkit.api_error('Image not found', 404)


def _get_image_json(image_id, headers=None):
    if headers is None:
        headers = {}
    try:
        data = store.get_content(store.image_json_path(image_id))
    except IOError:
        return toolkit.api_error('Image not found', 404)
    try:
        size = store.get_size(store.image_layer_path(image_id))
        headers['X-Docker-Size'] = str(size)
    except OSError:
        pass
    checksum_path = store.image_checksum_path(image_id)
    if store.exists(checksum_path):
        headers['X-Docker-Checksum'] = store.get_content(checksum_path)
    return toolkit.response(data, headers=headers, raw=True)


@app.route('/v1/private_images/<image_id>/layer', methods=['GET'])
@toolkit.requires_auth
@require_completion
def get_private_image_layer(image_id):
    try:
        repository = toolkit.get_repository()
        if not repository:
            # No auth token found, either standalone registry or privileged
            # access. In both cases, private images are "disabled"
            return toolkit.api_error('Image not found', 404)
        if not store.is_private(*repository):
            return toolkit.api_error('Image not found', 404)
        headers = None
        if store.supports_bytes_range:
            headers['Accept-Ranges'] = 'bytes'
        return _get_image_layer(image_id, headers)
    except IOError:
        return toolkit.api_error('Image not found', 404)


@app.route('/v1/images/<image_id>/layer', methods=['GET'])
@toolkit.requires_auth
@require_completion
@set_cache_headers
def get_image_layer(image_id, headers):
    try:
        if store.supports_bytes_range:
            headers['Accept-Ranges'] = 'bytes'
        repository = toolkit.get_repository()<commit_msg>Parse bytes range in incoming request and pass right args to the storage lib<commit_after>import datetime
import functools
import logging
import tarfile
import time

import flask
import simplejson as json

import checksums
import storage
import toolkit

from .app import app
from .app import cfg
import layers

import storage.local
store = storage.load()
logger = logging.getLogger(__name__)


def require_completion(f):
    """This make sure that the image push correctly finished."""
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        if store.exists(store.image_mark_path(kwargs['image_id'])):
            return toolkit.api_error('Image is being uploaded, retry later')
        return f(*args, **kwargs)
    return wrapper


def set_cache_headers(f):
    """Returns HTTP headers suitable for caching."""
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        # Set TTL to 1 year by default
        ttl = 31536000
        expires = datetime.datetime.fromtimestamp(int(time.time()) + ttl)
        expires = expires.strftime('%a, %d %b %Y %H:%M:%S GMT')
        headers = {
            'Cache-Control': 'public, max-age={0}'.format(ttl),
            'Expires': expires,
            'Last-Modified': 'Thu, 01 Jan 1970 00:00:00 GMT',
        }
        if 'If-Modified-Since' in flask.request.headers:
            return flask.Response(status=304, headers=headers)
        kwargs['headers'] = headers
        # Prevent the Cookie to be sent when the object is cacheable
        flask.session.modified = False
        return f(*args, **kwargs)
    return wrapper


def _get_image_layer(image_id, headers=None, bytes_range=None):
    if headers is None:
        headers = {}
    try:
        accel_uri_prefix = cfg.nginx_x_accel_redirect
        path = store.image_layer_path(image_id)
        if accel_uri_prefix:
            if isinstance(store, storage.local.LocalStorage):
                accel_uri = '/'.join([accel_uri_prefix, path])
                headers['X-Accel-Redirect'] = accel_uri
                logger.debug('send accelerated {0} ({1})'.format(
                    accel_uri, headers))
                return flask.Response('', headers=headers)
            else:
                logger.warn('nginx_x_accel_redirect config set,'
                            ' but storage is not LocalStorage')
        status = None
        if bytes_range:
            status = 206
            headers['Content-Range'] = '{0}-{1}/*'.format(*bytes_range)
        return flask.Response(store.stream_read(path, bytes_range),
                              headers=headers, status=status)
    except IOError:
        return toolkit.api_error('Image not found', 404)


def _get_image_json(image_id, headers=None):
    if headers is None:
        headers = {}
    try:
        data = store.get_content(store.image_json_path(image_id))
    except IOError:
        return toolkit.api_error('Image not found', 404)
    try:
        size = store.get_size(store.image_layer_path(image_id))
        headers['X-Docker-Size'] = str(size)
    except OSError:
        pass
    checksum_path = store.image_checksum_path(image_id)
    if store.exists(checksum_path):
        headers['X-Docker-Checksum'] = store.get_content(checksum_path)
    return toolkit.response(data, headers=headers, raw=True)


@app.route('/v1/private_images/<image_id>/layer', methods=['GET'])
@toolkit.requires_auth
@require_completion
def get_private_image_layer(image_id):
    try:
        repository = toolkit.get_repository()
        if not repository:
            # No auth token found, either standalone registry or privileged
            # access. In both cases, private images are "disabled"
            return toolkit.api_error('Image not found', 404)
        if not store.is_private(*repository):
            return toolkit.api_error('Image not found', 404)
        headers = None
        if store.supports_bytes_range:
            headers['Accept-Ranges'] = 'bytes'
        return _get_image_layer(image_id, headers)
    except IOError:
        return toolkit.api_error('Image not found', 404)


@app.route('/v1/images/<image_id>/layer', methods=['GET'])
@toolkit.requires_auth
@require_completion
@set_cache_headers
def get_image_layer(image_id, headers):
    try:
        if store.supports_bytes_range:
            headers['Accept-Ranges'] = 'bytes'
            # FIXME: not done
            bytes_range = self._parse_bytes_range()
        repository = toolkit.get_repository()
{'fraction_non_alphanumeric': 0.1058343057176196, 'fraction_numerical': 0.010851808634772461, 'mean_word_length': 2.7460664335664338, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2803570', 'n_tokens_mistral': 2617, 'n_tokens_neox': 2472, 'n_words': 624}