Managing HTTP Headers
1. Enabling Headers Module
| Directive | Description | Default | Context | Override |
|---|---|---|---|---|
| LoadModule | Loads the headers module at runtime | None | server config | None |
Note: On some systems, the module might be located at
modules/mod_headers.so or mod_headers.load. Ensure the path matches your installation.
2. Setting Response Headers
| Directive | Description | Values | Notes |
|---|---|---|---|
| Header | Sets a response header | name value |
Can be used multiple times to set multiple headers |
| HeaderName | Modifies the name of a header | oldname newname |
Useful for renaming headers |
| AddDefaultCharset | Adds a charset to the Content-Type header | charset |
Appends charset to existing Content-Type header |
| SetEnvIf | Sets environment variables based on request headers | header-name regex value |
Can be used to conditionally set headers |
Example: Setting a Custom Header
<IfModule mod_headers.c>
Header set X-Custom-Header "CustomValue"
</IfModule>
Example: Setting a Security Header
<IfModule mod_headers.c>
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "DENY"
</IfModule>
Note: The
Header directive can be used in various contexts (server config, virtual host, directory, .htaccess) and supports conditional logic using env or expr.
3. Adding Headers Without Overwriting
| Directive | Description | Default | Notes |
|---|---|---|---|
| Header add | Adds a header field to the response | None | Does not overwrite existing headers with same name |
| Header append | Appends a value to an existing header or creates new one | None | Similar to Header add, but appends to existing values |
Example: Using Header add
<IfModule mod_headers.c>
Header add X-Custom-Header "custom-value"
Header add X-Another-Header "another-value"
</IfModule>
Example: Using Header append
<IfModule mod_headers.c>
Header append X-Response-Time "100ms"
Header append X-Response-Time "200ms"
</IfModule>
Note:
Header add and Header append are part of the mod_headers module. Ensure it's enabled before using these directives.
Key Points
Header addadds a new header without overwriting existing ones.Header appendappends to an existing header or creates a new one.- Both directives support conditions (e.g.,
env=CONDITION,expr=EXPRESSION). - Useful for adding security headers, tracking identifiers, or custom metadata.
4. Appending Header Values
| Directive | Description | Values | Notes |
|---|---|---|---|
| Header append | Appends a value to an existing header field | Header append <field> <value> [expr=<expression>] [env=<environment-variable>] |
Can be used multiple times to append to the same header |
Example: Appending Based on a Condition
Header append X-Request-Time expr="%{REQUEST_TIME}" env=REQUEST_TIME
5. Unsetting Headers
| Directive | Description | Notes |
|---|---|---|
| Header unset | Removes a header from the response | Can be used to remove headers added by other modules or applications |
Note: The
Header unset directive is part of the mod_headers module, which must be enabled for this functionality to work.
6. Using Conditional Headers
| Header | Description | Usage |
|---|---|---|
| If-Match | Matches the entity tag of the resource | Used for optimistic concurrency control |
| If-None-Match | Matches the entity tag of the resource | Used to prevent modification of a resource if it has changed |
| If-Modified-Since | Checks if the resource has been modified since a given date | Used to reduce bandwidth by avoiding sending unchanged resources |
| If-Unmodified-Since | Checks if the resource has not been modified since a given date | Used to ensure that a resource has not changed before modifying it |
Example: Using If-Modified-Since
curl -H "If-Modified-Since: Wed, 21 Oct 2023 07:28:00 GMT" http://example.com/resource
Note: The server will return a 304 Not Modified status if the resource has not changed since the specified date.
7. Modifying Request Headers
| Directive | Description | Values | Notes |
|---|---|---|---|
| RequestHeader | Modifies or adds a header to the request | set|append|merge|unset|edit |
Can be used to modify or add headers before the request is processed |
| RequestHeader set | Sets a new header or replaces an existing one | header-name value |
Header name and value to set |
| RequestHeader append | Adds a new header value to an existing header | header-name value |
Appends to existing header, if it exists |
| RequestHeader merge | Merges a new header value with an existing one using comma separation | header-name value |
Merges values with comma separation |
| RequestHeader unset | Removes a header from the request | header-name |
Removes header by name |
| RequestHeader edit | Edits an existing header value using a regular expression | header-name regex replacement |
Applies regex to header value and replaces with new value |
Example: Setting a Custom Header
<IfModule mod_headers.c>
RequestHeader set X-Client-Info "Apache/2.4"
</IfModule>
Example: Appending to an Existing Header
<IfModule mod_headers.c>
RequestHeader append X-Forwarded-For "192.168.1.1"
</IfModule>
Example: Editing a Header Value
<IfModule mod_headers.c>
RequestHeader edit X-Forwarded-Proto "^http$" "https"
</IfModule>
8. Setting Custom Headers
| Directive | Description | Values | Notes |
|---|---|---|---|
| Header | Sets a custom header to be sent in the response | set|append|unset|merge |
Use set to override existing headers, append to add to them, unset to remove, and merge to merge with existing values |
| HeaderName | Specifies the name of the header to set or modify | string |
Can be any valid HTTP header name |
| HeaderValue | Specifies the value to set for the header | string |
Can include variables like %{REQUEST_URI} or %{HTTP_USER_AGENT} |
Example: Setting a Custom Header
<IfModule mod_headers.c>
Header set X-Custom-Header "MyValue"
</IfModule>
Example: Appending to an Existing Header
<IfModule mod_headers.c>
Header append X-Frame-Options "SAMEORIGIN"
</IfModule>
Example: Using Variables in Headers
<IfModule mod_headers.c>
Header set X-Request-Time "%{REQUEST_TIME}"
</IfModule>
Note: The
mod_headers module must be enabled for these directives to work.
Warning: Setting headers with sensitive data (e.g., passwords) can expose them in logs or browser developer tools.
9. Configuring Cache-Control Headers
| Directive | Values | Description |
|---|---|---|
| Header set Cache-Control | max-age=3600 |
Sets the maximum age of the cache in seconds |
| Header set Cache-Control | no-cache |
Forces revalidation before serving from cache |
| Header set Cache-Control | no-store |
Prevents caching of the response |
| Header set Cache-Control | public |
Allows caching by any cache, including public caches |
| Header set Cache-Control | private |
Allows caching only by the user's browser, not shared caches |
Example: Setting Cache-Control Header
<IfModule mod_headers.c>
Header set Cache-Control "max-age=3600, public"
</IfModule>
Note: The
Cache-Control header is more flexible and powerful than the older Expires header.
Warning: Misconfiguring
Cache-Control can lead to stale content being served or unnecessary revalidation.
10. Setting Expires Headers
| Directive | Values | Description |
|---|---|---|
| ExpiresActive | on | off |
Enables or disables the Expires module functionality. |
| ExpiresDefault | access | modification | time |
Sets the default expiration time for resources without explicit headers. |
| ExpiresByType | MIME type and time value | Assigns expiration times to specific MIME types. |
| ExpiresByLocation | URL pattern and time value | Applies expiration times based on URL location patterns. |
Example: Setting Expires Headers for Static Assets
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault "access plus 1 year"
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
</IfModule>
Example: Using ExpiresByLocation for Dynamic Content
<IfModule mod_expires.c>
ExpiresActive on
ExpiresByLocation "^/api/" "access plus 1 hour"
ExpiresByLocation "^/static/" "access plus 1 year"
</IfModule>
Note: The
ExpiresDefault directive sets a fallback expiration time if no specific directive matches. It's recommended to set this for all resources to ensure consistent caching behavior.
11. Understanding Header Inheritance
| Header Type | Inheritance Behavior | Notes |
|---|---|---|
| Request Headers | Passed through to backend | Most headers are forwarded by default |
| Response Headers | Can be added/modified per context | Headers can be set at various levels (server, virtual host, directory) |
| Server Tokens | Controlled via ServerTokens |
Can be set to Full, Minor, Minimal, or Prod |
| Custom Headers | Applied in order of configuration | Use Header directive to define custom headers |
Example: Setting Custom Response Headers
<IfModule mod_headers.c>
Header set X-Frame-Options "DENY"
Header set X-Content-Type-Options "nosniff"
</IfModule>
Note: Header inheritance can be controlled using
Header directives with add, set, or unset actions.
Warning: Setting
ServerTokens Full exposes server version details, which may be a security risk.
12. Testing Headers
| Header | Description | Example Value |
|---|---|---|
| Content-Type | Indicates the media type of the resource | application/json |
| Cache-Control | Directs caching mechanisms for the response | no-cache |
| Server | Identifies the software used by the origin server | Apache/2.4.57 (Unix) |
Note: Use
curl -I to fetch only headers without body content.