|
40 | 40 | Config, |
41 | 41 | GlobalContext, |
42 | 42 | HookType, |
| 43 | + HttpHeaderPayload, |
| 44 | + HttpHeaderPayloadResult, |
43 | 45 | PluginCondition, |
44 | 46 | PluginContext, |
45 | 47 | PluginContextTable, |
@@ -421,6 +423,54 @@ async def post_resource_fetch(plugin: PluginRef, payload: ResourcePostFetchPaylo |
421 | 423 | return await plugin.plugin.resource_post_fetch(payload, context) |
422 | 424 |
|
423 | 425 |
|
| 426 | +async def pre_http_forwarding_call(plugin: PluginRef, payload: HttpHeaderPayload, context: PluginContext) -> HttpHeaderPayloadResult: |
| 427 | + """Call plugin's HTTP pre-forwarding call hook. |
| 428 | +
|
| 429 | + Args: |
| 430 | + plugin: The plugin to execute. |
| 431 | + payload: The set of HTTP headers to be analyzed. |
| 432 | + context: The plugin context. |
| 433 | +
|
| 434 | + Returns: |
| 435 | + Modified HTTP headers with processing status. |
| 436 | +
|
| 437 | + Examples: |
| 438 | + >>> from mcpgateway.plugins.framework.base import PluginRef |
| 439 | + >>> from mcpgateway.plugins.framework import Plugin, HttpHeaderPayload, PluginContext, GlobalContext |
| 440 | + >>> # Assuming you have a plugin instance: |
| 441 | + >>> # plugin_ref = PluginRef(my_plugin) |
| 442 | + >>> payload = HttpHeaderPayload({"Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="}) |
| 443 | + >>> context = PluginContext(request_id="123") |
| 444 | + >>> # In async context: |
| 445 | + >>> # result = await pre_http_forwarding_call(plugin_ref, payload, context) |
| 446 | + """ |
| 447 | + return await plugin.plugin.http_pre_forwarding_call(payload, context) |
| 448 | + |
| 449 | + |
| 450 | +async def post_http_forwarding_call(plugin: PluginRef, payload: HttpHeaderPayload, context: PluginContext) -> HttpHeaderPayloadResult: |
| 451 | + """Call plugin's HTTP post-forwarding call hook. |
| 452 | +
|
| 453 | + Args: |
| 454 | + plugin: The plugin to execute. |
| 455 | + payload: The set of HTTP headers to be analyzed. |
| 456 | + context: The plugin context. |
| 457 | +
|
| 458 | + Returns: |
| 459 | + Modified HTTP headers with processing status. |
| 460 | +
|
| 461 | + Examples: |
| 462 | + >>> from mcpgateway.plugins.framework.base import PluginRef |
| 463 | + >>> from mcpgateway.plugins.framework import Plugin, HttpHeaderPayload, PluginContext, GlobalContext |
| 464 | + >>> # Assuming you have a plugin instance: |
| 465 | + >>> # plugin_ref = PluginRef(my_plugin) |
| 466 | + >>> payload = HttpHeaderPayload({"Authorization": "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="}) |
| 467 | + >>> context = PluginContext(request_id="123") |
| 468 | + >>> # In async context: |
| 469 | + >>> # result = await post_http_forwarding_call(plugin_ref, payload, context) |
| 470 | + """ |
| 471 | + return await plugin.plugin.http_post_forwarding_call(payload, context) |
| 472 | + |
| 473 | + |
424 | 474 | class PluginManager: |
425 | 475 | """Plugin manager for managing the plugin lifecycle. |
426 | 476 |
|
@@ -465,6 +515,7 @@ class PluginManager: |
465 | 515 | _post_tool_executor: PluginExecutor[ToolPostInvokePayload] = PluginExecutor[ToolPostInvokePayload]() |
466 | 516 | _resource_pre_executor: PluginExecutor[ResourcePreFetchPayload] = PluginExecutor[ResourcePreFetchPayload]() |
467 | 517 | _resource_post_executor: PluginExecutor[ResourcePostFetchPayload] = PluginExecutor[ResourcePostFetchPayload]() |
| 518 | + _http_executor: PluginExecutor[HttpHeaderPayload] = PluginExecutor[HttpHeaderPayload]() |
468 | 519 |
|
469 | 520 | # Context cleanup tracking |
470 | 521 | _context_store: Dict[str, Tuple[PluginContextTable, float]] = {} |
@@ -946,3 +997,69 @@ async def resource_post_fetch( |
946 | 997 | del self._context_store[global_context.request_id] |
947 | 998 |
|
948 | 999 | return result |
| 1000 | + |
| 1001 | + async def http_pre_forwarding_call( |
| 1002 | + self, payload: HttpHeaderPayload, global_context: GlobalContext, local_contexts: Optional[PluginContextTable] = None |
| 1003 | + ) -> tuple[HttpHeaderPayloadResult, PluginContextTable | None]: |
| 1004 | + """Execute pre-fetch hooks before an operation is called. |
| 1005 | +
|
| 1006 | + Args: |
| 1007 | + payload: The http payload containing http headers passed from requests to responses. |
| 1008 | + global_context: Shared context for all plugins with request metadata. |
| 1009 | + local_contexts: Optional existing contexts from previous hook executions. |
| 1010 | +
|
| 1011 | + Returns: |
| 1012 | + A tuple containing: |
| 1013 | + - HttpHeaderPayloadResult with processing status and modified headers |
| 1014 | + - PluginContextTable with plugin contexts for state management |
| 1015 | + """ |
| 1016 | + # Get plugins configured for this hook |
| 1017 | + plugins = self._registry.get_plugins_for_hook(HookType.HTTP_PRE_FORWARDING_CALL) |
| 1018 | + |
| 1019 | + def compare(payload: HttpHeaderPayload, conditions: list[PluginCondition], context: GlobalContext): |
| 1020 | + return True |
| 1021 | + |
| 1022 | + # Execute plugins |
| 1023 | + result = await self._http_executor.execute(plugins, payload, global_context, pre_http_forwarding_call, compare, local_contexts) |
| 1024 | + |
| 1025 | + # Store context for potential post-fetch |
| 1026 | + if result[1]: |
| 1027 | + self._context_store[global_context.request_id] = (result[1], time.time()) |
| 1028 | + |
| 1029 | + # Periodic cleanup |
| 1030 | + await self._cleanup_old_contexts() |
| 1031 | + |
| 1032 | + return result |
| 1033 | + |
| 1034 | + async def http_post_forwarding_call( |
| 1035 | + self, payload: HttpHeaderPayload, global_context: GlobalContext, local_contexts: Optional[PluginContextTable] = None |
| 1036 | + ) -> tuple[HttpHeaderPayloadResult, PluginContextTable | None]: |
| 1037 | + """Execute post-fetch hooks after an operation is complete. |
| 1038 | +
|
| 1039 | + Args: |
| 1040 | + payload: The http payload containing http headers passed from requests to responses. |
| 1041 | + global_context: Shared context for all plugins with request metadata. |
| 1042 | + local_contexts: Optional existing contexts from previous hook executions. |
| 1043 | +
|
| 1044 | + Returns: |
| 1045 | + A tuple containing: |
| 1046 | + - HttpHeaderPayloadResult with processing status and modified headers |
| 1047 | + - PluginContextTable with plugin contexts for state management |
| 1048 | + """ |
| 1049 | + # Get plugins configured for this hook |
| 1050 | + plugins = self._registry.get_plugins_for_hook(HookType.HTTP_POST_FORWARDING_CALL) |
| 1051 | + |
| 1052 | + def compare(payload: HttpHeaderPayload, conditions: list[PluginCondition], context: GlobalContext): |
| 1053 | + return True |
| 1054 | + |
| 1055 | + # Execute plugins |
| 1056 | + result = await self._http_executor.execute(plugins, payload, global_context, post_http_forwarding_call, compare, local_contexts) |
| 1057 | + |
| 1058 | + # Store context for potential post-fetch |
| 1059 | + if result[1]: |
| 1060 | + self._context_store[global_context.request_id] = (result[1], time.time()) |
| 1061 | + |
| 1062 | + # Periodic cleanup |
| 1063 | + await self._cleanup_old_contexts() |
| 1064 | + |
| 1065 | + return result |
0 commit comments