Contact Us 1-800-596-4880

JavaScript Scripting Policy

Policy name

JavaScript Scripting

Summary

Runs a user-supplied JavaScript module to inspect and modify requests and responses

Category

Transformation

First Omni Gateway version available

1.14.0

Release Notes

JavaScript Scripting Policy

Returned Status Codes

500 - The script threw an error while processing the request or response

Summary

The JavaScript Scripting policy runs a JavaScript module that you supply to inspect and modify HTTP traffic as it passes through the gateway. Use the policy to add or change headers, transform request or response bodies, and block a request with an early response.

The module runs as a standard JavaScript ES module and can export either or both of these functions:

  • requestFilter(request) runs for every incoming request. It can read and modify the request, allow the request to continue to the upstream service, or terminate the request with an immediate response.

  • responseFilter(response, requestData) runs for every upstream response. It can read and modify the response before the gateway returns it to the client.

The module must export at least one of these functions to properly load.

Module-level variables persist across invocations to share state between requests (for example, to maintain a counter). The runtime provides the standard console, TextEncoder, and TextDecoder globals. The script runs synchronously; async functions and promises returned from a filter aren’t awaited.

Configure Policy Parameters

Omni Gateway Local Mode

- policyRef:
    name: javascript-scripting-flex
  config:
    script: <string>   // REQUIRED - JavaScript ES module source
Parameter Required Default Value Description

script

Required

The full source text of a JavaScript ES module. The module must export at least one of requestFilter or responseFilter.

Managed Omni Gateway and Omni Gateway Connected Mode

When you apply the policy from the UI, the following parameters are displayed:

Parameter Description

Policy type

JavaScript Scripting

Script

The JavaScript ES module that exports requestFilter and/or responseFilter

Script API

The gateway calls the exported functions and passes objects that represent the request or response. These objects can’t be constructed from JavaScript.

Filter Functions

Function Description

requestFilter(request)

Called for each incoming request. Receives a request object. Returns a flow result that controls whether the request continues to the upstream service or is stopped with an early response. Returning undefined continues the request.

responseFilter(response, requestData)

Called for each upstream response. Receives a response object and the requestData value carried from requestFilter. The return value is ignored.

Request and Response Objects

Both the request and response objects expose the same methods to read and modify headers and the body:

Method Description

getHeaders()

Returns all headers as an array of [name, value] pairs.

setHeaders(headers)

Replaces all headers with the provided array of [name, value] pairs.

getHeader(name)

Returns the value of the first header matching name (case-insensitive), or undefined if absent.

setHeader(name, value)

Sets a header, replacing any existing values for that name.

addHeader(name, value)

Appends a header, preserving any existing values for that name.

removeHeader(name)

Removes all headers matching name.

getBody()

Returns the body as a Uint8Array.

setBody(body)

Replaces the body with the provided Uint8Array. Throws an error if the entity has no body or if the body exceeds the 1 MiB maximum.

getBodyString()

Returns the body decoded as a UTF-8 string. Invalid byte sequences are replaced with the Unicode replacement character (U+FFFD).

setBodyString(body)

Replaces the body with the UTF-8 encoding of the provided string. Throws an error if the entity has no body or if the encoded body exceeds the 1 MiB maximum.

containsBody()

Returns true if the entity has a body, or false otherwise. Use this to check whether body operations are safe before you call them.

Controlling Request Flow

The value that requestFilter returns controls whether the request continues:

  • Return undefined or { flow: "continue" } to allow the request to continue to the upstream service.

  • Return { flow: "continue", data: <value> } to continue and pass data to responseFilter. The requestData argument of responseFilter receives { flow: "continue", data: <value> }.

  • Return { flow: "break", response: { statusCode, headers, body } } to stop the request and send an immediate response to the client. The upstream service is not called. headers is an array of [name, value] pairs, and body is optional and can be a Uint8Array or a string.

If requestFilter returns an unexpected value, the gateway logs a warning and treats it as continue.

Error Handling

If a filter function throws an error, the gateway stops processing and returns a 500 response with the JSON body {"error":"Internal error"} to the client. The error is written to the gateway logs.

Logging

Calls to the console methods are written to the gateway logs at the corresponding level:

Console method Gateway log level

console.debug()

debug

console.log(), console.info()

info

console.warn()

warn

console.error()

error

Examples

Add and Remove Headers

This example adds a header to the request and the response, and removes a header from each:

- policyRef:
    name: javascript-scripting-flex
  config:
    script: |
      export function requestFilter(request) {
        request.setHeader("x-processed-by", "javascript-policy");
        request.removeHeader("x-internal");
      }

      export function responseFilter(response) {
        response.setHeader("x-served-by", "omni-gateway");
        response.removeHeader("server");
      }

Block a Request with an Early Response

This example rejects a request that is missing an API key and returns a 401 response without calling the upstream service:

- policyRef:
    name: javascript-scripting-flex
  config:
    script: |
      export function requestFilter(request) {
        if (!request.getHeader("x-api-key")) {
          return {
            flow: "break",
            response: {
              statusCode: 401,
              headers: [["content-type", "text/plain"]],
              body: "Missing API key",
            },
          };
        }
      }

Pass Data from the Request to the Response

This example reads a value during the request phase and uses it during the response phase:

- policyRef:
    name: javascript-scripting-flex
  config:
    script: |
      export function requestFilter(request) {
        const id = request.getHeader("x-request-id") || "unknown";
        return { flow: "continue", data: { id } };
      }

      export function responseFilter(response, requestData) {
        if (requestData.flow === "continue" && requestData.data) {
          response.setHeader("x-request-id", requestData.data.id);
        }
      }

Transform the Response Body

This example replaces the response body with a new string:

- policyRef:
    name: javascript-scripting-flex
  config:
    script: |
      export function responseFilter(response) {
        if (response.containsBody()) {
          response.setBodyString('{"message":"transformed by gateway"}');
          response.setHeader("content-type", "application/json");
        }
      }