Using CORS Library Functions | MuleSoft Documentation
# Using CORS Library Functions
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.   
---  
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 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:
```
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
Property | Required or Optional | Default Value | Description  
---|---|---|---  
`origin_groups` |  `Vec` containing groups of origins configurable with `cors::OriginGroup`.  
`public_resource` |  A boolean indicating if the CORS configuration is applied as a public resource.  
`support_credentials` |  A boolean indicating if the CORS configuration supports credentials, such as cookies, authorization headers, and TLS client certificates.  
### cors::OriginGroup Struct Configuration Parameters
Property | Required or Optional | Default Value | Description  
---|---|---|---  
`plain_origins` |  `Vec` of origins included in the group. For example, `http://www.the-origin-of-time.com`.  
`access_control_max_age` |  Duration in seconds to cache a preflight response before sending another preflight request.  
`allowed_methods` |  `Vec` of allowed HTTP methods configurable with `cors::AllowedMethod`.  
`Vec` of HTTP headers for preflight requests.  
`exposed_headers` |  `Vec` of headers that browser JavaScript can access.  
### cors::AllowedMethod Struct Configuration Parameters
Property | Required or Optional | Description  
---|---|---  
Method name.  
A boolean indicating if a method is allowed. Supported values are `CONNECT`, `DELETE`, `GET`, `OPTIONS`, `PATCH`, `POST`, `PUT`, or `TRACE`.  
## 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
Method | Type | Description  
---|---|---  
`response_type()` |  `cors::ResponseType` |  Returns an enum containing the type of action needed for the incoming request. For more details about the enum values, see `cors::ResponseType` Enum Response Values.  
`&[(String, String)]` |  A list of headers to add to the response.  
`into_headers()` |  `Vec<(String, String)>` |  Consumes the `cors::Check` struct and returns the list of headers to add to the response.  
### `cors::ResponseType` Enum Response Values
Value | Description  
---|---  
The incoming request is a CORS preflight request, and the policy must respond early.  
The incoming request is a CORS main request, and the request must continue to the upstream.  
## 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 example:
```
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()`:
```
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()`:
```
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