Skip to content
beginner Phase 2 · HTTP Deep Dive

HTTP Headers: Working with Request and Response Headers

Master HTTP headers including Content-Type, Authorization, Cache-Control, CORS, and custom headers with PHP header() function examples.

45m
0 problems
Topic Progress 0%

Common Request Headers

Request Headers

Request headers are sent by the client with every request to provide metadata.

Header Purpose Example
Host Target domain magento-store.com
User-Agent Client software info Mozilla/5.0 (Windows...)
Accept Preferred response format text/html, application/json
Accept-Language Preferred language en-US, en;q=0.9
Accept-Encoding Compression support gzip, deflate, br
Content-Type Body format application/json
Authorization Authentication credentials Bearer eyJhbGciOi...
Cookie Session cookies PHPSESSID=abc123
Cache-Control Caching directives no-cache
If-None-Match ETag for cache validation "abc123"
If-Modified-Since Last modified date Mon, 01 Jan 2026...

PHP: Reading Request Headers

<?php
// Method 1: $_SERVER superglobal
$accept = $_SERVER['HTTP_ACCEPT'];
$userAgent = $_SERVER['HTTP_USER_AGENT'];
$authorization = $_SERVER['HTTP_AUTHORIZATION'] ?? null;

// Method 2: getallheaders() function
$headers = getallheaders();
$contentType = $headers['Content-Type'] ?? null;
$accept = $headers['Accept'] ?? null;

// Method 3: Get specific header with custom name
function getHeader(string $name): ?string
{
    $headers = getallheaders();
    
    // Headers can be different cases
    foreach ($headers as $key => $value) {
        if (strtolower($key) === strtolower($name)) {
            return $value;
        }
    }
    return null;
}

// Parse Accept header to check supported formats
$accept = $_SERVER['HTTP_ACCEPT'] ?? '';
$wantsJson = strpos($accept, 'application/json') !== false;
$wantsHtml = strpos($accept, 'text/html') !== false;

if ($wantsJson) {
    header('Content-Type: application/json');
    echo json_encode($data);
} elseif ($wantsHtml) {
    header('Content-Type: text/html');
    echo renderTemplate($data);
}

Authorization Header Patterns

<?php
// Bearer token authentication (Magento REST API style)
$authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '';

if (preg_match('/^Bearer\s+(.+)$/i', $authHeader, $matches)) {
    $token = $matches[1];
    $user = validateBearerToken($token);
    
    if (!$user) {
        http_response_code(401);
        echo json_encode(['error' => 'Invalid token']);
        exit;
    }
} else {
    http_response_code(401);
    header('WWW-Authenticate: Bearer realm="api"');
    echo json_encode(['error' => 'Authorization header required']);
    exit;
}

// Basic authentication (admin panel style)
$authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '';

if (preg_match('/^Basic\s+(.+)$/i', $authHeader, $matches)) {
    $decoded = base64_decode($matches[1]);
    [$username, $password] = explode(':', $decoded, 2);
    
    $user = authenticateUser($username, $password);
    if (!$user) {
        http_response_code(401);
        header('WWW-Authenticate: Basic realm="Admin"');
        exit;
    }
}

Response Headers: Content-Type, Cache-Control, Security

Response Headers

Response headers are sent by the server to control how the client processes the response.

Header Purpose Example
Content-Type Response body format application/json; charset=UTF-8
Content-Length Body size in bytes 45213
Cache-Control Caching behavior max-age=3600, private
Expires Expiration date Mon, 01 Jan 2027 00:00:00 GMT
ETag Resource version hash "abc123"
Location Redirect URL https://magento-store.com/
Set-Cookie Set a cookie session=abc123; Path=/
X-Content-Type-Options Prevent MIME sniffing nosniff
X-Frame-Options Prevent clickjacking SAMEORIGIN
X-XSS-Protection XSS protection 1; mode=block
Strict-Transport-Security Force HTTPS max-age=31536000

PHP: Setting Response Headers

<?php
// Basic header setting
header('Content-Type: application/json; charset=UTF-8');
header('X-Custom-Header: SomeValue');

// Remove a header
header_remove('X-Powered-By');

// Set status code with headers
header('HTTP/1.1 200 OK');
http_response_code(200); // Alternative

// Content-Type for different formats
header('Content-Type: text/html; charset=UTF-8');
header('Content-Type: application/json; charset=UTF-8');
header('Content-Type: text/xml; charset=UTF-8');
header('Content-Type: image/png');

// Send file download
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="export.csv"');
header('Content-Length: ' . filesize($filePath));
readfile($filePath);

Caching Headers

<?php
// No caching - dynamic content
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');

// Cache for 1 hour
header('Cache-Control: public, max-age=3600');
header('Last-Modified: ' . date('r', $lastModified));

// Cache for 1 week
header('Cache-Control: public, max-age=604800');
header('ETag: "' . md5_file($filePath) . '"');

// Private cache (user-specific, like cart page)
header('Cache-Control: private, max-age=300');

// Validation with ETag
$etag = md5_file($filePath);
header('ETag: "' . $etag . '"');

if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] === '"' . $etag . '"') {
    http_response_code(304);
    exit;
}

Security Headers

<?php
// Security headers - should be on every response
header('X-Content-Type-Options: nosniff');     // Prevent MIME type sniffing
header('X-Frame-Options: SAMEORIGIN');         // Prevent clickjacking
header('X-XSS-Protection: 1; mode=block');     // Enable XSS filter
header('Referrer-Policy: strict-origin-when-cross-origin');
header('Content-Security-Policy: default-src \'self\'; script-src \'self\' \'unsafe-inline\'');
header('Strict-Transport-Security: max-age=31536000; includeSubDomains'); // HSTS

// Remove server identification headers
header_remove('X-Powered-By');
header_remove('Server');

Magento Security Headers

Magento applies these headers through Magento\Framework\Response\HeaderManager:

  • X-Content-Type-Options: nosniff
  • X-Frame-Options: SAMEORIGIN
  • X-XSS-Protection: 1; mode=block
  • X-Download-Options: noopen
  • X-Permitted-Cross-Domain-Policies: none

CORS Headers for Cross-Origin Requests

Understanding CORS

CORS (Cross-Origin Resource Sharing) controls how resources can be requested from a different domain.

Same-Origin Policy: Browsers block requests to a different domain by default.

CORS Headers: Tell the browser which domains are allowed to access the resource.

CORS Headers

Header Purpose Example
Access-Control-Allow-Origin Allowed origins https://magento-store.com
Access-Control-Allow-Methods Allowed HTTP methods GET, POST, PUT, DELETE
Access-Control-Allow-Headers Allowed request headers Content-Type, Authorization
Access-Control-Allow-Credentials Allow cookies/auth true
Access-Control-Max-Age Cache preflight results 86400 (24 hours)
Access-Control-Expose-Headers Headers the client can read X-Request-Id

PHP CORS Implementation

<?php
// CORS middleware - add to every API response
function setCorsHeaders(): void
{
    // Get the requesting origin
    $origin = $_SERVER['HTTP_ORIGIN'] ?? '';
    
    // Define allowed origins
    $allowedOrigins = [
        'https://magento-store.com',
        'https://www.magento-store.com',
        'https://admin.magento-store.com'
    ];
    
    // Check if origin is allowed
    if (in_array($origin, $allowedOrigins)) {
        header('Access-Control-Allow-Origin: ' . $origin);
    }
    
    // Allow credentials (cookies, auth headers)
    header('Access-Control-Allow-Credentials: true');
    
    // Handle preflight OPTIONS request
    if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
        header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS');
        header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With, X-Custom-Header');
        header('Access-Control-Max-Age: 86400'); // Cache for 24 hours
        http_response_code(204);
        exit;
    }
}

// Call this at the start of every API request
setCorsHeaders();

// Now handle the actual request
$product = getProductById($_GET['id']);
header('Content-Type: application/json');
echo json_encode($product);

Preflight vs Simple Requests

Simple requests (no preflight needed):

  • Method: GET, HEAD, POST
  • Headers: Accept, Content-Language, Content-Type (with limited values)
  • Content-Type: text/plain, multipart/form-data, application/x-www-form-urlencoded

Preflight requests (browser sends OPTIONS first):

  • Method: PUT, DELETE, PATCH
  • Headers: Authorization, Content-Type: application/json
  • Any custom headers

Magento CORS Configuration

<!-- app/code/Vendor/Module/etc/frontend/di.xml -->
<config>
    <type name="Magento\Framework\App\Response\CORS">
        <arguments>
            <argument name="allowedOrigins" xsi:type="array">
                <item name="frontend" xsi:type="string">https://magento-store.com</item>
                <item name="admin" xsi:type="string">https://admin.magento-store.com</item>
            </argument>
        </arguments>
    </type>
</config>

Common CORS Errors and Fixes

Error Cause Fix
Missing Access-Control-Allow-Origin No CORS headers sent Add CORS header for the origin
Origin not allowed Origin not in allowed list Add origin to allowed list
Credentials not supported Allow-Credentials not true Set Access-Control-Allow-Credentials: true
Method not allowed OPTIONS preflight failed Include method in Access-Control-Allow-Methods
Header not allowed Request header not in Allow-Headers Add header to Access-Control-Allow-Headers

Key Takeaway

CORS is a browser security feature that controls cross-origin requests. For Magento REST APIs consumed by frontend JavaScript or mobile apps, proper CORS configuration is essential.

Quiz

1. How do you read a request header in PHP?

Question 1 options

2. What does the Cache-Control: no-cache header mean?

Question 2 options

3. What CORS header tells the browser which domains can access the resource?

Question 3 options

4. When does a browser send a CORS preflight request?

Question 4 options

5. What header forces browsers to use HTTPS for all future requests?

Question 5 options

Flashcards

Question

How do you set a response header in PHP?

Answer

Use header('Name: Value') function. Must be called before any output. Example: header('Content-Type: application/json');

Question

What is the difference between no-cache and no-store?

Answer

no-cache: Can be cached but must revalidate before use. no-store: Should never be cached at all.

Question

What CORS headers are needed for a Magento REST API?

Answer

Access-Control-Allow-Origin (specific domain), Access-Control-Allow-Methods (GET, POST, PUT, DELETE), Access-Control-Allow-Headers (Content-Type, Authorization), Access-Control-Allow-Credentials (true).

Question

What security headers should every Magento response include?

Answer

X-Content-Type-Options: nosniff, X-Frame-Options: SAMEORIGIN, X-XSS-Protection: 1; mode=block, Strict-Transport-Security: max-age=31536000, Content-Security-Policy.

Question

How do you read the Authorization header in PHP?

Answer

$_SERVER['HTTP_AUTHORIZATION'] or getallheaders()['Authorization']. Parse with preg_match('/Bearer\s+(.+)/', $auth, $matches) for token extraction.

Question

What is a simple request vs preflight request?

Answer

Simple: GET/HEAD/POST with standard headers. Preflight: Any other method or custom headers. Browser sends OPTIONS first for preflight requests.

Question

How do you set ETag caching in PHP?

Answer

header('ETag: "' . md5($content) . '"'); Check with if ($_SERVER['HTTP_IF_NONE_MATCH'] === '"etag"') { http_response_code(304); exit; }

Question

What does Access-Control-Allow-Credentials: true do?

Answer

Allows the browser to send cookies and authentication headers in cross-origin requests. Without this, browsers strip credentials from cross-origin requests.

Revision Notes

Key Takeaways

  • 1. Request headers provide metadata about the client's request (Accept, Authorization, Content-Type)
  • 2. Response headers control how the client processes the response (Cache-Control, Content-Type)
  • 3. Use $_SERVER['HTTP_HEADER_NAME'] or getallheaders() to read request headers
  • 4. Use header() function to set response headers (must be called before output)
  • 5. CORS headers control cross-origin access: Access-Control-Allow-Origin is the most critical
  • 6. Security headers protect against common attacks: XSS, clickjacking, MIME sniffing

Interview Tips

  • Know how to read and set headers in PHP
  • Understand the difference between no-cache and no-store
  • Explain CORS and why preflight requests exist
  • List important security headers and their purposes
  • Understand how Authorization headers work (Bearer, Basic)

Cheat Sheet

HTTP Headers Cheat Sheet

Reading Headers (PHP):

$_SERVER['HTTP_ACCEPT']          // Accept header
$_SERVER['HTTP_AUTHORIZATION']   // Auth header
getallheaders()                  // All headers as array

Setting Headers (PHP):

header('Content-Type: application/json');
header('Cache-Control: public, max-age=3600');
header('Access-Control-Allow-Origin: https://site.com');
http_response_code(200);

CORS Headers:

  • Access-Control-Allow-Origin: Allowed domain
  • Access-Control-Allow-Methods: GET, POST, PUT, DELETE
  • Access-Control-Allow-Headers: Content-Type, Authorization
  • Access-Control-Allow-Credentials: true

Security Headers:

  • X-Content-Type-Options: nosniff
  • X-Frame-Options: SAMEORIGIN
  • Strict-Transport-Security: max-age=31536000

Cache Headers:

  • Cache-Control: public, max-age=3600
  • ETag: "hash"
  • Last-Modified: date