# JavaScript Examples - Functions on 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

The handler runs on the `firewall` event inside `event.waitUntil()` and 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 can also short-circuit with `event.respondWith(new Response(...))` to serve a custom JSON body, and it ends with `event.continue()` so that any request not already handled proceeds normally.

## Related resources

- [JavaScript examples](/en/documentation/devtools/javascript-examples/)
- [Runtime APIs](/en/documentation/products/applications/functions/runtime-apis/javascript/fetch-event/)