arraypress/wp-header-utils

A lean WordPress library for HTTP header detection and analysis

dev-main 2025-07-16 10:57 UTC

This package is auto-updated.

Last update: 2025-09-02 14:56:15 UTC


README

A lightweight WordPress library for HTTP header detection, content negotiation, and request analysis. Perfect for APIs, performance optimization, and understanding client capabilities.

Features

  • 🎯 Clean API: WordPress-style snake_case methods with consistent interfaces
  • 🌐 Content Negotiation: Parse Accept headers for API responses and content serving
  • 📊 Compression Detection: Identify gzip, brotli, and other compression support
  • 🔍 Request Analysis: Detect AJAX, mobile apps, and CDN requests
  • 🛡️ Security Ready: Extract authentication headers and custom client identifiers
  • Performance Optimized: Built-in caching and efficient header parsing
  • 🔧 WordPress Native: Uses WordPress sanitization and follows coding standards
  • 📱 Real-world Ready: CloudFlare, mobile app, and API detection

Requirements

  • PHP 7.4 or later
  • WordPress 5.0 or later

Installation

composer require arraypress/wp-header-utils

Basic Usage

Header Retrieval

use ArrayPress\HeaderUtils\Headers;

// Get specific headers
$accept = Headers::get( 'Accept' );
// Returns: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"

$user_agent = Headers::get( 'User-Agent' );
// Returns: "Mozilla/5.0 (Windows NT 10.0; Win64; x64)..."

$api_key = Headers::get( 'X-API-Key' );
// Returns: "abc123def456" or null

// Check if header exists
if ( Headers::has( 'Authorization' ) ) {
	// Process authenticated request
}

// Get all headers
$all_headers = Headers::get_all();
// Returns: ['accept' => '...', 'user-agent' => '...', ...]

Content Negotiation

// Get accepted content types with quality values
$accept_types = Headers::get_accept_types();

// Check if client accepts specific content type
if ( Headers::accepts( 'application/json' ) ) {
	wp_send_json( $data );
} else {
	// Serve HTML response
}

// Check for image format support
if ( Headers::accepts( 'image/webp' ) ) {
	serve_webp_images();
} else {
	serve_jpeg_images();
}

Compression Detection

// Check compression support
if ( Headers::is_gzip_supported() ) {
    ob_start( 'ob_gzhandler' );
}

if ( Headers::is_brotli_supported() ) {
    // Enable brotli compression
    header( 'Content-Encoding: br' );
}

// Get all supported encodings
$encoding = Headers::get( 'Accept-Encoding' );
// Returns: "gzip, deflate, br"

Request Type Detection

// Detect AJAX requests
if ( Headers::is_ajax() ) {
	// Handle AJAX-specific logic
	wp_send_json_success( $response );
}

// Detect mobile app requests
if ( Headers::is_mobile_app() ) {
	// Serve mobile app-specific content
	$app_version = Headers::get( 'X-App-Version' );
	handle_mobile_app_request( $app_version );
}

// Check for CloudFlare
if ( Headers::is_cloudflare() ) {
	$cf_country = Headers::get( 'CF-IPCountry' );
	serve_geo_specific_content( $cf_country );
}

Language Preferences

// Get accepted languages with quality values
$languages = Headers::get_accept_languages();
/*
Returns:
[
    'en-US' => 1.0,
    'en' => 0.9,
    'es' => 0.8,
    'fr' => 0.7
]
*/

// Use for content localization
$primary_language = array_key_first( $languages );
if ( $primary_language && $primary_language !== 'en' ) {
    switch_to_locale( get_locale_from_language( $primary_language ) );
}

Authentication & Security

// Get authentication headers
$auth_headers = Headers::get_auth_headers();
/*
Returns:
[
    'x-api-key' => 'abc123def456',
    'authorization' => 'Bearer token123'
]
*/

// API key authentication
$api_key = Headers::get( 'X-API-Key' );
if ( $api_key && validate_api_key( $api_key ) ) {
    // Process authenticated API request
}

// Get custom headers (X-* headers)
$custom_headers = Headers::get_custom_headers();
/*
Returns:
[
    'x-app-version' => '2.1.0',
    'x-platform' => 'iOS',
    'x-api-key' => 'abc123def456'
]
*/

Cache Control

// Get cache control directives
$cache_directives = Headers::get_cache_control();
/*
Returns:
[
    'no-cache' => true,
    'max-age' => '3600',
    'must-revalidate' => true
]
*/

// Check if client wants fresh content
if ( Headers::is_no_cache() ) {
    // Skip cache, serve fresh content
    header( 'Cache-Control: no-cache, no-store, must-revalidate' );
}

Common Use Cases

API Content Negotiation

function handle_api_request() {
	$accept_types = Headers::get_accept_types();

	// Serve appropriate format based on Accept header
	if ( Headers::accepts( 'application/json' ) ) {
		wp_send_json( $data );
	} elseif ( Headers::accepts( 'application/xml' ) ) {
		serve_xml_response( $data );
	} else {
		// Default to JSON
		wp_send_json( $data );
	}
}
add_action( 'wp_ajax_api_endpoint', 'handle_api_request' );

Mobile App Detection

function handle_mobile_app_requests() {
	if ( ! Headers::is_mobile_app() ) {
		return;
	}

	$app_version = Headers::get( 'X-App-Version' );
	$platform    = Headers::get( 'X-Platform' );

	// Handle deprecated app versions
	if ( version_compare( $app_version, '2.0.0', '<' ) ) {
		wp_send_json_error( [
			'message'     => 'App version not supported. Please update.',
			'min_version' => '2.0.0'
		] );
	}

	// Platform-specific handling
	if ( $platform === 'iOS' ) {
		handle_ios_specific_features();
	} elseif ( $platform === 'Android' ) {
		handle_android_specific_features();
	}
}
add_action( 'init', 'handle_mobile_app_requests' );

Performance Optimization

function optimize_response_based_on_headers() {
	// Enable compression if supported
	if ( Headers::is_gzip_supported() && ! ob_get_level() ) {
		ob_start( 'ob_gzhandler' );
	}

	// Serve WebP images if supported
	if ( Headers::accepts( 'image/webp' ) ) {
		add_filter( 'wp_get_attachment_image_src', 'convert_to_webp' );
	}

	// Handle cache preferences
	if ( Headers::is_no_cache() ) {
		header( 'Cache-Control: no-cache, no-store, must-revalidate' );
		header( 'Pragma: no-cache' );
		header( 'Expires: 0' );
	}
}
add_action( 'init', 'optimize_response_based_on_headers' );

CloudFlare Integration

function handle_cloudflare_requests() {
	if ( ! Headers::is_cloudflare() ) {
		return;
	}

	$cf_headers = Headers::get_cloudflare_headers();

	// Get visitor's country
	$country = Headers::get( 'CF-IPCountry' );
	if ( $country ) {
		set_geo_specific_content( $country );
	}

	// Get real IP address
	$real_ip = Headers::get( 'CF-Connecting-IP' );
	if ( $real_ip ) {
		$_SERVER['REMOTE_ADDR'] = $real_ip;
	}

	// Track CloudFlare analytics
	$cf_ray = Headers::get( 'CF-Ray' );
	if ( $cf_ray ) {
		track_cloudflare_request( $cf_ray );
	}
}
add_action( 'init', 'handle_cloudflare_requests' );

AJAX Response Optimization

function optimize_ajax_responses() {
	if ( ! Headers::is_ajax() ) {
		return;
	}

	// Disable WordPress admin bar for AJAX requests
	show_admin_bar( false );

	// Set JSON content type if client accepts it
	if ( Headers::accepts( 'application/json' ) ) {
		header( 'Content-Type: application/json; charset=utf-8' );
	}

	// Enable compression for AJAX responses
	if ( Headers::is_gzip_supported() ) {
		header( 'Content-Encoding: gzip' );
	}
}
add_action( 'wp_ajax_nopriv_*', 'optimize_ajax_responses', 1 );
add_action( 'wp_ajax_*', 'optimize_ajax_responses', 1 );

API Authentication

function authenticate_api_request() {
	$auth_headers = Headers::get_auth_headers();

	// Check for API key
	if ( isset( $auth_headers['x-api-key'] ) ) {
		$api_key = $auth_headers['x-api-key'];
		if ( ! validate_api_key( $api_key ) ) {
			wp_send_json_error( 'Invalid API key', 401 );
		}

		return;
	}

	// Check for Bearer token
	if ( isset( $auth_headers['authorization'] ) ) {
		$auth_header = $auth_headers['authorization'];
		if ( strpos( $auth_header, 'Bearer ' ) === 0 ) {
			$token = substr( $auth_header, 7 );
			if ( ! validate_bearer_token( $token ) ) {
				wp_send_json_error( 'Invalid token', 401 );
			}

			return;
		}
	}

	wp_send_json_error( 'Authentication required', 401 );
}

function secure_api_endpoint() {
	authenticate_api_request();

	// Process authenticated request
	$data = get_api_data();
	wp_send_json_success( $data );
}

add_action( 'wp_ajax_secure_endpoint', 'secure_api_endpoint' );
add_action( 'wp_ajax_nopriv_secure_endpoint', 'secure_api_endpoint' );

Comprehensive Header Analysis

function analyze_request_headers() {
	$header_info = Headers::get_header_info();

	// Log comprehensive request information
	$request_data = [
		'timestamp'           => current_time( 'mysql' ),
		'url'                 => $_SERVER['REQUEST_URI'],
		'method'              => $_SERVER['REQUEST_METHOD'],
		'accept_types'        => $header_info['accept_types'],
		'languages'           => $header_info['accept_languages'],
		'compression_support' => [
			'gzip'   => $header_info['supports_gzip'],
			'brotli' => $header_info['supports_brotli']
		],
		'request_type'        => [
			'ajax'       => $header_info['is_ajax'],
			'mobile_app' => $header_info['is_mobile_app'],
			'cloudflare' => $header_info['is_cloudflare']
		],
		'cache_preferences'   => $header_info['cache_control'],
		'custom_headers'      => $header_info['custom_headers']
	];

	// Store or process request analytics
	update_option( 'request_analytics', $request_data );
}

add_action( 'wp', 'analyze_request_headers' );

Method Reference

Core Methods

  • get(string $header, $default = null) - Get specific header value
  • get_all() - Get all headers as array
  • has(string $header) - Check if header exists

Content Negotiation

  • get_accept_types() - Get accepted content types with quality values
  • accepts( string $content_type ) - Check if client accepts content type
  • get_accept_languages() - Get accepted languages with quality values

Compression Detection

  • is_gzip_supported() - Check if client supports gzip compression
  • is_brotli_supported() - Check if client supports brotli compression

Request Type Detection

  • is_ajax() - Check if request is AJAX (X-Requested-With)
  • is_mobile_app() - Check if request is from mobile app
  • is_cloudflare() - Check if request is behind CloudFlare

Cache Control

  • get_cache_control() - Get cache control directives as array
  • is_no_cache() - Check if client requests no caching

Header Filtering

  • get_custom_headers() - Get all X-* custom headers
  • get_cloudflare_headers() - Get all CF-* CloudFlare headers
  • get_auth_headers() - Get authentication headers

Comprehensive Analysis

  • get_header_info() - Get all header information in one call

WordPress Integration

  • Sanitized Input: All header data is sanitized using sanitize_text_field()
  • WordPress Native: Uses WordPress coding standards and best practices
  • Performance Optimized: Built-in caching for repeated header access
  • Fallback Support: Works with and without getallheaders() function
  • Security Focused: Proper sanitization and validation of all header data

Supported Headers

Standard HTTP Headers

  • Accept - Content type preferences
  • Accept-Language - Language preferences
  • Accept-Encoding - Compression support
  • Cache-Control - Caching directives
  • User-Agent - Client identification
  • Authorization - Authentication

Custom Headers

  • X-API-Key - API authentication
  • X-Requested-With - AJAX detection
  • X-App-Version - Mobile app version
  • X-Platform - Client platform (iOS, Android)
  • X-Auth-Token - Custom authentication

CloudFlare Headers

  • CF-Ray - Request identifier
  • CF-Connecting-IP - Real client IP
  • CF-IPCountry - Visitor country
  • CF-Visitor - Protocol information

Performance

  • Cached Results: Headers are cached after first access for performance
  • Efficient Parsing: Optimized header parsing and content negotiation
  • Memory Efficient: Minimal memory footprint with smart caching
  • WordPress Optimized: Integrates seamlessly with WordPress performance patterns

Requirements

  • PHP 7.4+
  • WordPress 5.0+

Testing

The library has been thoroughly tested with:

  • 100% test coverage for core functionality
  • Real-world header patterns from browsers, mobile apps, and CDNs
  • Edge case handling for malformed and missing headers
  • Performance validation with caching mechanisms
  • WordPress integration with proper sanitization
  • Content negotiation with various Accept header formats

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the GPL-2.0-or-later License.

Support