object

# `http_cors`

Transport-neutral CORS request classification, preflight response generation, and response decoration helpers for normalized HTTP messages.

Availability:
`logtalk_load(http_cors(loader))`
Author: Paulo Moura
Version: 1:0:0
Date: 2026-06-26
Compilation flags:
`static, context_switching_calls`
Imports:
`public` options
`public` http_origin_site_helpers
Uses:
atom
http_core
list
Remarks:
(none)
Inherited public predicates:
check_option/1 check_options/1 default_option/1 default_options/1 option/2 option/3 valid_option/1 valid_options/1

## Public predicates

### `request_origin/2`

Returns the single request `Origin` header value when present.

Compilation flags:
`static`
Template:
`request_origin(Request,Origin)`
Mode and number of proofs:
`request_origin(+compound,-atom)` - `zero_or_one`

### `is_cors_request/1`

Succeeds when the request carries a single `Origin` header value.

Compilation flags:
`static`
Template:
`is_cors_request(Request)`
Mode and number of proofs:
`is_cors_request(+compound)` - `zero_or_one`

### `is_preflight_request/1`

Succeeds when the request is a CORS preflight request with method `options` and a single `Access-Control-Request-Method` header value.

Compilation flags:
`static`
Template:
`is_preflight_request(Request)`
Mode and number of proofs:
`is_preflight_request(+compound)` - `zero_or_one`

### `preflight_response/3`

Builds a normalized CORS preflight response using the given policy options. Allowed preflight requests return `200 OK` with the relevant `Access-Control-*` headers and denied requests return `403 Forbidden`. Non-preflight requests raise an error.

Compilation flags:
`static`
Template:
`preflight_response(Request,Response,Options)`
Mode and number of proofs:
`preflight_response(+compound,-compound,+list(compound))` - `one_or_error`
Exceptions:
`Request` is not a CORS preflight request:
`domain_error(http_cors_preflight_request,Request)`
`Options` is a variable or a partial list:
`instantiation_error`
`Options` is neither a variable nor a list:
`type_error(list,Options)`
An element `Option` of the list `Options` is neither a variable nor a compound term:
`type_error(compound,Option)`
An element `Option` of the list `Options` is a compound term but not a valid option:
`domain_error(option,Option)`
`Options` contains an invalid CORS option combination:
`domain_error(http_cors_options,Options)`
The generated response violates normalized HTTP response semantics:
`domain_error(http_header_semantics,Header)`

### `add_response_headers/4`

Decorates a normalized response with the relevant CORS response headers when the request matches and the policy allows it. Denied requests preserve or add cache-relevant `Vary` metadata but do not add permission headers.

Compilation flags:
`static`
Template:
`add_response_headers(Request,Response0,Response,Options)`
Mode and number of proofs:
`add_response_headers(+compound,+compound,-compound,+list(compound))` - `one_or_error`
Exceptions:
`Options` is a variable or a partial list:
`instantiation_error`
`Options` is neither a variable nor a list:
`type_error(list,Options)`
An element `Option` of the list `Options` is neither a variable nor a compound term:
`type_error(compound,Option)`
An element `Option` of the list `Options` is a compound term but not a valid option:
`domain_error(option,Option)`
`Options` contains an invalid CORS option combination:
`domain_error(http_cors_options,Options)`
`Response0` is not a valid normalized HTTP response term:
`domain_error(http_response,Response0)`
The decorated response violates normalized HTTP response semantics:
`domain_error(http_header_semantics,Header)`

## Protected predicates

(no local declarations; see entity ancestors if any)

## Private predicates

(no local declarations; see entity ancestors if any)

## Operators

(none)