mcp-proxy-adapter 6.6.1__tar.gz → 6.6.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/PKG-INFO +1 -1
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/api/app.py +28 -26
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/config.py +2 -9
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/server_adapter.py +1 -1
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/check_config.py +1 -1
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/config_builder.py +11 -17
- mcp_proxy_adapter-6.6.1/mcp_proxy_adapter/examples/generate_certificates_bugfix.py → mcp_proxy_adapter-6.6.3/mcp_proxy_adapter/examples/generate_certificates.py +11 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/generate_config.py +3 -3
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/run_full_test_suite.py +3 -3
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/security_test_client.py +6 -5
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/test_chk_hostname_automated.py +7 -10
- mcp_proxy_adapter-6.6.3/mcp_proxy_adapter/examples/test_framework_complete.py +269 -0
- mcp_proxy_adapter-6.6.3/mcp_proxy_adapter/examples/test_mcp_server.py +188 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/main.py +11 -18
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/version.py +1 -1
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter.egg-info/PKG-INFO +1 -1
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter.egg-info/SOURCES.txt +6 -14
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/pyproject.toml +1 -1
- mcp_proxy_adapter-6.6.1/mcp_proxy_adapter/examples/config_builder_simple.py +0 -271
- mcp_proxy_adapter-6.6.1/mcp_proxy_adapter/examples/generate_all_certificates.py +0 -487
- mcp_proxy_adapter-6.6.1/mcp_proxy_adapter/examples/generate_certificates_cli.py +0 -406
- mcp_proxy_adapter-6.6.1/mcp_proxy_adapter/examples/generate_certificates_fixed.py +0 -313
- mcp_proxy_adapter-6.6.1/mcp_proxy_adapter/examples/generate_certificates_framework.py +0 -366
- mcp_proxy_adapter-6.6.1/mcp_proxy_adapter/examples/generate_certificates_openssl.py +0 -391
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/README.md +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/__main__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/api/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/api/handlers.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/api/middleware/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/api/middleware/base.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/api/middleware/command_permission_middleware.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/api/middleware/error_handling.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/api/middleware/factory.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/api/middleware/logging.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/api/middleware/performance.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/api/middleware/protocol_middleware.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/api/middleware/transport_middleware.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/api/middleware/unified_security.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/api/middleware/user_info_middleware.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/api/schemas.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/api/tool_integration.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/api/tools.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/auth_validation_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/base.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/builtin_commands.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/catalog_manager.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/cert_monitor_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/certificate_management_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/command_registry.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/config_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/dependency_container.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/dependency_manager.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/echo_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/health_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/help_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/hooks.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/key_management_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/load_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/plugins_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/protocol_management_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/proxy_registration_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/reload_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/result.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/role_test_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/roles_management_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/security_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/settings_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/ssl_setup_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/token_management_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/transport_management_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/commands/unload_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/app_factory.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/app_runner.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/auth_validator.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/certificate_utils.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/client.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/client_manager.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/client_security.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/config_converter.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/config_validator.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/crl_utils.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/errors.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/logging.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/mtls_asgi.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/mtls_asgi_app.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/mtls_server.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/protocol_manager.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/proxy_client.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/proxy_registration.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/role_utils.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/security_adapter.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/security_factory.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/security_integration.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/server_engine.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/settings.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/ssl_utils.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/transport_manager.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/unified_config_adapter.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/utils.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/custom_openapi.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/basic_framework/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/basic_framework/commands/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/basic_framework/hooks/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/basic_framework/main.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/bugfix_certificate_config.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/cert_manager_bugfix.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/commands/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/config_cli.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/create_test_configs.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/debug_request_state.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/debug_role_chain.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/demo_client.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/full_application/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/full_application/commands/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/full_application/commands/custom_echo_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/full_application/commands/dynamic_calculator_command.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/full_application/hooks/__init__.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/full_application/hooks/application_hooks.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/full_application/hooks/builtin_command_hooks.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/full_application/main.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/full_application/proxy_endpoints.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/proxy_registration_example.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/required_certificates.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/run_example.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/run_proxy_server.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/run_security_tests_fixed.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/setup_test_environment.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/simple_protocol_test.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/test_config.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/test_config_builder.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/test_examples.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/test_protocol_examples.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/universal_client.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/update_config_certificates.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/openapi.py +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/schemas/base_schema.json +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/schemas/openapi_schema.json +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/schemas/roles.json +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/schemas/roles_schema.json +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter.egg-info/dependency_links.txt +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter.egg-info/entry_points.txt +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter.egg-info/not-zip-safe +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter.egg-info/requires.txt +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter.egg-info/top_level.txt +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/setup.cfg +0 -0
- {mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/setup.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: mcp-proxy-adapter
|
3
|
-
Version: 6.6.
|
3
|
+
Version: 6.6.3
|
4
4
|
Summary: Powerful JSON-RPC microservices framework with built-in security, authentication, and proxy registration
|
5
5
|
Home-page: https://github.com/maverikod/mcp-proxy-adapter
|
6
6
|
Author: Vasiliy Zdanovskiy
|
@@ -88,11 +88,11 @@ def create_lifespan(config_path: Optional[str] = None):
|
|
88
88
|
public_host = reg_cfg.get("public_host")
|
89
89
|
public_port = reg_cfg.get("public_port")
|
90
90
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
protocol = "https" if
|
91
|
+
# Check SSL configuration from new structure
|
92
|
+
protocol = config.get("server.protocol", "http")
|
93
|
+
verify_client = config.get("transport.verify_client", False)
|
94
|
+
ssl_enabled = protocol in ["https", "mtls"] or verify_client
|
95
|
+
protocol = "https" if ssl_enabled else "http"
|
96
96
|
|
97
97
|
import os
|
98
98
|
docker_host_addr = os.getenv("DOCKER_HOST_ADDR", "172.17.0.1")
|
@@ -227,20 +227,26 @@ def create_ssl_context(
|
|
227
227
|
"""
|
228
228
|
current_config = app_config if app_config is not None else config.get_all()
|
229
229
|
|
230
|
-
#
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
# Fallback to legacy SSL config
|
235
|
-
if not ssl_config.get("enabled", False):
|
236
|
-
ssl_config = current_config.get("ssl", {})
|
230
|
+
# Check SSL configuration from new structure
|
231
|
+
protocol = current_config.get("server", {}).get("protocol", "http")
|
232
|
+
verify_client = current_config.get("transport", {}).get("verify_client", False)
|
233
|
+
ssl_enabled = protocol in ["https", "mtls"] or verify_client
|
237
234
|
|
238
|
-
if not
|
235
|
+
if not ssl_enabled:
|
239
236
|
logger.info("SSL is disabled in configuration")
|
240
237
|
return None
|
241
238
|
|
242
|
-
|
243
|
-
|
239
|
+
# Get certificate paths from configuration
|
240
|
+
cert_file = current_config.get("ssl", {}).get("cert_file")
|
241
|
+
key_file = current_config.get("ssl", {}).get("key_file")
|
242
|
+
|
243
|
+
# If not found in ssl section, use default paths
|
244
|
+
if not cert_file:
|
245
|
+
project_root = Path(__file__).parent.parent.parent
|
246
|
+
cert_file = str(project_root / "certs" / "server.crt")
|
247
|
+
if not key_file:
|
248
|
+
project_root = Path(__file__).parent.parent.parent
|
249
|
+
key_file = str(project_root / "certs" / "server.key")
|
244
250
|
|
245
251
|
if not cert_file or not key_file:
|
246
252
|
logger.warning("SSL enabled but certificate or key file not specified")
|
@@ -308,17 +314,13 @@ def create_app(
|
|
308
314
|
print(
|
309
315
|
f"🔍 Debug: create_app received app_config keys: {list(app_config.keys())}"
|
310
316
|
)
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
)
|
319
|
-
print(
|
320
|
-
f"🔍 Debug: create_app SSL config: key_file={ssl_config.get('key_file')}"
|
321
|
-
)
|
317
|
+
# Debug SSL configuration
|
318
|
+
protocol = app_config.get("server", {}).get("protocol", "http")
|
319
|
+
verify_client = app_config.get("transport", {}).get("verify_client", False)
|
320
|
+
ssl_enabled = protocol in ["https", "mtls"] or verify_client
|
321
|
+
print(f"🔍 Debug: create_app SSL config: enabled={ssl_enabled}")
|
322
|
+
print(f"🔍 Debug: create_app protocol: {protocol}")
|
323
|
+
print(f"🔍 Debug: create_app verify_client: {verify_client}")
|
322
324
|
else:
|
323
325
|
print(f"🔍 Debug: create_app received app_config type: {type(app_config)}")
|
324
326
|
else:
|
@@ -84,15 +84,8 @@ class Config:
|
|
84
84
|
"transport": {
|
85
85
|
"type": "http",
|
86
86
|
"port": None,
|
87
|
-
"
|
88
|
-
|
89
|
-
"cert_file": None,
|
90
|
-
"key_file": None,
|
91
|
-
"ca_cert": None,
|
92
|
-
"verify_client": False,
|
93
|
-
"client_cert_required": False,
|
94
|
-
"chk_hostname": False, # Default to False when SSL is disabled
|
95
|
-
},
|
87
|
+
"verify_client": False,
|
88
|
+
"chk_hostname": False, # Default to False for HTTP
|
96
89
|
},
|
97
90
|
"proxy_registration": {
|
98
91
|
"enabled": False,
|
{mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/core/server_adapter.py
RENAMED
@@ -65,7 +65,7 @@ class ServerConfigAdapter:
|
|
65
65
|
|
66
66
|
# Map verification mode
|
67
67
|
if ssl_config.get("verify_client", False):
|
68
|
-
hypercorn_ssl["verify_mode"] =
|
68
|
+
hypercorn_ssl["verify_mode"] = 2 # ssl.CERT_REQUIRED
|
69
69
|
|
70
70
|
# Map hostname checking
|
71
71
|
if "chk_hostname" in ssl_config:
|
{mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/check_config.py
RENAMED
@@ -15,7 +15,7 @@ from pathlib import Path
|
|
15
15
|
from typing import Dict, Any, List, Optional
|
16
16
|
|
17
17
|
# Add the project root to the path
|
18
|
-
sys.path.insert(0, str(Path(__file__).parent))
|
18
|
+
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
|
19
19
|
|
20
20
|
from mcp_proxy_adapter.config import Config
|
21
21
|
from mcp_proxy_adapter.examples.config_builder import ConfigBuilder, Protocol, AuthMethod
|
{mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/config_builder.py
RENAMED
@@ -77,15 +77,8 @@ class ConfigBuilder:
|
|
77
77
|
"transport": {
|
78
78
|
"type": "http",
|
79
79
|
"port": None,
|
80
|
-
"
|
81
|
-
|
82
|
-
"cert_file": None,
|
83
|
-
"key_file": None,
|
84
|
-
"ca_cert": None,
|
85
|
-
"verify_client": False,
|
86
|
-
"client_cert_required": False,
|
87
|
-
"chk_hostname": False,
|
88
|
-
},
|
80
|
+
"verify_client": False,
|
81
|
+
"chk_hostname": False
|
89
82
|
}
|
90
83
|
}
|
91
84
|
|
@@ -94,18 +87,19 @@ class ConfigBuilder:
|
|
94
87
|
self.config["server"]["protocol"] = protocol.value
|
95
88
|
|
96
89
|
if protocol == Protocol.HTTP:
|
97
|
-
# HTTP - no SSL
|
98
|
-
|
90
|
+
# HTTP - no SSL, no client verification
|
91
|
+
self.config["transport"]["verify_client"] = False
|
92
|
+
self.config["transport"]["chk_hostname"] = False
|
99
93
|
|
100
94
|
elif protocol == Protocol.HTTPS:
|
101
|
-
# HTTPS -
|
102
|
-
|
103
|
-
|
95
|
+
# HTTPS - SSL enabled, no client verification
|
96
|
+
self.config["transport"]["verify_client"] = False
|
97
|
+
self.config["transport"]["chk_hostname"] = True
|
104
98
|
|
105
99
|
elif protocol == Protocol.MTLS:
|
106
|
-
# mTLS -
|
107
|
-
|
108
|
-
|
100
|
+
# mTLS - SSL enabled, client verification required
|
101
|
+
self.config["transport"]["verify_client"] = True
|
102
|
+
self.config["transport"]["chk_hostname"] = True
|
109
103
|
|
110
104
|
return self
|
111
105
|
|
@@ -229,7 +229,18 @@ class BugfixCertificateGenerator:
|
|
229
229
|
with open(client_info["output_key"], 'w') as f:
|
230
230
|
f.write(result.private_key_pem)
|
231
231
|
|
232
|
+
# Also create a copy in certs/ directory for easier access
|
233
|
+
cert_name_base = client_info["common_name"].replace("-", "_")
|
234
|
+
certs_cert = self.certs_dir / f"{cert_name_base}_client.crt"
|
235
|
+
certs_key = self.certs_dir / f"{cert_name_base}_client.key"
|
236
|
+
|
237
|
+
with open(certs_cert, 'w') as f:
|
238
|
+
f.write(result.certificate_pem)
|
239
|
+
with open(certs_key, 'w') as f:
|
240
|
+
f.write(result.private_key_pem)
|
241
|
+
|
232
242
|
self.print_success(f"{cert_name} certificate generated: {client_info['output_cert']}")
|
243
|
+
self.print_success(f"Also created: {certs_cert} and {certs_key}")
|
233
244
|
return True
|
234
245
|
else:
|
235
246
|
self.print_error(f"Failed to generate {cert_name} certificate")
|
{mcp_proxy_adapter-6.6.1 → mcp_proxy_adapter-6.6.3}/mcp_proxy_adapter/examples/generate_config.py
RENAMED
@@ -12,10 +12,10 @@ import sys
|
|
12
12
|
from pathlib import Path
|
13
13
|
from typing import Dict, Any, Optional
|
14
14
|
|
15
|
-
# Add the
|
16
|
-
sys.path.insert(0, str(Path(__file__).parent
|
15
|
+
# Add the project root to the path to import config_builder
|
16
|
+
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
|
17
17
|
|
18
|
-
from config_builder import ConfigBuilder, ConfigFactory, Protocol, AuthMethod
|
18
|
+
from mcp_proxy_adapter.examples.config_builder import ConfigBuilder, ConfigFactory, Protocol, AuthMethod
|
19
19
|
|
20
20
|
|
21
21
|
def create_config_from_flags(
|
@@ -113,7 +113,7 @@ class FullTestSuiteRunner:
|
|
113
113
|
|
114
114
|
try:
|
115
115
|
# Check if certificate generation script exists
|
116
|
-
cert_script = self.working_dir / "
|
116
|
+
cert_script = self.working_dir / "mcp_proxy_adapter" / "examples" / "generate_certificates.py"
|
117
117
|
if not cert_script.exists():
|
118
118
|
self.print_error(
|
119
119
|
f"Certificate generation script not found: {cert_script}"
|
@@ -167,7 +167,7 @@ class FullTestSuiteRunner:
|
|
167
167
|
|
168
168
|
try:
|
169
169
|
# Check if create_test_configs.py exists
|
170
|
-
config_script = self.working_dir / "create_test_configs.py"
|
170
|
+
config_script = self.working_dir / "mcp_proxy_adapter" / "examples" / "create_test_configs.py"
|
171
171
|
if not config_script.exists():
|
172
172
|
self.print_error(f"Configuration generator not found: {config_script}")
|
173
173
|
return False
|
@@ -194,7 +194,7 @@ class FullTestSuiteRunner:
|
|
194
194
|
# Run the configuration generator
|
195
195
|
cmd = [
|
196
196
|
sys.executable,
|
197
|
-
"create_test_configs.py",
|
197
|
+
"mcp_proxy_adapter/examples/create_test_configs.py",
|
198
198
|
"--comprehensive-config",
|
199
199
|
"comprehensive_config.json",
|
200
200
|
]
|
@@ -124,11 +124,12 @@ class SecurityTestClient:
|
|
124
124
|
def create_ssl_context_for_mtls(self) -> ssl.SSLContext:
|
125
125
|
"""Create SSL context for mTLS connections."""
|
126
126
|
# For mTLS, we need client certificates - check if they exist
|
127
|
-
#
|
128
|
-
# Use
|
129
|
-
|
130
|
-
|
131
|
-
|
127
|
+
# Use absolute paths to avoid issues with working directory
|
128
|
+
# Use newly generated admin_client_client.crt which is signed by the same CA as server
|
129
|
+
project_root = Path(__file__).parent.parent.parent
|
130
|
+
cert_file = str(project_root / "certs" / "admin_client_client.crt")
|
131
|
+
key_file = str(project_root / "keys" / "admin-client_client.key")
|
132
|
+
ca_cert_file = str(project_root / "certs" / "localhost_server.crt")
|
132
133
|
|
133
134
|
# CRITICAL: For mTLS, certificates are REQUIRED
|
134
135
|
if not os.path.exists(cert_file):
|
@@ -13,7 +13,7 @@ from pathlib import Path
|
|
13
13
|
import sys
|
14
14
|
|
15
15
|
# Add the project root to the path
|
16
|
-
sys.path.insert(0, str(Path(__file__).parent))
|
16
|
+
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
|
17
17
|
|
18
18
|
from mcp_proxy_adapter.config import Config
|
19
19
|
from mcp_proxy_adapter.examples.config_builder import ConfigBuilder, Protocol, AuthMethod
|
@@ -27,7 +27,7 @@ def test_chk_hostname_default_config():
|
|
27
27
|
|
28
28
|
# Default should be HTTP with chk_hostname=False
|
29
29
|
assert config.get("server.protocol") == "http"
|
30
|
-
assert config.get("transport.
|
30
|
+
assert config.get("transport.chk_hostname") is False
|
31
31
|
|
32
32
|
print("✅ Default config: chk_hostname=False for HTTP")
|
33
33
|
|
@@ -49,7 +49,7 @@ def test_chk_hostname_http_config():
|
|
49
49
|
|
50
50
|
# HTTP should have chk_hostname=False
|
51
51
|
assert config.get("server.protocol") == "http"
|
52
|
-
assert config.get("transport.
|
52
|
+
assert config.get("transport.chk_hostname") is False
|
53
53
|
|
54
54
|
print("✅ HTTP config: chk_hostname=False")
|
55
55
|
finally:
|
@@ -74,7 +74,7 @@ def test_chk_hostname_https_config():
|
|
74
74
|
|
75
75
|
# HTTPS should have chk_hostname=True
|
76
76
|
assert config.get("server.protocol") == "https"
|
77
|
-
assert config.get("transport.
|
77
|
+
assert config.get("transport.chk_hostname") is True
|
78
78
|
|
79
79
|
print("✅ HTTPS config: chk_hostname=True")
|
80
80
|
finally:
|
@@ -98,7 +98,7 @@ def test_chk_hostname_mtls_config():
|
|
98
98
|
|
99
99
|
# mTLS should have chk_hostname=True
|
100
100
|
assert config.get("server.protocol") == "mtls"
|
101
|
-
assert config.get("transport.
|
101
|
+
assert config.get("transport.chk_hostname") is True
|
102
102
|
|
103
103
|
print("✅ mTLS config: chk_hostname=True")
|
104
104
|
finally:
|
@@ -114,10 +114,7 @@ def test_chk_hostname_override():
|
|
114
114
|
# Add transport section if it doesn't exist
|
115
115
|
if "transport" not in https_config:
|
116
116
|
https_config["transport"] = {}
|
117
|
-
|
118
|
-
https_config["transport"]["ssl"] = {}
|
119
|
-
https_config["transport"]["ssl"]["chk_hostname"] = False
|
120
|
-
https_config["transport"]["ssl"]["_chk_hostname_user_set"] = True
|
117
|
+
https_config["transport"]["chk_hostname"] = False
|
121
118
|
|
122
119
|
# Save to temporary file and load with Config
|
123
120
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f:
|
@@ -130,7 +127,7 @@ def test_chk_hostname_override():
|
|
130
127
|
|
131
128
|
# Should respect the override
|
132
129
|
assert config.get("server.protocol") == "https"
|
133
|
-
assert config.get("transport.
|
130
|
+
assert config.get("transport.chk_hostname") is False
|
134
131
|
|
135
132
|
print("✅ HTTPS config with chk_hostname=False override works")
|
136
133
|
finally:
|
@@ -0,0 +1,269 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""
|
3
|
+
Complete framework testing with real MCP servers.
|
4
|
+
|
5
|
+
Author: Vasiliy Zdanovskiy
|
6
|
+
email: vasilyvz@gmail.com
|
7
|
+
"""
|
8
|
+
|
9
|
+
import asyncio
|
10
|
+
import json
|
11
|
+
import subprocess
|
12
|
+
import time
|
13
|
+
import requests
|
14
|
+
import ssl
|
15
|
+
from pathlib import Path
|
16
|
+
from typing import Dict, List, Optional, Tuple
|
17
|
+
import logging
|
18
|
+
|
19
|
+
# Configure logging
|
20
|
+
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
21
|
+
logger = logging.getLogger(__name__)
|
22
|
+
|
23
|
+
class FrameworkTester:
|
24
|
+
"""Complete framework testing with real MCP servers."""
|
25
|
+
|
26
|
+
def __init__(self):
|
27
|
+
self.project_root = Path(__file__).parent.parent.parent
|
28
|
+
self.configs_dir = self.project_root / "configs"
|
29
|
+
self.examples_dir = Path(__file__).parent
|
30
|
+
self.test_results = []
|
31
|
+
self.server_processes = []
|
32
|
+
|
33
|
+
async def test_all_protocols(self):
|
34
|
+
"""Test all protocols with real MCP server registration."""
|
35
|
+
logger.info("🧪 Starting Complete Framework Testing")
|
36
|
+
logger.info("=" * 60)
|
37
|
+
|
38
|
+
# Test configurations
|
39
|
+
test_configs = [
|
40
|
+
("http.json", "HTTP", 20000),
|
41
|
+
("https.json", "HTTPS", 20003),
|
42
|
+
("mtls.json", "mTLS", 20006)
|
43
|
+
]
|
44
|
+
|
45
|
+
for config_file, protocol, port in test_configs:
|
46
|
+
logger.info(f"\n🔧 Testing {protocol} (port {port})")
|
47
|
+
logger.info("-" * 40)
|
48
|
+
|
49
|
+
try:
|
50
|
+
# Start proxy adapter server
|
51
|
+
proxy_process = await self._start_proxy_server(config_file, port)
|
52
|
+
if not proxy_process:
|
53
|
+
continue
|
54
|
+
|
55
|
+
# Wait for server to start
|
56
|
+
await asyncio.sleep(2)
|
57
|
+
|
58
|
+
# Test server registration
|
59
|
+
await self._test_server_registration(protocol, port)
|
60
|
+
|
61
|
+
# Test MCP communication
|
62
|
+
await self._test_mcp_communication(protocol, port)
|
63
|
+
|
64
|
+
# Test security features
|
65
|
+
await self._test_security_features(protocol, port)
|
66
|
+
|
67
|
+
# Stop server
|
68
|
+
proxy_process.terminate()
|
69
|
+
await asyncio.sleep(1)
|
70
|
+
|
71
|
+
logger.info(f"✅ {protocol} testing completed successfully")
|
72
|
+
|
73
|
+
except Exception as e:
|
74
|
+
logger.error(f"❌ {protocol} testing failed: {e}")
|
75
|
+
self.test_results.append({
|
76
|
+
"protocol": protocol,
|
77
|
+
"status": "failed",
|
78
|
+
"error": str(e)
|
79
|
+
})
|
80
|
+
|
81
|
+
# Print summary
|
82
|
+
self._print_summary()
|
83
|
+
|
84
|
+
async def _start_proxy_server(self, config_file: str, port: int) -> Optional[subprocess.Popen]:
|
85
|
+
"""Start proxy adapter server."""
|
86
|
+
config_path = self.configs_dir / config_file
|
87
|
+
|
88
|
+
if not config_path.exists():
|
89
|
+
logger.error(f"❌ Config file not found: {config_path}")
|
90
|
+
return None
|
91
|
+
|
92
|
+
logger.info(f"🚀 Starting proxy server with {config_file}")
|
93
|
+
|
94
|
+
try:
|
95
|
+
# Start server in background
|
96
|
+
process = subprocess.Popen([
|
97
|
+
"python", str(self.examples_dir / "main.py"),
|
98
|
+
"--config", str(config_path)
|
99
|
+
], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
100
|
+
|
101
|
+
self.server_processes.append(process)
|
102
|
+
return process
|
103
|
+
|
104
|
+
except Exception as e:
|
105
|
+
logger.error(f"❌ Failed to start server: {e}")
|
106
|
+
return None
|
107
|
+
|
108
|
+
async def _test_server_registration(self, protocol: str, port: int):
|
109
|
+
"""Test MCP server registration."""
|
110
|
+
logger.info(f"📝 Testing server registration for {protocol}")
|
111
|
+
|
112
|
+
base_url = f"http://localhost:{port}" if protocol == "HTTP" else f"https://localhost:{port}"
|
113
|
+
|
114
|
+
# Test registration endpoint
|
115
|
+
registration_data = {
|
116
|
+
"server_id": "test-mcp-server",
|
117
|
+
"server_url": "stdio://test-server",
|
118
|
+
"server_name": "Test MCP Server",
|
119
|
+
"description": "Test server for framework validation"
|
120
|
+
}
|
121
|
+
|
122
|
+
try:
|
123
|
+
# Create SSL context for HTTPS/mTLS
|
124
|
+
ssl_context = None
|
125
|
+
if protocol in ["HTTPS", "mTLS"]:
|
126
|
+
ssl_context = ssl.create_default_context()
|
127
|
+
ssl_context.check_hostname = False
|
128
|
+
ssl_context.verify_mode = ssl.CERT_NONE
|
129
|
+
|
130
|
+
response = requests.post(
|
131
|
+
f"{base_url}/register",
|
132
|
+
json=registration_data,
|
133
|
+
verify=False,
|
134
|
+
timeout=10
|
135
|
+
)
|
136
|
+
|
137
|
+
if response.status_code == 200:
|
138
|
+
logger.info("✅ Server registration successful")
|
139
|
+
else:
|
140
|
+
logger.warning(f"⚠️ Registration returned status {response.status_code}")
|
141
|
+
|
142
|
+
except Exception as e:
|
143
|
+
logger.error(f"❌ Registration failed: {e}")
|
144
|
+
raise
|
145
|
+
|
146
|
+
async def _test_mcp_communication(self, protocol: str, port: int):
|
147
|
+
"""Test MCP communication through proxy."""
|
148
|
+
logger.info(f"🔗 Testing MCP communication for {protocol}")
|
149
|
+
|
150
|
+
base_url = f"http://localhost:{port}" if protocol == "HTTP" else f"https://localhost:{port}"
|
151
|
+
|
152
|
+
# Test MCP JSON-RPC call
|
153
|
+
mcp_request = {
|
154
|
+
"jsonrpc": "2.0",
|
155
|
+
"id": 1,
|
156
|
+
"method": "tools/list",
|
157
|
+
"params": {}
|
158
|
+
}
|
159
|
+
|
160
|
+
try:
|
161
|
+
ssl_context = None
|
162
|
+
if protocol in ["HTTPS", "mTLS"]:
|
163
|
+
ssl_context = ssl.create_default_context()
|
164
|
+
ssl_context.check_hostname = False
|
165
|
+
ssl_context.verify_mode = ssl.CERT_NONE
|
166
|
+
|
167
|
+
response = requests.post(
|
168
|
+
f"{base_url}/mcp",
|
169
|
+
json=mcp_request,
|
170
|
+
headers={"Content-Type": "application/json"},
|
171
|
+
verify=False,
|
172
|
+
timeout=10
|
173
|
+
)
|
174
|
+
|
175
|
+
if response.status_code == 200:
|
176
|
+
result = response.json()
|
177
|
+
if "result" in result:
|
178
|
+
logger.info("✅ MCP communication successful")
|
179
|
+
else:
|
180
|
+
logger.warning(f"⚠️ MCP response: {result}")
|
181
|
+
else:
|
182
|
+
logger.warning(f"⚠️ MCP call returned status {response.status_code}")
|
183
|
+
|
184
|
+
except Exception as e:
|
185
|
+
logger.error(f"❌ MCP communication failed: {e}")
|
186
|
+
raise
|
187
|
+
|
188
|
+
async def _test_security_features(self, protocol: str, port: int):
|
189
|
+
"""Test security features."""
|
190
|
+
logger.info(f"🔒 Testing security features for {protocol}")
|
191
|
+
|
192
|
+
base_url = f"http://localhost:{port}" if protocol == "HTTP" else f"https://localhost:{port}"
|
193
|
+
|
194
|
+
# Test without authentication
|
195
|
+
try:
|
196
|
+
ssl_context = None
|
197
|
+
if protocol in ["HTTPS", "mTLS"]:
|
198
|
+
ssl_context = ssl.create_default_context()
|
199
|
+
ssl_context.check_hostname = False
|
200
|
+
ssl_context.verify_mode = ssl.CERT_NONE
|
201
|
+
|
202
|
+
response = requests.get(
|
203
|
+
f"{base_url}/health",
|
204
|
+
verify=False,
|
205
|
+
timeout=10
|
206
|
+
)
|
207
|
+
|
208
|
+
if response.status_code == 200:
|
209
|
+
logger.info("✅ Health check successful")
|
210
|
+
else:
|
211
|
+
logger.warning(f"⚠️ Health check returned status {response.status_code}")
|
212
|
+
|
213
|
+
except Exception as e:
|
214
|
+
logger.error(f"❌ Security test failed: {e}")
|
215
|
+
raise
|
216
|
+
|
217
|
+
def _print_summary(self):
|
218
|
+
"""Print test summary."""
|
219
|
+
logger.info("\n" + "=" * 60)
|
220
|
+
logger.info("📊 FRAMEWORK TESTING SUMMARY")
|
221
|
+
logger.info("=" * 60)
|
222
|
+
|
223
|
+
total_tests = len(self.test_results)
|
224
|
+
successful_tests = len([r for r in self.test_results if r["status"] == "success"])
|
225
|
+
|
226
|
+
logger.info(f"Total tests: {total_tests}")
|
227
|
+
logger.info(f"Successful: {successful_tests}")
|
228
|
+
logger.info(f"Failed: {total_tests - successful_tests}")
|
229
|
+
|
230
|
+
if total_tests > 0:
|
231
|
+
success_rate = (successful_tests / total_tests) * 100
|
232
|
+
logger.info(f"Success rate: {success_rate:.1f}%")
|
233
|
+
|
234
|
+
if success_rate == 100:
|
235
|
+
logger.info("🎉 All tests passed! Framework is working correctly.")
|
236
|
+
elif success_rate >= 80:
|
237
|
+
logger.info("✅ Most tests passed. Framework is mostly functional.")
|
238
|
+
else:
|
239
|
+
logger.info("⚠️ Many tests failed. Framework needs attention.")
|
240
|
+
|
241
|
+
logger.info("=" * 60)
|
242
|
+
|
243
|
+
async def cleanup(self):
|
244
|
+
"""Cleanup server processes."""
|
245
|
+
logger.info("🧹 Cleaning up server processes...")
|
246
|
+
|
247
|
+
for process in self.server_processes:
|
248
|
+
try:
|
249
|
+
if process.poll() is None: # Process is still running
|
250
|
+
process.terminate()
|
251
|
+
process.wait(timeout=5)
|
252
|
+
except subprocess.TimeoutExpired:
|
253
|
+
process.kill()
|
254
|
+
except Exception as e:
|
255
|
+
logger.warning(f"Warning: Failed to cleanup process: {e}")
|
256
|
+
|
257
|
+
self.server_processes.clear()
|
258
|
+
|
259
|
+
async def main():
|
260
|
+
"""Main testing function."""
|
261
|
+
tester = FrameworkTester()
|
262
|
+
|
263
|
+
try:
|
264
|
+
await tester.test_all_protocols()
|
265
|
+
finally:
|
266
|
+
await tester.cleanup()
|
267
|
+
|
268
|
+
if __name__ == "__main__":
|
269
|
+
asyncio.run(main())
|