<commit_before>__all__ = [
    'DirHandler',
    'FileHandler',
    'make_dir_handler',
    'make_file_handler',
    # Context.
    'LOCAL_PATH',
]

import mimetypes

from g1.bases import labels

from .. import consts
from .. import wsgi_apps

from . import composers
from . import etags


def make_dir_handler(local_dir_path):
    dir_handler = DirHandler(local_dir_path)
    return composers.Chain([
        dir_handler.check,
        composers.MethodRouter({
            consts.METHOD_HEAD: dir_handler.head,
            consts.METHOD_GET: dir_handler.get,
        }),
    ])


def make_file_handler(local_file_path):
    file_handler = FileHandler(local_file_path)
    return composers.Chain([
        composers.MethodRouter({
            consts.METHOD_HEAD: file_handler.head,
            consts.METHOD_GET: file_handler.get,
        }),
    ])


def get_local_path(request, local_dir_path):
    path_str = composers.get_path_str(request)
    # We use ``resolve`` to normalize path, which also follows symlinks.
    # A side effect is that this handler rejects any symlink to file
    # that is out of scope, which may be not bad.
    local_path = (local_dir_path / path_str.lstrip('/')).resolve()
    try:
        local_path.relative_to(local_dir_path)
    except ValueError:
        raise wsgi_apps.HttpError(<commit_msg>Expose `headers` argument from make_file_handler<commit_after>__all__ = [
    'DirHandler',
    'FileHandler',
    'make_dir_handler',
    'make_file_handler',
    # Context.
    'LOCAL_PATH',
]

import mimetypes

from g1.bases import labels

from .. import consts
from .. import wsgi_apps

from . import composers
from . import etags


def make_dir_handler(local_dir_path):
    dir_handler = DirHandler(local_dir_path)
    return composers.Chain([
        dir_handler.check,
        composers.MethodRouter({
            consts.METHOD_HEAD: dir_handler.head,
            consts.METHOD_GET: dir_handler.get,
        }),
    ])


def make_file_handler(local_file_path, headers=()):
    file_handler = FileHandler(local_file_path, headers=headers)
    return composers.Chain([
        composers.MethodRouter({
            consts.METHOD_HEAD: file_handler.head,
            consts.METHOD_GET: file_handler.get,
        }),
    ])


def get_local_path(request, local_dir_path):
    path_str = composers.get_path_str(request)
    # We use ``resolve`` to normalize path, which also follows symlinks.
    # A side effect is that this handler rejects any symlink to file
    # that is out of scope, which may be not bad.
    local_path = (local_dir_path / path_str.lstrip('/')).resolve()
    try:
        local_path.relative_to(local_dir_path)
    except ValueError:
        raise wsgi_apps.HttpError(
{'fraction_non_alphanumeric': 0.09191176470588236, 'fraction_numerical': 0.0007352941176470588, 'mean_word_length': 3.0430906389301633, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5269400', 'n_tokens_mistral': 864, 'n_tokens_neox': 852, 'n_words': 193}