VOOZH about

URL: https://deepwiki.com/hypervel/http/4.3-cors-middleware

⇱ CORS Middleware | hypervel/http | DeepWiki


Loading...
Menu

CORS Middleware

Purpose

The CORS (Cross-Origin Resource Sharing) middleware system provides comprehensive handling of cross-origin HTTP requests. The system consists of the HandleCors middleware class that intercepts requests and the Cors logic class that implements CORS specification rules. This page documents CORS request processing, preflight handling, origin validation, and configuration options.

For information about other middleware components, see Core Middleware & Request Lifecycle and Request Validation Middleware. For general middleware concepts, see Middleware & Routing.

Architecture Overview

The CORS system is composed of two primary classes: HandleCors middleware that integrates into the PSR-15 middleware pipeline, and Cors which encapsulates CORS logic and header manipulation.

CORS Component Structure


Sources: src/Middleware/HandleCors.php19-122 src/Cors.php37-299

HandleCors Middleware

The HandleCors class implements MiddlewareInterface and serves as the integration point for CORS functionality in the request pipeline. It is responsible for determining when CORS processing should occur and coordinating between request handling and the Cors logic class.

Class Structure

ComponentTypePurpose
$containerContainerInterfaceDependency injection container
$exceptionHandlerExceptionHandlerContractException handling coordination
$requestRequestContractCurrent HTTP request
$corsCorsCORS logic instance
$configarrayCORS configuration array

Sources: src/Middleware/HandleCors.php23-30

Request Processing Flow

The process() method implements the core middleware logic:


Sources: src/Middleware/HandleCors.php32-56

Path Matching

The middleware uses hasMatchingPath() to determine if CORS processing should apply to the current request. Path matching supports:

  • Host-specific path configurations
  • Wildcard pattern matching via Str::is()
  • Comparison against both full URL and decoded path

The method retrieves paths from configuration using getPathsByHost(), which checks for host-specific paths first, then falls back to string-only paths in the configuration array.

Sources: src/Middleware/HandleCors.php75-105

Header Addition

The addRequestHeaders() method applies CORS headers to responses after normal request processing:

  1. For OPTIONS requests, adds Vary: Access-Control-Request-Method header
  2. Delegates to Cors::addActualRequestHeaders() for main CORS headers
  3. Used both for successful responses and exceptions (via afterResponse callback)

Sources: src/Middleware/HandleCors.php58-70

Cors Logic Class

The Cors class contains the core CORS specification implementation. It was ported from fruitcake/php-cors and handles origin validation, preflight requests, and header configuration.

CORS State


Sources: src/Cors.php39-99

Request Type Detection

The Cors class provides two key detection methods:

MethodConditionPurpose
isCorsRequest()Request has Origin headerIdentifies cross-origin requests
isPreflightRequest()Request is OPTIONS with Access-Control-Request-MethodIdentifies preflight requests

Sources: src/Cors.php137-145

Preflight Request Handling


The handlePreflightRequest() method creates a 204 No Content response and applies preflight-specific headers via addPreflightRequestHeaders(). Headers are only added if the origin is allowed, as determined by the presence of the Access-Control-Allow-Origin header.

Sources: src/Cors.php147-171

Actual Request Headers

For non-preflight CORS requests, addActualRequestHeaders() adds:

  1. Access-Control-Allow-Origin - The validated origin or wildcard
  2. Access-Control-Allow-Credentials - If credentials are supported
  3. Access-Control-Expose-Headers - Headers the client can access

Sources: src/Cors.php194-204

Configuration Options

The CORS configuration is published to config/autoload/cors.php and supports both camelCase and snake_case option names.

Configuration Schema

OptionTypeDefaultPurpose
pathsarray['api/*', 'sanctum/csrf-cookie']URL paths where CORS applies
allowed_methodsstring[]['*']Allowed HTTP methods
allowed_originsstring[]['*']Allowed origin domains
allowed_origins_patternsstring[][]Regex patterns for origins
allowed_headersstring[]['*']Allowed request headers
exposed_headersstring[][]Headers exposed to client
max_ageint|null0Preflight cache duration in seconds
supports_credentialsboolfalseAllow credentials (cookies, auth)

Sources: publish/cors.php5-34

Path Configuration

Paths support two formats:

  1. Global paths - String values apply to all hosts: ['api/*', 'admin/*']
  2. Host-specific paths - Nested arrays keyed by hostname:
    
    

Path matching uses wildcard patterns via Str::is(), supporting * as a wildcard character.

Sources: src/Middleware/HandleCors.php94-105

Option Normalization

The normalizeOptions() method processes configuration:

  1. Converts headers to lowercase and methods to uppercase
  2. Detects ['*'] values and sets corresponding allowAll* flags
  3. Converts wildcard origins to regex patterns via convertWildcardToPattern()

Sources: src/Cors.php101-135

Origin Validation

Validation Logic


Sources: src/Cors.php173-192

Origin Header Configuration

The configureAllowedOrigin() method implements three strategies based on configuration:

StrategyConditionBehavior
WildcardallowAllOrigins=true and no credentialsSets Access-Control-Allow-Origin: * (cacheable)
Single originExactly one origin in allowedOriginsSets fixed origin header (cacheable)
DynamicMultiple origins or patternsEchoes validated request Origin header, adds Vary: Origin

The dynamic strategy is necessary when supporting credentials, as browsers reject * origins with credentials.

Sources: src/Cors.php206-224

Response Header Configuration

Header Configuration Methods


Sources: src/Cors.php235-284

Allowed Methods

When allowAllMethods is true, the middleware echoes the Access-Control-Request-Method header value and adds Vary: Access-Control-Request-Method. Otherwise, it returns the comma-separated list from allowedMethods.

Sources: src/Cors.php235-245

Allowed Headers

When allowAllHeaders is true, the middleware echoes the Access-Control-Request-Headers header value and adds Vary: Access-Control-Request-Headers. Otherwise, it returns the comma-separated list from allowedHeaders.

Sources: src/Cors.php247-257

Credentials Support

If supportsCredentials is enabled, adds Access-Control-Allow-Credentials: true header. This prevents using wildcard origins, forcing dynamic origin validation.

Sources: src/Cors.php259-266

Exposed Headers

The configureExposedHeaders() method adds Access-Control-Expose-Headers with a comma-separated list of headers that the client-side JavaScript can access. Only applied to actual requests, not preflight.

Sources: src/Cors.php268-275

Max Age

Sets Access-Control-Max-Age header to indicate how long (in seconds) the preflight response can be cached. A value of 0 disables caching.

Sources: src/Cors.php277-284

Vary Header Management

The varyHeader() method ensures proper HTTP caching by adding headers to the Vary response header. This tells caches that the response varies based on specific request headers.

The method:

  1. Creates Vary header if it doesn't exist
  2. Appends to existing Vary header, avoiding duplicates
  3. Comma-separates multiple vary values

Common vary headers added:

  • Origin - When using dynamic origin validation
  • Access-Control-Request-Method - When allowing all methods
  • Access-Control-Request-Headers - When allowing all headers

Sources: src/Cors.php286-298

Configuration Publishing

The CORS configuration file is registered in ConfigProvider for publishing. Developers can publish the configuration using Hyperf's vendor:publish command to customize CORS behavior.

Publishing configuration structure:

  • ID: 'config'
  • Source: __DIR__ . '/../publish/cors.php'
  • Destination: BASE_PATH . '/config/autoload/cors.php'

Sources: src/ConfigProvider.php21-28