예제 #1
0
    def test_authenticated_proxy_http_tunnel(self,
                                             mock_server_connection: mock.Mock,
                                             mock_fromfd: mock.Mock,
                                             mock_selector: mock.Mock) -> None:
        server = mock_server_connection.return_value
        server.connect.return_value = True
        server.buffer_size.return_value = 0
        self._conn = mock_fromfd.return_value
        self.mock_selector_for_client_read_read_server_write(
            mock_selector, server)

        flags = Proxy.initialize(auth_code=base64.b64encode(b'user:pass'))
        flags.plugins = Proxy.load_plugins(
            [bytes_(PLUGIN_HTTP_PROXY),
             bytes_(PLUGIN_WEB_SERVER)])

        self.protocol_handler = HttpProtocolHandler(TcpClientConnection(
            self._conn, self._addr),
                                                    flags=flags)
        self.protocol_handler.initialize()

        assert self.http_server_port is not None
        self._conn.recv.return_value = CRLF.join([
            b'CONNECT localhost:%d HTTP/1.1' % self.http_server_port,
            b'Host: localhost:%d' % self.http_server_port,
            b'User-Agent: proxy.py/%s' % bytes_(__version__),
            b'Proxy-Connection: Keep-Alive',
            b'Proxy-Authorization: Basic dXNlcjpwYXNz', CRLF
        ])
        self.assert_tunnel_response(mock_server_connection, server)
        self.protocol_handler.client.flush()
        self.assert_data_queued_to_server(server)

        self.protocol_handler.run_once()
        server.flush.assert_called_once()
예제 #2
0
 def test_default_web_server_returns_404(
         self, mock_fromfd: mock.Mock, mock_selector: mock.Mock) -> None:
     self._conn = mock_fromfd.return_value
     mock_selector.return_value.select.return_value = [(
         selectors.SelectorKey(
             fileobj=self._conn,
             fd=self._conn.fileno,
             events=selectors.EVENT_READ,
             data=None), selectors.EVENT_READ), ]
     flags = Proxy.initialize()
     flags.plugins = Proxy.load_plugins([
         bytes_(PLUGIN_HTTP_PROXY),
         bytes_(PLUGIN_WEB_SERVER),
     ])
     self.protocol_handler = HttpProtocolHandler(
         TcpClientConnection(self._conn, self._addr),
         flags=flags)
     self.protocol_handler.initialize()
     self._conn.recv.return_value = CRLF.join([
         b'GET /hello HTTP/1.1',
         CRLF,
     ])
     self.protocol_handler.run_once()
     self.assertEqual(
         self.protocol_handler.request.state,
         httpParserStates.COMPLETE)
     self.assertEqual(
         self.protocol_handler.client.buffer[0],
         HttpWebServerPlugin.DEFAULT_404_RESPONSE)
예제 #3
0
    def test_static_web_server_serves(
            self, mock_fromfd: mock.Mock, mock_selector: mock.Mock) -> None:
        # Setup a static directory
        static_server_dir = os.path.join(tempfile.gettempdir(), 'static')
        index_file_path = os.path.join(static_server_dir, 'index.html')
        html_file_content = b'''<html><head></head><body><h1>Proxy.py Testing</h1></body></html>'''
        os.makedirs(static_server_dir, exist_ok=True)
        with open(index_file_path, 'wb') as f:
            f.write(html_file_content)

        self._conn = mock_fromfd.return_value
        self._conn.recv.return_value = build_http_request(
            b'GET', b'/index.html')

        mock_selector.return_value.select.side_effect = [
            [(selectors.SelectorKey(
                fileobj=self._conn,
                fd=self._conn.fileno,
                events=selectors.EVENT_READ,
                data=None), selectors.EVENT_READ)],
            [(selectors.SelectorKey(
                fileobj=self._conn,
                fd=self._conn.fileno,
                events=selectors.EVENT_WRITE,
                data=None), selectors.EVENT_WRITE)], ]

        flags = Proxy.initialize(
            enable_static_server=True,
            static_server_dir=static_server_dir)
        flags.plugins = Proxy.load_plugins([
            bytes_(PLUGIN_HTTP_PROXY),
            bytes_(PLUGIN_WEB_SERVER),
        ])

        self.protocol_handler = HttpProtocolHandler(
            TcpClientConnection(self._conn, self._addr),
            flags=flags)
        self.protocol_handler.initialize()

        self.protocol_handler.run_once()
        self.protocol_handler.run_once()

        self.assertEqual(mock_selector.return_value.select.call_count, 2)
        self.assertEqual(self._conn.send.call_count, 1)
        encoded_html_file_content = gzip.compress(html_file_content)
        self.assertEqual(self._conn.send.call_args[0][0], build_http_response(
            200, reason=b'OK', headers={
                b'Content-Type': b'text/html',
                b'Cache-Control': b'max-age=86400',
                b'Content-Encoding': b'gzip',
                b'Connection': b'close',
                b'Content-Length': bytes_(len(encoded_html_file_content)),
            },
            body=encoded_html_file_content
        ))
예제 #4
0
 def setUp(self, mock_fromfd: mock.Mock, mock_selector: mock.Mock) -> None:
     self.fileno = 10
     self._addr = ('127.0.0.1', 54382)
     self._conn = mock_fromfd.return_value
     self.mock_selector = mock_selector
     self.flags = Proxy.initialize()
     self.flags.plugins = Proxy.load_plugins([
         bytes_(PLUGIN_HTTP_PROXY),
         bytes_(PLUGIN_WEB_SERVER),
     ])
     self.protocol_handler = HttpProtocolHandler(
         TcpClientConnection(self._conn, self._addr),
         flags=self.flags)
     self.protocol_handler.initialize()
예제 #5
0
 def init_and_make_pac_file_request(self, pac_file: str) -> None:
     flags = Proxy.initialize(pac_file=pac_file)
     flags.plugins = Proxy.load_plugins([
         bytes_(PLUGIN_HTTP_PROXY),
         bytes_(PLUGIN_WEB_SERVER),
         bytes_(PLUGIN_PAC_FILE),
     ])
     self.protocol_handler = HttpProtocolHandler(
         TcpClientConnection(self._conn, self._addr),
         flags=flags)
     self.protocol_handler.initialize()
     self._conn.recv.return_value = CRLF.join([
         b'GET / HTTP/1.1',
         CRLF,
     ])
예제 #6
0
    def test_authenticated_proxy_http_get(self,
                                          mock_server_connection: mock.Mock,
                                          mock_fromfd: mock.Mock,
                                          mock_selector: mock.Mock) -> None:
        self._conn = mock_fromfd.return_value
        self.mock_selector_for_client_read(mock_selector)

        server = mock_server_connection.return_value
        server.connect.return_value = True
        server.buffer_size.return_value = 0

        flags = Proxy.initialize(auth_code=base64.b64encode(b'user:pass'))
        flags.plugins = Proxy.load_plugins([
            bytes_(PLUGIN_HTTP_PROXY),
            bytes_(PLUGIN_WEB_SERVER),
        ])

        self.protocol_handler = HttpProtocolHandler(TcpClientConnection(
            self._conn, self._addr),
                                                    flags=flags)
        self.protocol_handler.initialize()
        assert self.http_server_port is not None

        self._conn.recv.return_value = b'GET http://localhost:%d HTTP/1.1' % self.http_server_port
        self.protocol_handler.run_once()
        self.assertEqual(self.protocol_handler.request.state,
                         httpParserStates.INITIALIZED)

        self._conn.recv.return_value = CRLF
        self.protocol_handler.run_once()
        self.assertEqual(self.protocol_handler.request.state,
                         httpParserStates.LINE_RCVD)

        assert self.http_server_port is not None
        self._conn.recv.return_value = CRLF.join([
            b'User-Agent: proxy.py/%s' % bytes_(__version__),
            b'Host: localhost:%d' % self.http_server_port, b'Accept: */*',
            b'Proxy-Connection: Keep-Alive',
            b'Proxy-Authorization: Basic dXNlcjpwYXNz', CRLF
        ])
        self.assert_data_queued(mock_server_connection, server)
예제 #7
0
 def test_proxy_authentication_failed(self, mock_fromfd: mock.Mock,
                                      mock_selector: mock.Mock) -> None:
     self._conn = mock_fromfd.return_value
     self.mock_selector_for_client_read(mock_selector)
     flags = Proxy.initialize(auth_code=base64.b64encode(b'user:pass'))
     flags.plugins = Proxy.load_plugins([
         bytes_(PLUGIN_HTTP_PROXY),
         bytes_(PLUGIN_WEB_SERVER),
         bytes_(PLUGIN_PROXY_AUTH),
     ])
     self.protocol_handler = HttpProtocolHandler(TcpClientConnection(
         self._conn, self._addr),
                                                 flags=flags)
     self.protocol_handler.initialize()
     self._conn.recv.return_value = CRLF.join([
         b'GET http://abhinavsingh.com HTTP/1.1', b'Host: abhinavsingh.com',
         CRLF
     ])
     self.protocol_handler.run_once()
     self.assertEqual(self.protocol_handler.client.buffer[0],
                      ProxyAuthenticationFailed.RESPONSE_PKT)
예제 #8
0
    def test_static_web_server_serves_404(
            self,
            mock_fromfd: mock.Mock,
            mock_selector: mock.Mock) -> None:
        self._conn = mock_fromfd.return_value
        self._conn.recv.return_value = build_http_request(
            b'GET', b'/not-found.html')

        mock_selector.return_value.select.side_effect = [
            [(selectors.SelectorKey(
                fileobj=self._conn,
                fd=self._conn.fileno,
                events=selectors.EVENT_READ,
                data=None), selectors.EVENT_READ)],
            [(selectors.SelectorKey(
                fileobj=self._conn,
                fd=self._conn.fileno,
                events=selectors.EVENT_WRITE,
                data=None), selectors.EVENT_WRITE)], ]

        flags = Proxy.initialize(enable_static_server=True)
        flags.plugins = Proxy.load_plugins([
            bytes_(PLUGIN_HTTP_PROXY),
            bytes_(PLUGIN_WEB_SERVER),
        ])

        self.protocol_handler = HttpProtocolHandler(
            TcpClientConnection(self._conn, self._addr),
            flags=flags)
        self.protocol_handler.initialize()

        self.protocol_handler.run_once()
        self.protocol_handler.run_once()

        self.assertEqual(mock_selector.return_value.select.call_count, 2)
        self.assertEqual(self._conn.send.call_count, 1)
        self.assertEqual(self._conn.send.call_args[0][0],
                         HttpWebServerPlugin.DEFAULT_404_RESPONSE)