<commit_before># -*- coding: utf-8 -*-
"""
hyper/contrib
~~~~~~~~~~~~~

Contains a few utilities for use with other HTTP libraries.
"""
try:
    from requests.adapters import HTTPAdapter
    from requests.models import Response
    from requests.structures import CaseInsensitiveDict
    from requests.utils import get_encoding_from_headers
    from requests.cookies import extract_cookies_to_jar
except ImportError:  # pragma: no cover
    HTTPAdapter = object

from hyper.common.connection import HTTPConnection
from hyper.compat import urlparse


class HTTP20Adapter(HTTPAdapter):
    """
    A Requests Transport Adapter that uses hyper to send requests over
    HTTP/2. This implements some degree of connection pooling to maximise the
    HTTP/2 gain.
    """
    def __init__(self, *args, **kwargs):
        #: A mapping between HTTP netlocs and ``HTTP20Connection`` objects.
        self.connections = {}

    def get_connection(self, host, port, scheme):
        """
        Gets an appropriate HTTP/2 connection object based on host/port/scheme
        tuples.
        """
        secure = (scheme == 'https')

        if port is None:  # pragma: no cover
            port = 80 if not secure else 443

        try:
            conn = self.connections[(host, port, scheme)]
        except KeyError:
            conn = HTTPConnection(host, port, secure=secure)
            self.connections[(host, port, scheme)] = conn

        return conn

    def send(self, request, stream=False, **kwargs):
        """
        Sends a HTTP message to the server.
        """
        parsed = urlparse(request.url)

        conn = self.get_connection(parsed.hostname, parsed.port, parsed.scheme)

        # Build the selector.
        selector = parsed.path
        selector += '?' + parsed.query if parsed.query else ''
        selector += '#' + parsed.fragment if parsed.fragment else ''

        conn.request(
            request.method,
            selector,
            request.body,
            request.headers
        )
        resp = conn.get_response()

        r = self.build_response(request, resp)

        if not stream:
            r.content

        return r

    def build_response(self, request, resp):
        """
        Builds a Requests' response object.  This emulates most of the logic of
        the standard fuction but deals with the lack of the ``.headers``
        property on the HTTP20Response object.<commit_msg>Support for client side certificate in requests adapter.<commit_after># -*- coding: utf-8 -*-
"""
hyper/contrib
~~~~~~~~~~~~~

Contains a few utilities for use with other HTTP libraries.
"""
try:
    from requests.adapters import HTTPAdapter
    from requests.models import Response
    from requests.structures import CaseInsensitiveDict
    from requests.utils import get_encoding_from_headers
    from requests.cookies import extract_cookies_to_jar
except ImportError:  # pragma: no cover
    HTTPAdapter = object

from hyper.common.connection import HTTPConnection
from hyper.compat import urlparse


class HTTP20Adapter(HTTPAdapter):
    """
    A Requests Transport Adapter that uses hyper to send requests over
    HTTP/2. This implements some degree of connection pooling to maximise the
    HTTP/2 gain.
    """
    def __init__(self, *args, **kwargs):
        #: A mapping between HTTP netlocs and ``HTTP20Connection`` objects.
        self.connections = {}

    def get_connection(self, host, port, scheme, cert=None):
        """
        Gets an appropriate HTTP/2 connection object based on
        host/port/scheme/cert tuples.
        """
        secure = (scheme == 'https')

        if port is None:  # pragma: no cover
            port = 80 if not secure else 443

        ssl_context = None

        if cert is not None:
            ssl_context = init_context()
            try:
                basestring
            except NameError:
                basestring = str
            if not isinstance(cert, basestring):
                ssl_context.load_cert_chain(cert[0], cert[1])
            else:
                ssl_context.load_cert_chain(cert)

        try:
            conn = self.connections[(host, port, scheme, cert)]
        except KeyError:
            conn = HTTPConnection(host, port, secure=secure,
                                  ssl_context=ssl_context)
            self.connections[(host, port, scheme, cert)] = conn

        return conn

    def send(self, request, stream=False, **kwargs):
        """
        Sends a HTTP message to the server.
        """
        parsed = urlparse(request.url)
        conn = self.get_connection(parsed.hostname, parsed.port, parsed.scheme,
                                   cert=kwargs.get('cert'))

        # Build the selector.
        selector = parsed.path
        selector += '?' + parsed.query if parsed.query else ''
        selector += '#' + parsed.fragment if parsed.fragment else ''

        conn.request(
            request.method,
            selector,
            request.body,
            request.headers
        )
        resp = conn.get_response()

        r = self.build_response(request, resp)

        if not stream:
            r.content

        return r

    def build_response(self, request, resp):
        """
        Builds a Requests' response object.  This emulates most of the logic of
        the standard fuction but deals with the lack of the ``.headers``
        property on the HTTP20Response object.
{'fraction_non_alphanumeric': 0.08718795888399412, 'fraction_numerical': 0.005873715124816446, 'mean_word_length': 2.1680232558139534, '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': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2435147', 'n_tokens_mistral': 1430, 'n_tokens_neox': 1367, 'n_words': 472}