Proxy Events

Tags: events

The proxy application dispatches event arount the lifecycle of transactions and their associated messages (incoming requests, outgoing responses, etc.).

Transaction Events

The HttpProxyController is responsible for implementing the actual proxy logic. It translates incoming requests into outgoing requests to remote services, and incoming responses into outgoing responses to the caller (which, in fine, will be the user’s http client).

This process is called a Transaction in HARP Proxy, and the controller provides events to interract with its lifecycle.

⚡️ EVENT_TRANSACTION_STARTED

Dispatched as a EVENT_TRANSACTION_STARTED event when a transaction object is created, with a TransactionEvent instance.

Example

Here is an example of a listener coroutine for the EVENT_TRANSACTION_STARTED event:

from whistle import AsyncEventDispatcher

from harp_apps.proxy.events import EVENT_TRANSACTION_STARTED, TransactionEvent


async def on_transaction_started(event: TransactionEvent):
    print(f"Transaction started: {event}")


if __name__ == "__main__":
    # for example completeness only, you should use the system dispatcher
    dispatcher = AsyncEventDispatcher()
    dispatcher.add_listener(EVENT_TRANSACTION_STARTED, on_transaction_started)

⚡️ EVENT_TRANSACTION_MESSAGE

Dispatched as a EVENT_TRANSACTION_MESSAGE event when a message is sent to a transaction (either request or response), with a HttpMessageEvent instance.

Example

Here is an example of a listener coroutine for the EVENT_TRANSACTION_MESSAGE event:

from whistle import AsyncEventDispatcher

from harp_apps.proxy.events import EVENT_TRANSACTION_MESSAGE, HttpMessageEvent


async def on_transaction_message(event: HttpMessageEvent):
    print(f"Transaction message: {event}")


if __name__ == "__main__":
    # for example completeness only, you should use the system dispatcher
    dispatcher = AsyncEventDispatcher()
    dispatcher.add_listener(EVENT_TRANSACTION_MESSAGE, on_transaction_message)

⚡️ EVENT_TRANSACTION_ENDED

Dispatched as a EVENT_TRANSACTION_ENDED event, with a TransactionEvent instance, when a transaction is finished.

Example

Here is an example of a listener coroutine for the EVENT_TRANSACTION_ENDED event:

from whistle import AsyncEventDispatcher

from harp_apps.proxy.events import EVENT_TRANSACTION_ENDED, TransactionEvent


async def on_transaction_ended(event: TransactionEvent):
    print(f"Transaction ended: {event}")


if __name__ == "__main__":
    # for example completeness only, you should use the system dispatcher
    dispatcher = AsyncEventDispatcher()
    dispatcher.add_listener(EVENT_TRANSACTION_ENDED, on_transaction_ended)

Filtering Events

To implement filtering logic (for rules, or your custom needs), a few events are here to let you filter the incoming requests and their associated responses. You can even forge your own responses (maybe conditionnaly) to bypass the proxying logic whenever needed.

⚡️ EVENT_FILTER_PROXY_REQUEST

Dispatched when an incoming request is ready to be filtered, for example by the rules application.

Dispatched as a EVENT_FILTER_PROXY_REQUEST event, with a ProxyFilterEvent instance.

If a response is set on the event instance, then the actual incoming request will be bypassed and the forged response will be returned.

Example

Here is an example of a listener coroutine for the EVENT_FILTER_PROXY_REQUEST event:

from whistle import AsyncEventDispatcher

from harp_apps.proxy.events import EVENT_FILTER_PROXY_REQUEST, ProxyFilterEvent


async def on_filter_request(event: ProxyFilterEvent):
    print(f"Filtering request: {event}")


if __name__ == "__main__":
    # for example completeness only, you should use the system dispatcher
    dispatcher = AsyncEventDispatcher()
    dispatcher.add_listener(EVENT_FILTER_PROXY_REQUEST, on_filter_request)

⚡️ EVENT_FILTER_PROXY_RESPONSE

Dispatched when an outgoing response is ready to be filtered, for example by the rules application.

Dispatched as a EVENT_FILTER_PROXY_RESPONSE event, with the same ProxyFilterEvent instance as the previous event, with the response set.

You can change the response instance on the event to modify the response that will be returned to the caller.

Example

Here is an example of a listener coroutine for the EVENT_FILTER_PROXY_RESPONSE event:

from whistle import AsyncEventDispatcher

from harp_apps.proxy.events import EVENT_FILTER_PROXY_RESPONSE, ProxyFilterEvent


async def on_filter_response(event: ProxyFilterEvent):
    print(f"Filtering response: {event}")


if __name__ == "__main__":
    # for example completeness only, you should use the system dispatcher
    dispatcher = AsyncEventDispatcher()
    dispatcher.add_listener(EVENT_FILTER_PROXY_RESPONSE, on_filter_response)

Gotchas

All incoming proxy requests will go through this event. If you’re looking to filter outgoing HTTP requests, have a look at HTTP Client Events.

Please note that the same event instance will be used for both events. It means that if you stop propagation of the event, all further filtering will be skipped, for both events.