---
schema_version: "1"
id: 0e9e795f72ffd2f9fd1438096378b64fb31c58c45c7b9671c6b5efa3d8ef8f5d
title: Using CORS Library Functions
collection: mulesoft
version: current
locale: en-us
portal_url: https://docs.salesforce.com/mulesoft/current/en-us/pdk/1.5/policies-pdk-configure-features-cors.md
canonical_url: https://docs.mulesoft.com/pdk/1.5/policies-pdk-configure-features-cors
source_site: docs.mulesoft.com
content_type: documentation
content_hash: 4922a8a52595bd66d4a27f3747ccd14389d44aed95d8cc94e1c76a06eb934762
description: MuleSoft Documentation Site
release: "1.5"
latest: false
---
---
product: Omni Gateway Policy Development Kit (PDK)
version: 1.5
---

# Using CORS Library Functions

> For the full documentation index, see: https://docs.mulesoft.com/llms.txt

> [!NOTE] To view an example policy project that uses Flex Gateway Policy Development Kit (PDK)'s
> Cross-origin resource sharing (CORS) library, see
> [CORS Validation Policy Example](https://github.com/mulesoft/pdk-custom-policy-examples/blob/1.5.0/cors-validation/README.md).

CORS is a mechanism for web applications to access resources defined in another domain. Browsers
support CORS by default. The PDK CORS library complies with the
[CORS W3C recommendation](https://fetch.spec.whatwg.org/) standards and provides a set of tools to
validate incoming requests and protect resources.

## Define a CORS Configuration Instance

The CORS library is available from the `pdk::cors` module. The module provides the
`cors::Configuration`, `cors::OriginGroup`, and `cors::AllowedMethod` structs and their builders to
define how to validate incoming requests. For example, the following code snippet defines a function
that hardcodes the `cors::Configuration` instance:

```Rust
use pdk::cors;

fn create_cors_configuration() -> cors:Configuration {
    cors::Configuration::builder()
        .public_resource(false)
        .support_credentials(true)
        .origin_groups(vec![cors::OriginGroup::builder()
            .origin_group_name("default group".to_string())
            .plain_origins(vec!["http://www.the-origin-of-time.com".to_string()])
            .access_control_max_age(60)
            .headers(vec![
                "x-allow-origin".to_string(),
                "x-yet-another-valid-header".to_string(),
            ])
            .exposed_headers(vec!["x-forwarded-for".to_string()])
            .allowed_methods(vec![
                cors::AllowedMethod::builder()
                    .method_name("POST".to_string())
                    .allowed(true)
                    .build()
                    .unwrap(),
                cors::AllowedMethod::builder()
                    .method_name("PUT".to_string())
                    .allowed(true)
                    .build()
                    .unwrap(),
            ])
            .build()
            .unwrap()])
        .build()
        .unwrap();
}
```

### cors::Configuration Struct Configuration Parameters

<table><colgroup><col> <col> <col> <col></colgroup><thead><tr><th>Property</th><th>Required or Optional</th><th>Default Value</th><th>Description</th></tr></thead><tbody><tr><td><div><div><p><code>origin_groups</code></p></div></div></td><td><div><div><p>Optional</p></div></div></td><td><div><div><p>Empty <code>Vec</code></p></div></div></td><td><div><div><p><code>Vec</code> containing groups of origins configurable with <code>cors::OriginGroup</code>.</p></div></div></td></tr><tr><td><div><div><p><code>public_resource</code></p></div></div></td><td><div><div><p>Optional</p></div></div></td><td><div><div><p><code>false</code></p></div></div></td><td><div><div><p>A boolean indicating if the CORS configuration is applied as a public resource.</p></div></div></td></tr><tr><td><div><div><p><code>support_credentials</code></p></div></div></td><td><div><div><p>Optional</p></div></div></td><td><div><div><p><code>false</code></p></div></div></td><td><div><div><p>A boolean indicating if the CORS configuration supports credentials, such as cookies, authorization headers, and TLS client certificates.</p></div></div></td></tr></tbody></table>

### cors::OriginGroup Struct Configuration Parameters

<table><colgroup><col> <col> <col> <col></colgroup><thead><tr><th>Property</th><th>Required or Optional</th><th>Default Value</th><th>Description</th></tr></thead><tbody><tr><td><div><div><p><code>plain_origins</code></p></div></div></td><td><div><div><p>Optional</p></div></div></td><td><div><div><p>Empty <code>Vec</code></p></div></div></td><td><div><div><p><code>Vec</code> of origins included in the group. For example, <code>http://www.the-origin-of-time.com</code>.</p></div></div></td></tr><tr><td><div><div><p><code>access_control_max_age</code></p></div></div></td><td><div><div><p>Optional</p></div></div></td><td><div><div><p>30</p></div></div></td><td><div><div><p>Duration in seconds to cache a preflight response before sending another preflight request.</p></div></div></td></tr><tr><td><div><div><p><code>allowed_methods</code></p></div></div></td><td><div><div><p>Optional</p></div></div></td><td><div><div><p>Empty <code>Vec</code></p></div></div></td><td><div><div><p><code>Vec</code> of allowed HTTP methods configurable with <code>cors::AllowedMethod</code>.</p></div></div></td></tr><tr><td><div><div><p><code>headers</code></p></div></div></td><td><div><div><p>Optional</p></div></div></td><td><div><div><p>Empty <code>Vec</code></p></div></div></td><td><div><div><p><code>Vec</code> of HTTP headers for preflight requests.</p></div></div></td></tr><tr><td><div><div><p><code>exposed_headers</code></p></div></div></td><td><div><div><p>Optional</p></div></div></td><td><div><div><p>Empty <code>Vec</code></p></div></div></td><td><div><div><p><code>Vec</code> of headers that browser JavaScript can access.</p></div></div></td></tr></tbody></table>

### cors::AllowedMethod Struct Configuration Parameters

<table><colgroup><col> <col> <col></colgroup><thead><tr><th>Property</th><th>Required or Optional</th><th>Description</th></tr></thead><tbody><tr><td><div><div><p><code>method_name</code></p></div></div></td><td><div><div><p>Required</p></div></div></td><td><div><div><p>Method name.</p></div></div></td></tr><tr><td><div><div><p><code>is_allowed</code></p></div></div></td><td><div><div><p>Required</p></div></div></td><td><div><div><p>A boolean indicating if a method is allowed. Supported values are <code>CONNECT</code>, <code>DELETE</code>, <code>GET</code>, <code>OPTIONS</code>, <code>PATCH</code>, <code>POST</code>, <code>PUT</code>, or <code>TRACE</code>.</p></div></div></td></tr></tbody></table>

## CORS Validation Methods

The `cors::Cors` struct contains the `check_headers()` method to validate incoming headers against a
provided `cors::Configuration` instance. The `cors::Cors::check_headers()` method returns the
`Result<cors::Check, cors::CorsError>` struct. The result is `Err` when the CORS validation fails.
If the validation passes, the request is `Ok` and you can evaluate the `cors::Check` struct.

### `cors::Check` Struct Available Methods

<table><colgroup><col> <col> <col></colgroup><thead><tr><th>Method</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><div><div><p><code>response_type()</code></p></div></div></td><td><div><div><p><code>cors::ResponseType</code></p></div></div></td><td><div><div><p>Returns an enum containing the type of action needed for the incoming request. For more details about the enum values, see <a href="#enum-response"><code>cors::ResponseType</code> Enum Response Values</a>.</p></div></div></td></tr><tr><td><div><div><p><code>headers()</code></p></div></div></td><td><div><div><p><code>&amp;[(String, String)]</code></p></div></div></td><td><div><div><p>A list of headers to add to the response.</p></div></div></td></tr><tr><td><div><div><p><code>into_headers()</code></p></div></div></td><td><div><div><p><code>Vec&lt;(String, String)&gt;</code></p></div></div></td><td><div><div><p>Consumes the <code>cors::Check</code> struct and returns the list of headers to add to the response.</p></div></div></td></tr></tbody></table>

### `cors::ResponseType` Enum Response Values

<table><colgroup><col> <col></colgroup><thead><tr><th>Value</th><th>Description</th></tr></thead><tbody><tr><td><div><div><p><code>Preflight</code></p></div></div></td><td><div><div><p>The incoming request is a CORS preflight request, and the policy must respond early.</p></div></div></td></tr><tr><td><div><div><p><code>Main</code></p></div></div></td><td><div><div><p>The incoming request is a CORS main request, and the request must continue to the upstream.</p></div></div></td></tr></tbody></table>

## Write a CORS Validation Policy

To write a CORS validation policy:

1.  Define an `#[entrypoint]` function that defines the `cors::Configuration` instance. In the
    following example, `create_cors_configuration()` is the function defined in the
    [Define a CORS Configuration Instance](#cors-configuration) example:

    ```rust
    use pdk::*;
    use pdk::cors;

    #[entrypoint]
    async fn configure(launcher: Launcher) -> Result<(), LaunchError> {

        let cors_configuration = create_cors_configuration();

        let filter = on_request(|rs| request_filter(rs, &cors_configuration))
            .on_response(response_filter);

        launcher.launch(filter).await
    }
    ```

2.  Define a `request_filter()` function to validate the incoming requests by using the CORS
    validation methods. The `Flow` returned must contain a `Vec<(String, String)>` to pass the
    headers returned from `cors::Cors::check_headers()` to the `response_filter()`:

    ```rust
    async fn request_filter(
        request_headers_state: RequestHeadersState,
        cors_configuration: &cors::Configuration<'_>,
    ) -> Flow<Vec<(String, String)>> {

        // Create a new CORS checker.
        let cors = cors::Cors::new(cors_configuration);

        let request_headers = request_headers_state.handler().headers();

        let cors_result = cors.check(&request_headers);

        match cors_result {

            // The CORS validation was succesful.
            Ok(cors_check) => match cors_check.response_type() {

                // A CORS preflight fetch was requested, return an early response.
                cors::ResponseType::Preflight => {
                    Flow::Break(Response::new(200).with_headers(check.into_headers()))
                }

                // This is a CORS main request, continue and pass the headers to the response.
                cors::ResponseType::Main => {
                    logger::info!("Main CORS response.");
                    Flow::Continue(check.into_headers())
                }
            },

            // The CORS validation failed. The request must be refused.
            Err(cors_error) => {
                Flow::Break(Response::new(200))
            }
        }
    }
    ```

3.  Define a `response_filter()` function that validates the response by using the CORS validation
    methods. `RequestData` contains the headers returned by `cors::Cors::check_headers()`:

    ```rust
    async fn response_filter(state: ResponseHeadersState, data: RequestData<Vec<(String, String)>>) {

        // Take the headers to add from the request data.
        let RequestData::Continue(headers_to_add) = data else {
            return;
        };

        // Add the headers to the response
        for (name, value) in headers_to_add.iter() {
            state.handler().set_header(name, value);
        }
    }
    ```

## See Also

- [Implementing Your Custom Policy Features in Rust](https://docs.mulesoft.com/pdk/1.5/policies-pdk-configure-features)
