<commit_before>"""Tests for managing HTTP issues (malformed requests, etc)."""
# -*- coding: utf-8 -*-
# vim: set fileencoding=utf-8 :

import errno
import socket

import pytest
import six
from six.moves import urllib, http_client

from cheroot.test import helper, webtest


HTTP_BAD_REQUEST = 400
HTTP_LENGTH_REQUIRED = 411
HTTP_NOT_FOUND = 404
HTTP_OK = 200
HTTP_VERSION_NOT_SUPPORTED = 505


class HelloController(helper.Controller):
    def hello(req, resp):
        return 'Hello world!'

    def body_required(req, resp):
        if req.environ.get('Content-Length', None) is None:
            resp.status = '411 Length Required'
            return
        return 'Hello world!'

    def query_string(req, resp):
        return req.environ.get('QUERY_STRING', '')

    def asterisk(req, resp):
        method = req.environ.get('REQUEST_METHOD', 'NO METHOD FOUND')
        tmpl = 'Got asterisk URI path with {method} method'
        return tmpl.format(**locals())

    def _munge(string):
        """
        WSGI 1.0 is a mess around unicode. Create endpoints
        that match the PATH_INFO that it produces.
        """
        if six.PY3:
            return string.encode('utf-8').decode('latin-1')
        return string

    handlers = {
        '/hello': hello,
        '/no_body': hello,
        '/body_required': body_required,
        '/query_string': query_string,
        _munge('/привіт'): hello,
        _munge('/Юххууу'): hello,
        '/\xa0Ðblah key 0 900 4 data': hello,
        '/*': asterisk,
    }


def _get_http_response(connection, method='GET'):
    c = connection
    kwargs = {'strict': c.strict} if hasattr(c, 'strict') else {}
    # Python 3.2 removed the 'strict' feature, saying:
    # "http.client now always assumes HTTP/1.x compliant servers."
    return c.response_class(c.sock, method=method, **kwargs)


@pytest.fixture(scope='module')
def testing_server(wsgi_server):
    wsgi_server.wsgi_app = HelloController()
    wsgi_server.max_request_body_size = 30000000
    return wsgi_server


@pytest.fixture
def server_client(testing_server):
    host, port = testing_server.bind_addr

    interface = webtest.interface(host)

    def probe_ipv6_sock(interface):
        import errno
        import socket
        from contextlib import closing
        try:
            with closing(socket.socket(family=socket.AF_INET6)) as sock:
                sock.bind((interface, 0))
        except OSError as sock_err:
            if sock_err.errno == errno.EADDRNOTAVAIL:
                pass
            raise
        else:
            return True

        return False

    if ':' in interface and not probe_ipv6_sock(interface):<commit_msg>Fix OSError handling in probe helper<commit_after>"""Tests for managing HTTP issues (malformed requests, etc)."""
# -*- coding: utf-8 -*-
# vim: set fileencoding=utf-8 :

import errno
import socket

import pytest
import six
from six.moves import urllib, http_client

from cheroot.test import helper, webtest


HTTP_BAD_REQUEST = 400
HTTP_LENGTH_REQUIRED = 411
HTTP_NOT_FOUND = 404
HTTP_OK = 200
HTTP_VERSION_NOT_SUPPORTED = 505


class HelloController(helper.Controller):
    def hello(req, resp):
        return 'Hello world!'

    def body_required(req, resp):
        if req.environ.get('Content-Length', None) is None:
            resp.status = '411 Length Required'
            return
        return 'Hello world!'

    def query_string(req, resp):
        return req.environ.get('QUERY_STRING', '')

    def asterisk(req, resp):
        method = req.environ.get('REQUEST_METHOD', 'NO METHOD FOUND')
        tmpl = 'Got asterisk URI path with {method} method'
        return tmpl.format(**locals())

    def _munge(string):
        """
        WSGI 1.0 is a mess around unicode. Create endpoints
        that match the PATH_INFO that it produces.
        """
        if six.PY3:
            return string.encode('utf-8').decode('latin-1')
        return string

    handlers = {
        '/hello': hello,
        '/no_body': hello,
        '/body_required': body_required,
        '/query_string': query_string,
        _munge('/привіт'): hello,
        _munge('/Юххууу'): hello,
        '/\xa0Ðblah key 0 900 4 data': hello,
        '/*': asterisk,
    }


def _get_http_response(connection, method='GET'):
    c = connection
    kwargs = {'strict': c.strict} if hasattr(c, 'strict') else {}
    # Python 3.2 removed the 'strict' feature, saying:
    # "http.client now always assumes HTTP/1.x compliant servers."
    return c.response_class(c.sock, method=method, **kwargs)


@pytest.fixture(scope='module')
def testing_server(wsgi_server):
    wsgi_server.wsgi_app = HelloController()
    wsgi_server.max_request_body_size = 30000000
    return wsgi_server


@pytest.fixture
def server_client(testing_server):
    host, port = testing_server.bind_addr

    interface = webtest.interface(host)

    def probe_ipv6_sock(interface):
        import errno
        import socket
        from contextlib import closing
        try:
            with closing(socket.socket(family=socket.AF_INET6)) as sock:
                sock.bind((interface, 0))
        except OSError as sock_err:
            if sock_err.errno != errno.EADDRNOTAVAIL:
                raise
        else:
            return True

        return False

    if ':' in interface and not probe_ipv6_sock(interface):
{'fraction_non_alphanumeric': 0.10612855007473841, 'fraction_numerical': 0.0171898355754858, 'mean_word_length': 2.63408010862186, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, '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': '805664', 'n_tokens_mistral': 1724, 'n_tokens_neox': 1604, 'n_words': 437}