def assert_pipeline_response(self, response: bytes) -> None: self.parser = HttpParser(httpParserTypes.RESPONSE_PARSER) self.parser.parse(response + response) self.assertEqual(self.parser.state, httpParserStates.COMPLETE) self.assertEqual(self.parser.body, b'{"key":"value"}') self.assertEqual(self.parser.buffer, response) # parse buffer parser = HttpParser(httpParserTypes.RESPONSE_PARSER) parser.parse(self.parser.buffer) self.assertEqual(parser.state, httpParserStates.COMPLETE) self.assertEqual(parser.body, b'{"key":"value"}') self.assertEqual(parser.buffer, b'')
def test_paramiko_doc(self) -> None: response = b'HTTP/1.1 304 Not Modified\r\nDate: Tue, 03 Dec 2019 02:31:55 GMT\r\nConnection: keep-alive' \ b'\r\nLast-Modified: Sun, 23 Jun 2019 22:58:21 GMT\r\nETag: "5d10040d-1af2c"' \ b'\r\nX-Cname-TryFiles: True\r\nX-Served: Nginx\r\nX-Deity: web02\r\nCF-Cache-Status: DYNAMIC' \ b'\r\nServer: cloudflare\r\nCF-RAY: 53f2208c6fef6c38-SJC\r\n\r\n' self.parser = HttpParser(httpParserTypes.RESPONSE_PARSER) self.parser.parse(response) self.assertEqual(self.parser.state, httpParserStates.COMPLETE)
async def test_static_web_server_serves(self) -> None: self._conn.recv.return_value = build_http_request( b'GET', b'/index.html', ) self.mock_selector.return_value.select.side_effect = [ [( selectors.SelectorKey( fileobj=self._conn.fileno(), fd=self._conn.fileno(), events=selectors.EVENT_READ, data=None, ), selectors.EVENT_READ, )], [( selectors.SelectorKey( fileobj=self._conn.fileno(), fd=self._conn.fileno(), events=selectors.EVENT_WRITE, data=None, ), selectors.EVENT_WRITE, )], ] await self.protocol_handler._run_once() await self.protocol_handler._run_once() self.assertEqual(self.mock_selector.return_value.select.call_count, 2) self.assertEqual(self._conn.send.call_count, 1) encoded_html_file_content = gzip.compress(self.html_file_content) # parse response and verify response = HttpParser(httpParserTypes.RESPONSE_PARSER) response.parse(self._conn.send.call_args[0][0]) self.assertEqual(response.code, b'200') self.assertEqual(response.header(b'content-type'), b'text/html') self.assertEqual(response.header(b'cache-control'), b'max-age=86400') self.assertEqual(response.header(b'content-encoding'), b'gzip') self.assertEqual(response.header(b'connection'), b'close') self.assertEqual( response.header(b'content-length'), bytes_(len(encoded_html_file_content)), ) assert response.body self.assertEqual( gzip.decompress(response.body), self.html_file_content, )
async def test_man_in_the_middle_plugin(self) -> None: await self.protocol_handler._run_once() self.assertEqual(self.mock_sign_csr.call_count, 1) self.assertEqual(self.mock_gen_csr.call_count, 1) self.assertEqual(self.mock_gen_public_key.call_count, 1) self.mock_server_conn.assert_called_once_with('uni.corn', 443) self.server.connect.assert_called() self.assertEqual( self.protocol_handler.work.connection, self.client_ssl_connection, ) self.assertEqual(self.server.connection, self.server_ssl_connection) self._conn.send.assert_called_with( PROXY_TUNNEL_ESTABLISHED_RESPONSE_PKT, ) self.assertFalse(self.protocol_handler.work.has_buffer()) # request = build_http_request( b'GET', b'/', headers={ b'Host': b'uni.corn', }, no_ua=True, ) self.client_ssl_connection.recv.return_value = request # Client read await self.protocol_handler._run_once() self.server.queue.assert_called_once_with(request) # Server write await self.protocol_handler._run_once() self.server.flush.assert_called_once() # Server read self.server.recv.return_value = okResponse( content=b'Original Response From Upstream', ) await self.protocol_handler._run_once() response = HttpParser(httpParserTypes.RESPONSE_PARSER) response.parse(self.protocol_handler.work.buffer[0]) assert response.body self.assertEqual( gzip.decompress(response.body), b'Hello from man in the middle', )
def assert_tunnel_response(self, mock_server_connection: mock.Mock, server: mock.Mock) -> None: self.protocol_handler.run_once() self.assertTrue( cast(HttpProxyPlugin, self.protocol_handler. plugins['HttpProxyPlugin']).server is not None) self.assertEqual(self.protocol_handler.client.buffer[0], HttpProxyPlugin.PROXY_TUNNEL_ESTABLISHED_RESPONSE_PKT) mock_server_connection.assert_called_once() server.connect.assert_called_once() server.queue.assert_not_called() server.closed = False parser = HttpParser(httpParserTypes.RESPONSE_PARSER) parser.parse(self.protocol_handler.client.buffer[0].tobytes()) self.assertEqual(parser.state, httpParserStates.COMPLETE) assert parser.code is not None self.assertEqual(int(parser.code), 200)
def test_issue_398(self) -> None: p = HttpParser(httpParserTypes.RESPONSE_PARSER) p.parse(HTTP_1_0 + b' 200 OK' + CRLF) self.assertEqual(p.version, HTTP_1_0) self.assertEqual(p.code, b'200') self.assertEqual(p.reason, b'OK') self.assertEqual(p.state, httpParserStates.LINE_RCVD) p.parse( b'CP=CAO PSA OUR' + CRLF + b'Cache-Control:private,max-age=0;' + CRLF + b'X-Frame-Options:SAMEORIGIN' + CRLF + b'X-Content-Type-Options:nosniff' + CRLF + b'X-XSS-Protection:1; mode=block' + CRLF + b'Content-Security-Policy:default-src \'self\' \'unsafe-inline\' \'unsafe-eval\'' + CRLF + b'Strict-Transport-Security:max-age=2592000; includeSubdomains' + CRLF + b'Set-Cookie: lang=eng; path=/;HttpOnly;' + CRLF + b'Content-type:text/html;charset=UTF-8;' + CRLF + CRLF + b'<!-- HTML RESPONSE HERE -->', ) self.assertEqual(p.body, b'<!-- HTML RESPONSE HERE -->') self.assertEqual(p.state, httpParserStates.RCVING_BODY)
async def test_proposed_rest_api_plugin(self) -> None: path = b'/v1/users/' self._conn.recv.return_value = build_http_request( b'GET', b'http://%s%s' % ( ProposedRestApiPlugin.API_SERVER, path, ), headers={ b'Host': ProposedRestApiPlugin.API_SERVER, }, ) self.mock_selector.return_value.select.side_effect = [ [( selectors.SelectorKey( fileobj=self._conn.fileno(), fd=self._conn.fileno(), events=selectors.EVENT_READ, data=None, ), selectors.EVENT_READ, )], ] await self.protocol_handler._run_once() self.mock_server_conn.assert_not_called() response = HttpParser(httpParserTypes.RESPONSE_PARSER) response.parse(self.protocol_handler.work.buffer[0]) assert response.body self.assertEqual( response.header(b'content-type'), b'application/json', ) self.assertEqual( response.header(b'content-encoding'), b'gzip', ) self.assertEqual( gzip.decompress(response.body), bytes_(json.dumps(ProposedRestApiPlugin.REST_API_SPEC[path], ), ), )
async def assert_tunnel_response( self, server: mock.Mock, ) -> None: await self.protocol_handler._run_once() self.assertTrue( cast( HttpProxyPlugin, self.protocol_handler.plugin, ).upstream is not None, ) self.assertEqual( self.protocol_handler.work.buffer[0], PROXY_TUNNEL_ESTABLISHED_RESPONSE_PKT, ) self.mock_server_connection.assert_called_once() server.connect.assert_called_once() server.queue.assert_not_called() server.closed = False parser = HttpParser(httpParserTypes.RESPONSE_PARSER) parser.parse(self.protocol_handler.work.buffer[0]) self.assertEqual(parser.state, httpParserStates.COMPLETE) assert parser.code is not None self.assertEqual(int(parser.code), 200)
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.request = HttpParser(httpParserTypes.REQUEST_PARSER) self.response = HttpParser(httpParserTypes.RESPONSE_PARSER)
def setUp(self) -> None: self.request = HttpParser(httpParserTypes.REQUEST_PARSER)
def __init__(self, *args: Any, **kwargs: Any) -> None: super().__init__(*args, **kwargs) self.response = HttpParser(httpParserTypes.RESPONSE_PARSER)
async def test_man_in_the_middle_plugin(self) -> None: request = build_http_request( b'GET', b'http://super.secure/', headers={ b'Host': b'super.secure', }, no_ua=True, ) self._conn.recv.return_value = request server = self.mock_server_conn.return_value server.connect.return_value = True def has_buffer() -> bool: return cast(bool, server.queue.called) def closed() -> bool: return not server.connect.called server.has_buffer.side_effect = has_buffer type(server).closed = mock.PropertyMock(side_effect=closed) self.mock_selector.return_value.select.side_effect = [ [( selectors.SelectorKey( fileobj=self._conn.fileno(), fd=self._conn.fileno(), events=selectors.EVENT_READ, data=None, ), selectors.EVENT_READ, )], [( selectors.SelectorKey( fileobj=server.connection.fileno(), fd=server.connection.fileno(), events=selectors.EVENT_WRITE, data=None, ), selectors.EVENT_WRITE, )], [( selectors.SelectorKey( fileobj=server.connection.fileno(), fd=server.connection.fileno(), events=selectors.EVENT_READ, data=None, ), selectors.EVENT_READ, )], ] # Client read await self.protocol_handler._run_once() self.mock_server_conn.assert_called_with( 'super.secure', DEFAULT_HTTP_PORT, ) server.connect.assert_called_once() queued_request = \ build_http_request( b'GET', b'/', headers={ b'Host': b'super.secure', b'Via': b'1.1 %s' % PROXY_AGENT_HEADER_VALUE, }, no_ua=True, ) server.queue.assert_called_once() print(server.queue.call_args_list[0][0][0].tobytes()) print(queued_request) self.assertEqual(server.queue.call_args_list[0][0][0], queued_request) # Server write await self.protocol_handler._run_once() server.flush.assert_called_once() # Server read server.recv.return_value = \ build_http_response( httpStatusCodes.OK, reason=b'OK', body=b'Original Response From Upstream', ) await self.protocol_handler._run_once() response = HttpParser(httpParserTypes.RESPONSE_PARSER) response.parse(self.protocol_handler.work.buffer[0]) assert response.body self.assertEqual( gzip.decompress(response.body), b'Hello from man in the middle', )
def test_proxy_protocol_not_for_response_parser(self) -> None: with self.assertRaises(AssertionError): HttpParser( httpParserTypes.RESPONSE_PARSER, enable_proxy_protocol=True, )