# Functions on a firewall

A general-purpose example for functions that run on the firewall, combining several request-handling actions in one handler. Use it as a starting point when you need to inspect incoming headers and metadata and then decide whether to block, drop, modify, or answer a request directly on Azion's global network. The sample code exemplifies the following capabilities:

- `event.deny()`
- `event.drop()`
- `event.addRequestHeader()`
- `event.addResponseHeader()`
- `event.respondWith()`
- `event.continue()`

```js
    async function firewallHandler(event) {
        // Access the value of x-deny, one of the headers
        let condition = event.request.headers.get("x-deny");
    
        if (condition) {
            // event.deny() triggers a default 403 Response
            event.deny();
        }
    
        let anotherCondition = event.request.headers.get("x-drop"); // Access the value of x-drop, , one of the headers
        if (anotherCondition) {
            // event.drop() drops the connection without returning a Response
            event.drop();
        }
    
        // Access the value of x-third, one of the headers
        let aThirdCondition = event.request.headers.get("x-third");
        if (aThirdCondition) {
            // event.addRequestHeader() adds a new header to the Request object, passing key:"value".
            event.addRequestHeader("X-New-Request-Header", "Hello");
        }
    
        // Access the value of x-fourth, one of the headers
        let aFourthCondition = event.request.headers.get("x-fourth");
        if (aFourthCondition) {
            //  event.addResponseHeader() adds a new header to the Response object
            //  that will be delivered after accessing the origin. 
            event.addResponseHeader("X-New-Response-Header", "Bye");
        }
    
        // The metadata object contains the attributes of the request
        if (event.request.metadata["remote_addr"] == "127.0.0.1") {
            // event.respondWith(new Response()) allows you to serve your own Response
            event.respondWith(new Response('{"my_custom_response": true}', {
                status: 599,
                headers: { "content-type": "application/json" }
            }));
        }
    
        // If the request was not denied or dropped and did not have a Response returned,
        // it is necessary to continue the processing, and to do so use use -> event.continue()
        // Do not forget this command, otherwise the request won't continue!
        event.continue();
    }

    addEventListener("firewall", (event) => event.waitUntil(firewallHandler(event)));
```

## How it works

This code runs as a `firewall` handler, so it executes in a firewall and not in the application request path. It registers the handler with `addEventListener("firewall", ...)` and runs the asynchronous work inside `event.waitUntil()`. Refer to [Functions for Firewall](/en/documentation/platform/firewall/functions/) for the full set of actions a firewall handler can call.

The handler reads several request headers with `event.request.headers.get()` to drive its decisions. Depending on which header is present, it can call `event.deny()` to return a 403, `event.drop()` to close the connection without a response, or `event.addRequestHeader()` and `event.addResponseHeader()` to inject custom headers. It also inspects `event.request.metadata["remote_addr"]` and can short-circuit with `event.respondWith(new Response(...))` to serve a custom JSON body. It ends with `event.continue()`, so any request not already handled proceeds normally.

## Related resources

- [JavaScript examples](/en/documentation/platform/functions/javascript-examples.md): Browse the other syntax patterns in the collection.
- [Functions for Firewall](/en/documentation/platform/firewall/functions.md): Read the reference for every action a firewall handler can call.
- [Metadata API](/en/documentation/devtools/runtime/api-reference/metadata.md): Look up the request metadata fields, including `remote_addr`.
- [Functions Instances for Firewall](/en/documentation/platform/firewall/functions-instances.md): See how a function is instantiated on a firewall and triggered by a rule.
- [Limits for functions on a firewall](/en/documentation/platform/functions/limits.md#limits-for-functions-on-a-firewall): The limits a firewall function shares with every function, and where the bounds of the firewall itself are listed.
