Contact Us 1-800-596-4880

Reading and Writing Request Headers and Bodies with Stop Iteration

Use the Omni Gateway Policy Development Kit (PDK) enable_stop_iteration feature to simultaneously read and modify headers and body content.

PDK Policies using stop iteration only supports payload bodies of up to 1MB.

Only Omni Gateway version 1.12.0 or later support stop interation.

Enable Stop Iteration in your Cargo.toml

To enable this feature, add enable_stop_iteration to your Cargo.toml file dependencies:

[dependencies]
pdk = { version = "1.8.0", features = ["enable_stop_iteration"] }

Read and Write Request Headers

After enabling the feature, use into_headers_body_state() to transition from the initial request or response state to the combined headers-body state:

use pdk::hl::*;

async fn request_filter(request_state: RequestState) -> Flow<()> {
   // Transition to headers-body state
   let state = request_state.into_headers_body_state().await;

   // Access both headers and body through the unified handler
   state.handler().set_header("x-custom-header", "value");

   if state.contains_body() {
       let _ = state.handler().set_body("modified body".as_bytes());
   }

   Flow::Continue(())
}

The into_headers_body_state() method returns a RequestHeadersBodyState for request flows or ResponseHeadersBodyState for response flows. Both states provide a unified handler() that implements both HeadersHandler and BodyHandler traits:

pub trait Handler {
    fn headers(&self) -> Vec<(String, String)>;
    fn header(&self, name: &str) -> Option<String>;
    fn add_header(&self, name: &str, value: &str);
    fn set_header(&self, name: &str, value: &str);
    fn set_headers(&self, headers: Vec<(&str, &str)>);
    fn remove_header(&self, name: &str);
    fn body(&self) -> Vec<u8>;
    fn set_body(&self, body: &[u8]) -> Result<(), BodyError>;
    fr contains_body(&self) -> Bool;
}

Handle Requests Without Body

When a request or response doesn’t contain a body, the headers-body state handler gracefully handles the absence:

async fn request_filter(request_state: RequestState) -> Flow<()> {
   let state = request_state.into_headers_body_state().await;

   // Check if body exists
   if state.contains_body() {
       let body = state.handler().body();
       // Process body
   }

   // Attempting to set body on a request without body returns an error
   if let Err(BodyError::BodyNotSent) = state.handler().set_body("data".as_bytes()) {
       // Handle case where body cannot be set (e.g., GET request)
       state.handler().set_header("x-data", "data");
   }

   Flow::Continue(())
}

Stop Iteration Configuration Examples

PDK provides the Stop Iteration Example policy to demonstrate how to use the headers-body unified state in Rust code.

Within the example policy, see these code sections for additional configuration details: