Contact Us 1-800-596-4880

Reading and Writing Request Headers and Bodies with Stop Iteration

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

PDK Policies using stop iteration on support payload bodies of 1 MB.

Only Flex 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: