<commit_before>import re
import time
import socket
import unittest
from unit.applications.lang.python import TestApplicationPython


class TestProxy(TestApplicationPython):
    prerequisites = {'modules': ['python']}

    SERVER_PORT = 7999

    @staticmethod
    def run_server(server_port):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        server_address = ('', server_port)
        sock.bind(server_address)
        sock.listen(5)

        def recvall(sock):
            buff_size = 4096
            data = b''
            while True:
                part = sock.recv(buff_size)
                data += part
                if len(part) < buff_size:
                    break
            return data

        req = b"""HTTP/1.1 200 OK
Content-Length: 10

"""

        while True:
            connection, client_address = sock.accept()

            data = recvall(connection).decode()

            to_send = req

            m = re.search('X-Len: (\d+)', data)
            if m:
                to_send += b'X' * int(m.group(1))

            connection.sendall(to_send)

            connection.close()

    def get_http10(self, *args, **kwargs):
        return self.get(*args, http_10=True, **kwargs)

    def post_http10(self, *args, **kwargs):
        return self.post(*args, http_10=True, **kwargs)

    def setUp(self):
        super().setUp()

        self.run_process(self.run_server, self.SERVER_PORT)
        self.waitforsocket(self.SERVER_PORT)

        self.assertIn(
            'success',
            self.conf(
                {
                    "listeners": {
                        "*:7080": {"pass": "routes"},
                        "*:7081": {"pass": "applications/mirror"},
                    },
                    "routes": [{"action": {"proxy": "http://127.0.0.1:7081"}}],
                    "applications": {
                        "mirror": {
                            "type": "python",
                            "processes": {"spare": 0},
                            "path": self.current_dir + "/python/mirror",
                            "working_directory": self.current_dir
                            + "/python/mirror",
                            "module": "wsgi",
                        },
                        "custom_header": {
                            "type": "python",
                            "processes": {"spare": 0},
                            "path": self.current_dir + "/python/custom_header",
                            "working_directory": self.current_dir
                            + "/python/custom_header",
                            "module": "wsgi",
                        },
                        "delayed": {
                            "type": "python",
                            "processes": {"spare": 0},
                            "path": self.current_dir + "/python/delayed",
                            "working_directory": self.current_dir
                            + "/python/delayed",
                            "module": "wsgi",
                        },
                    },
                }
            ),
            'proxy initial configuration',
        )

    def test_proxy_http10(self):
        for _ in range(10):
            self.assertEqual(self.get_http10()['status'], 200, 'status')

    def test_proxy_chain(self):
        self.assertIn(
            'success',
            self.conf(
                {
                    "listeners": {
                        "*:7080": {"pass": "routes/first"},
                        "*:7081": {"pass": "routes/second"},
                        "*:7082": {"pass": "routes/third"},
                        "*:7083": {"pass": "routes/fourth"},
                        "*:7084": {"pass": "routes/fifth"},
                        "*:7085": {"pass": "applications/mirror"},
                    },
                    "routes": {
                        "first": [
                            {"action": {"proxy": "http://127.0.0.1:7081"}}
                        ],
                        "second": [
                            {"action": {"proxy": "http://127.0.0.1:7082"}}
                        ],
                        "third": [
                            {"action": {"proxy": "http://127.0.0.1:7083"}}
                        ],
                        "fourth": [
                            {"action": {"proxy": "http://127.0.0.1:7084"}}
                        ],
                        "fifth": [
                            {"action": {"proxy": "http://127.0.0.1:7085"}}
                        ],
                    },
                    "applications": {
                        "mirror": {
                            "type": "python",
                            "processes": {"spare": 0},
                            "path": self.current_dir + "/python/mirror",
                            "working_directory": self.current_dir
                            + "/python/mirror",
                            "module": "wsgi",
                        }
                    },
                }
            ),
            'proxy chain configuration',
        )

        self.assertEqual(self.get_http10()['status'], 200, 'status')

    def test_proxy_body(self):
        payload = '0123456789'
        for _ in range(10):
            resp = self.post_http10(body=payload)

            self.assertEqual(resp['status'], 200, 'status')
            self.assertEqual(resp['body'], payload, 'body')

        payload = 'X' * 4096
        for _ in range(10):
            resp = self.post_http10(body=payload)

            self.assertEqual(resp['status'], 200, 'status')
            self.assertEqual(resp['body'], payload, 'body')

        payload = 'X' * 4097
        for _ in range(10):
            resp = self.post_http10(body=payload)

            self.assertEqual(resp['status'], 200, 'status')
            self.assertEqual(resp['body'], payload, 'body')

        payload = 'X' * 4096 * 256
        for _ in range(10):
            resp = self.post_http10(body=payload, read_buffer_size=4096 * 128)

            self.assertEqual(resp['status'], 200, 'status')
            self.assertEqual(resp['body'], payload, 'body')

        payload = 'X' * 4096 * 257
        for _ in range(10):
            resp = self.post_http10(body=payload, read_buffer_size=4096 * 128)

            self.assertEqual(resp['status'], 200, 'status')
            self.assertEqual(resp['body'], payload, 'body')

    def test_proxy_parallel(self):
        payload = 'X' * 4096 * 257
        buff_size = 4096 * 258

        socks = []
        for i in range(10):
            _, sock = self.post_http10(
                body=payload + str(i),
                start=True,
                no_recv=True,<commit_msg>Tests: added proxy test with large body.<commit_after>import re
import time
import socket
import unittest
from unit.applications.lang.python import TestApplicationPython


class TestProxy(TestApplicationPython):
    prerequisites = {'modules': ['python']}

    SERVER_PORT = 7999

    @staticmethod
    def run_server(server_port):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        server_address = ('', server_port)
        sock.bind(server_address)
        sock.listen(5)

        def recvall(sock):
            buff_size = 4096
            data = b''
            while True:
                part = sock.recv(buff_size)
                data += part
                if len(part) < buff_size:
                    break
            return data

        req = b"""HTTP/1.1 200 OK
Content-Length: 10

"""

        while True:
            connection, client_address = sock.accept()

            data = recvall(connection).decode()

            to_send = req

            m = re.search('X-Len: (\d+)', data)
            if m:
                to_send += b'X' * int(m.group(1))

            connection.sendall(to_send)

            connection.close()

    def get_http10(self, *args, **kwargs):
        return self.get(*args, http_10=True, **kwargs)

    def post_http10(self, *args, **kwargs):
        return self.post(*args, http_10=True, **kwargs)

    def setUp(self):
        super().setUp()

        self.run_process(self.run_server, self.SERVER_PORT)
        self.waitforsocket(self.SERVER_PORT)

        self.assertIn(
            'success',
            self.conf(
                {
                    "listeners": {
                        "*:7080": {"pass": "routes"},
                        "*:7081": {"pass": "applications/mirror"},
                    },
                    "routes": [{"action": {"proxy": "http://127.0.0.1:7081"}}],
                    "applications": {
                        "mirror": {
                            "type": "python",
                            "processes": {"spare": 0},
                            "path": self.current_dir + "/python/mirror",
                            "working_directory": self.current_dir
                            + "/python/mirror",
                            "module": "wsgi",
                        },
                        "custom_header": {
                            "type": "python",
                            "processes": {"spare": 0},
                            "path": self.current_dir + "/python/custom_header",
                            "working_directory": self.current_dir
                            + "/python/custom_header",
                            "module": "wsgi",
                        },
                        "delayed": {
                            "type": "python",
                            "processes": {"spare": 0},
                            "path": self.current_dir + "/python/delayed",
                            "working_directory": self.current_dir
                            + "/python/delayed",
                            "module": "wsgi",
                        },
                    },
                }
            ),
            'proxy initial configuration',
        )

    def test_proxy_http10(self):
        for _ in range(10):
            self.assertEqual(self.get_http10()['status'], 200, 'status')

    def test_proxy_chain(self):
        self.assertIn(
            'success',
            self.conf(
                {
                    "listeners": {
                        "*:7080": {"pass": "routes/first"},
                        "*:7081": {"pass": "routes/second"},
                        "*:7082": {"pass": "routes/third"},
                        "*:7083": {"pass": "routes/fourth"},
                        "*:7084": {"pass": "routes/fifth"},
                        "*:7085": {"pass": "applications/mirror"},
                    },
                    "routes": {
                        "first": [
                            {"action": {"proxy": "http://127.0.0.1:7081"}}
                        ],
                        "second": [
                            {"action": {"proxy": "http://127.0.0.1:7082"}}
                        ],
                        "third": [
                            {"action": {"proxy": "http://127.0.0.1:7083"}}
                        ],
                        "fourth": [
                            {"action": {"proxy": "http://127.0.0.1:7084"}}
                        ],
                        "fifth": [
                            {"action": {"proxy": "http://127.0.0.1:7085"}}
                        ],
                    },
                    "applications": {
                        "mirror": {
                            "type": "python",
                            "processes": {"spare": 0},
                            "path": self.current_dir + "/python/mirror",
                            "working_directory": self.current_dir
                            + "/python/mirror",
                            "module": "wsgi",
                        }
                    },
                }
            ),
            'proxy chain configuration',
        )

        self.assertEqual(self.get_http10()['status'], 200, 'status')

    def test_proxy_body(self):
        payload = '0123456789'
        for _ in range(10):
            resp = self.post_http10(body=payload)

            self.assertEqual(resp['status'], 200, 'status')
            self.assertEqual(resp['body'], payload, 'body')

        payload = 'X' * 4096
        for _ in range(10):
            resp = self.post_http10(body=payload)

            self.assertEqual(resp['status'], 200, 'status')
            self.assertEqual(resp['body'], payload, 'body')

        payload = 'X' * 4097
        for _ in range(10):
            resp = self.post_http10(body=payload)

            self.assertEqual(resp['status'], 200, 'status')
            self.assertEqual(resp['body'], payload, 'body')

        payload = 'X' * 4096 * 256
        for _ in range(10):
            resp = self.post_http10(body=payload, read_buffer_size=4096 * 128)

            self.assertEqual(resp['status'], 200, 'status')
            self.assertEqual(resp['body'], payload, 'body')

        payload = 'X' * 4096 * 257
        for _ in range(10):
            resp = self.post_http10(body=payload, read_buffer_size=4096 * 128)

            self.assertEqual(resp['status'], 200, 'status')
            self.assertEqual(resp['body'], payload, 'body')

        self.conf({'http': {'max_body_size': 32 * 1024 * 1024}}, 'settings')

        payload = '0123456789abcdef' * 32 * 64 * 1024
        resp = self.post_http10(body=payload, read_buffer_size=1024 * 1024)
        self.assertEqual(resp['status'], 200, 'status')
        self.assertEqual(resp['body'], payload, 'body')

    def test_proxy_parallel(self):
        payload = 'X' * 4096 * 257
        buff_size = 4096 * 258

        socks = []
        for i in range(10):
            _, sock = self.post_http10(
                body=payload + str(i),
                start=True,
                no_recv=True,
{'fraction_non_alphanumeric': 0.1363377067883628, 'fraction_numerical': 0.036437535653166, 'mean_word_length': 1.186282151208106, 'pattern_counts': {'":': 134, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 12, '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': '7514226', 'n_tokens_mistral': 4105, 'n_tokens_neox': 3608, 'n_words': 684}