Implementing Content Negotiation
1. Enabling Negotiation Module
| Module | Status | Description |
|---|---|---|
| mod_negotiation | NEW | Enables content negotiation for files with multiple representations |
MultiViews option allows Apache to serve the most appropriate version of a file based on client preferences.
2. Using MultiViews Option
The MultiViews option in Apache HTTP Server enables content negotiation based on the client's Accept header and file extensions. When enabled, Apache will look for files with different content types (e.g., .html, .en.html, .fr.html) and serve the most appropriate version.
| Directive | Values | Description |
|---|---|---|
| Options | +MultiViews or -MultiViews |
Enables or disables content negotiation based on file extensions and client preferences. |
MultiViews can lead to performance overhead as Apache must check for multiple file variants. It is recommended to use it only when content negotiation is required.
3. Configuring Language Negotiation
| Directive | Description | Default | Notes |
|---|---|---|---|
| LanguagePriority | Sets the priority order for language negotiation | None | Must be set to define language priorities |
| ContentNegotiation | Enables content negotiation | Off | Must be enabled to use language negotiation |
| AddLanguage | Adds a language to the negotiation list | None | Can be used multiple times for different languages |
Example: Setting Language Priority
<IfModule mod_negotiation.c>
LanguagePriority en fr de
</IfModule>
Example: Adding Language Support
<IfModule mod_negotiation.c>
AddLanguage en .en
AddLanguage fr .fr
AddLanguage de .de
</IfModule>
mod_negotiation to be loaded and enabled.
4. Setting Character Set Negotiation
| Directive | Values | Description |
|---|---|---|
| AddDefaultCharset | UTF-8 |
Sets the default character set for text content types. |
| AddCharset | UTF-8 |
Maps a character set to a content type. |
| CharsetSource | default, file |
Determines the source of character set information. |
5. Creating Type Map Files
Type map files in Apache HTTP Server are used to define how the server should handle content negotiation for specific file extensions or MIME types. These files are particularly useful when you want to override the default content negotiation behavior or provide explicit mappings for content types.
| Directive | Description | Values |
|---|---|---|
| AddType | Maps a file extension to a MIME type | .html → text/html |
| TypesConfig | Specifies the path to a type map file | /etc/apache2/mime.types |
Example: Creating a Custom Type Map File
# Create a custom type map file
touch /etc/apache2/custom_types.map
# Add content to the file
echo "# Custom MIME type mappings" > /etc/apache2/custom_types.map
echo ".js application/javascript" >> /etc/apache2/custom_types.map
echo ".json application/json" >> /etc/apache2/custom_types.map
Example: Using the Type Map in Apache Configuration
# In your Apache config file (e.g., httpd.conf or .htaccess)
TypesConfig /etc/apache2/custom_types.map
TypesConfig directive should point to a valid file containing MIME type mappings. The format of the file is extension mime-type, one per line.
6. Setting Quality Values
| Directive | Values | Description |
|---|---|---|
| AcceptFilter | on | off |
Enables or disables AcceptFilter for content negotiation |
| AcceptLanguage | en, fr, de |
Specifies preferred languages for content negotiation |
| AcceptCharset | utf-8, iso-8859-1 |
Defines preferred character sets for content negotiation |
| AcceptEncoding | gzip, deflate |
Lists preferred content encodings for negotiation |
Example: Setting Quality Values in .htaccess
AcceptLanguage en fr de
AcceptCharset utf-8 iso-8859-1
AcceptEncoding gzip deflate
q= parameter in the Accept header. The server uses these to prioritize content types based on client preferences.
7. Understanding Variant Selection Algorithm
The Variant Selection Algorithm in Apache HTTP Server is used to select the most appropriate content variant based on client preferences and server configuration. It evaluates various criteria to determine which version of a resource should be served.
| Criterion | Description | Behavior |
|---|---|---|
| Content-Type | Matches the MIME type of the requested resource. | Server selects variant with matching content-type. |
| Language | Matches the preferred language of the client. | Server selects variant with matching language tag. |
| Encoding | Matches the encoding preferred by the client (e.g., gzip). | Server selects variant with matching encoding. |
| Charset | Matches the character set preferred by the client. | Server selects variant with matching charset. |
| Quality Values | Client-provided quality values (q-values) to prioritize variants. | Server selects variant with highest q-value match. |
Example: Content Negotiation Configuration
<IfModule mod_negotiation.c>
LanguagePriority en fr de
SetEnvIf Accept-Language "^en" preferEnglish
SetEnvIf Accept-Language "^fr" preferFrench
</IfModule>
mod_negotiation module must be enabled to use content negotiation features.
Variant Selection Process
- Client sends Accept headers specifying preferences.
- Server evaluates available variants against client preferences.
- Server selects the best match based on quality values and criteria.
- If no match is found, the server may fall back to a default variant.
8. Configuring Content Encoding Negotiation
Content encoding negotiation allows the server to select the most appropriate encoding for a response based on client capabilities and preferences.
| Directive | Description | Values | Default |
|---|---|---|---|
| AddOutputFilterByType | Applies output filters based on content type | ENCODING MIME_TYPE |
None |
| BrowserMatch | Matches browser capabilities to set encoding preferences | REGEX ENCODING |
None |
| SetEnvIf | Sets environment variables based on client headers | HEADER VALUE |
None |
Example: Setting up content encoding negotiation
<IfModule mod_mime.c>
AddOutputFilterByType DEFLATE text/html text/css application/json
</IfModule>
<IfModule mod_setenvif.c>
SetEnvIfNoCase Accept-Encoding "gzip" accept-encoding
</IfModule>
mod_deflate module is enabled to support content encoding.
| Encoding | Description | Support | Notes |
|---|---|---|---|
| gzip | Standard compression algorithm | Good | Most widely supported |
| br | Brotli compression | Modern | High compression ratio, newer support |
| compress | Unix compress format | Limited | Legacy, less common |
9. Using Prefer-Language Header
| Directive | Description | Default | Notes |
|---|---|---|---|
| AcceptLanguage | Defines the list of languages that the server can serve | None | Used in conjunction with Prefer-Language |
| LanguagePriority | Specifies the priority order of languages to serve | None | Can be set using LanguagePriority |
Example: Setting up language negotiation
<IfModule mod_negotiation.c>
AddLanguage en .en
AddLanguage fr .fr
LanguagePriority en fr
AcceptLanguage en fr
</IfModule>
Prefer-Language header is not a standard HTTP header but can be used in custom implementations or with specific modules like mod_negotiation.
10. Serving Multiple Representations
| Directive | Description | Values |
|---|---|---|
| AcceptFilter | Configures content negotiation based on Accept headers | off, on |
| ContentNegotiation | Enables or disables content negotiation | on, off |
| LanguagePriority | Defines priority order for language variants | List of language codes (e.g., en fr de) |
| AddDefaultCharset | Sets default charset for content negotiation | Character set name (e.g., UTF-8) |
Example: Content Negotiation Configuration
<IfModule mod_negotiation.c>
Options +MultiViews
LanguagePriority en fr de
AddDefaultCharset UTF-8
</IfModule>
MultiViews can lead to unexpected behavior if not configured carefully.
11. Testing Content Negotiation
Example: Testing content negotiation with curl
curl -H "Accept-Language: en-US" http://example.com/resource
curl -H "Accept-Encoding: gzip" http://example.com/resource
curl -H "Accept: text/html" http://example.com/resource
| Header | Description | Usage |
|---|---|---|
| Accept | Specifies the MIME types that are acceptable for the response | Used by clients to indicate preferred content types |
| Accept-Language | Indicates the language that the client prefers | Helps server select localized content |
| Accept-Encoding | Indicates which content encoding (e.g., gzip) the client supports | Used for compression negotiation |
curl -v to inspect the actual response headers and verify content negotiation behavior.
12. Debugging Negotiation Issues
Example: Enabling Content Negotiation Logs
<IfModule mod_negotiation.c>
NegotiationLog /var/log/apache2/negotiation.log
</IfModule>
| Directive | Description | Default |
|---|---|---|
| NegotiationLog | Specifies the file to log negotiation decisions | None |
NegotiationLog directive is available in Apache 2.4 and later.