HTTP.Headers (http_fetch v0.8.0)
HTTP headers processing and manipulation utilities.
This module provides a comprehensive API for working with HTTP headers, including case-insensitive lookups, header normalization, Content-Type parsing, and a default User-Agent generator.
Features
- Case-insensitive operations: All header name comparisons are case-insensitive
- Header normalization: Converts header names to Title-Case format
- Multiple headers: Support for multiple values for the same header name
- Content-Type parsing: Extract media type and parameters
- Default User-Agent: Automatically generated based on runtime environment
Basic Usage
# Create headers
headers = HTTP.Headers.new([
{"Content-Type", "application/json"},
{"Authorization", "Bearer token"}
])
# Get header value (case-insensitive)
content_type = HTTP.Headers.get(headers, "content-type")
# => "application/json"
# Set/update header
headers = HTTP.Headers.set(headers, "Accept", "application/json")
# Set only if not present
headers = HTTP.Headers.set_default(headers, "User-Agent", "CustomAgent/1.0")
# Add multiple values for same header
headers = HTTP.Headers.add(headers, "Accept", "text/html")
values = HTTP.Headers.get_all(headers, "Accept")
# => ["application/json", "text/html"]Content-Type Parsing
{media_type, params} =
HTTP.Headers.parse_content_type("application/json; charset=utf-8")
# => {"application/json", %{"charset" => "utf-8"}}User-Agent
The library provides a default User-Agent string that includes:
- Operating system information
- System architecture
- OTP version
- BEAM version
- Elixir version
- Library version
Example User-Agent:
"Mozilla/5.0 (macOS; x86_64-apple-darwin24.6.0) OTP/27 BEAM/15.1 Elixir/1.18.3 http_fetch/0.5.0"Access the default User-Agent:
user_agent = HTTP.Headers.user_agent()
Summary
Functions
Adds a new header value without removing existing headers with the same name.
Removes a header by name (case-insensitive).
Formats headers for display (useful for debugging).
Converts a map of headers to a HTTP.Headers struct.
Gets a header value by name (case-insensitive).
Gets all header values for a given header name (case-insensitive).
Checks if a header exists (case-insensitive).
Merges two HTTP.Headers structs, with the second taking precedence.
Creates a new HTTP.Headers struct.
Normalizes header names to title case (e.g., "content-type" becomes "Content-Type").
Parses a header string into a {name, value} tuple.
Parses a Content-Type header to extract the media type and parameters.
Sets a header value, replacing any existing header with the same name.
Sets a header only if it doesn't already exist (case-insensitive).
Returns the underlying list of headers.
Converts a HTTP.Headers struct to a map for easy lookup.
Returns the default User-Agent string used by the library.
Types
Functions
Adds a new header value without removing existing headers with the same name.
Examples
iex> headers = HTTP.Headers.new([{"Accept", "text/html"}])
iex> updated = HTTP.Headers.add(headers, "Accept", "application/json")
iex> HTTP.Headers.get_all(updated, "Accept")
["text/html", "application/json"]
iex> headers = HTTP.Headers.new()
iex> updated = HTTP.Headers.add(headers, "Authorization", "Bearer token")
iex> HTTP.Headers.get(updated, "Authorization")
"Bearer token"
iex> headers = HTTP.Headers.new([{"Content-Type", "text/plain"}])
iex> updated = HTTP.Headers.add(headers, "Authorization", "Bearer token")
iex> HTTP.Headers.get(updated, "Authorization")
"Bearer token"
iex> HTTP.Headers.get(updated, "Content-Type")
"text/plain"
Removes a header by name (case-insensitive).
Examples
iex> headers = HTTP.Headers.new([{"Content-Type", "application/json"}, {"Authorization", "Bearer token"}])
iex> updated = HTTP.Headers.delete(headers, "content-type")
iex> HTTP.Headers.has?(updated, "content-type")
false
iex> HTTP.Headers.has?(updated, "Authorization")
true
Formats headers for display (useful for debugging).
Examples
iex> headers = HTTP.Headers.new([{"Content-Type", "application/json"}, {"Authorization", "Bearer token"}])
iex> HTTP.Headers.format(headers)
"Content-Type: application/jsonAuthorization: Bearer token"
Converts a map of headers to a HTTP.Headers struct.
Examples
iex> headers = HTTP.Headers.from_map(%{"content-type" => "application/json", "authorization" => "Bearer token"})
iex> {"Content-Type", "application/json"} in headers.headers
true
iex> {"Authorization", "Bearer token"} in headers.headers
true
Gets a header value by name (case-insensitive).
Examples
iex> headers = HTTP.Headers.new([{"Content-Type", "application/json"}])
iex> HTTP.Headers.get(headers, "content-type")
"application/json"
iex> headers = HTTP.Headers.new([{"Authorization", "Bearer token"}])
iex> HTTP.Headers.get(headers, "missing")
nil
Gets all header values for a given header name (case-insensitive).
Examples
iex> headers = HTTP.Headers.new([{"Accept", "text/html"}, {"Accept", "application/json"}])
iex> HTTP.Headers.get_all(headers, "accept")
["text/html", "application/json"]
iex> headers = HTTP.Headers.new([{"Content-Type", "application/json"}, {"Authorization", "Bearer token"}])
iex> HTTP.Headers.get_all(headers, "content-type")
["application/json"]
iex> headers = HTTP.Headers.new([{"Content-Type", "application/json"}])
iex> HTTP.Headers.get_all(headers, "missing")
[]
Checks if a header exists (case-insensitive).
Examples
iex> headers = HTTP.Headers.new([{"Content-Type", "application/json"}])
iex> HTTP.Headers.has?(headers, "content-type")
true
iex> headers = HTTP.Headers.new([{"Content-Type", "application/json"}])
iex> HTTP.Headers.has?(headers, "missing")
false
Merges two HTTP.Headers structs, with the second taking precedence.
Examples
iex> headers1 = HTTP.Headers.new([{"Content-Type", "text/plain"}])
iex> headers2 = HTTP.Headers.new([{"Content-Type", "application/json"}])
iex> merged = HTTP.Headers.merge(headers1, headers2)
iex> HTTP.Headers.get(merged, "Content-Type")
"application/json"
iex> headers1 = HTTP.Headers.new([{"A", "1"}])
iex> headers2 = HTTP.Headers.new([{"B", "2"}])
iex> merged = HTTP.Headers.merge(headers1, headers2)
iex> HTTP.Headers.get(merged, "A")
"1"
iex> HTTP.Headers.get(merged, "B")
"2"
@spec new(headers_list()) :: t()
Creates a new HTTP.Headers struct.
Examples
iex> HTTP.Headers.new([{"Content-Type", "application/json"}])
%HTTP.Headers{headers: [{"Content-Type", "application/json"}]}
iex> HTTP.Headers.new()
%HTTP.Headers{headers: []}
Normalizes header names to title case (e.g., "content-type" becomes "Content-Type").
Examples
iex> HTTP.Headers.normalize_name("content-type")
"Content-Type"
iex> HTTP.Headers.normalize_name("AUTHORIZATION")
"Authorization"
Parses a header string into a {name, value} tuple.
Examples
iex> HTTP.Headers.parse("Content-Type: application/json")
{"Content-Type", "application/json"}
iex> HTTP.Headers.parse("Authorization: Bearer token123")
{"Authorization", "Bearer token123"}
Parses a Content-Type header to extract the media type and parameters.
Examples
iex> HTTP.Headers.parse_content_type("application/json; charset=utf-8")
{"application/json", %{"charset" => "utf-8"}}
iex> HTTP.Headers.parse_content_type("text/plain")
{"text/plain", %{}}
Sets a header value, replacing any existing header with the same name.
Examples
iex> headers = HTTP.Headers.new([{"Content-Type", "text/plain"}])
iex> updated = HTTP.Headers.set(headers, "Content-Type", "application/json")
iex> HTTP.Headers.get(updated, "Content-Type")
"application/json"
iex> headers = HTTP.Headers.new()
iex> updated = HTTP.Headers.set(headers, "Authorization", "Bearer token")
iex> HTTP.Headers.get(updated, "Authorization")
"Bearer token"
Sets a header only if it doesn't already exist (case-insensitive).
Examples
iex> headers = HTTP.Headers.new([{"Content-Type", "text/plain"}])
iex> updated = HTTP.Headers.set_default(headers, "Content-Type", "application/json")
iex> HTTP.Headers.get(updated, "Content-Type")
"text/plain"
iex> headers = HTTP.Headers.new([{"Accept", "text/html"}])
iex> updated = HTTP.Headers.set_default(headers, "User-Agent", "CustomAgent/1.0")
iex> HTTP.Headers.get(updated, "User-Agent")
"CustomAgent/1.0"
iex> headers = HTTP.Headers.new()
iex> updated = HTTP.Headers.set_default(headers, "Authorization", "Bearer token")
iex> HTTP.Headers.get(updated, "Authorization")
"Bearer token"
@spec to_list(t()) :: headers_list()
Returns the underlying list of headers.
Examples
iex> headers = HTTP.Headers.new([{"Content-Type", "application/json"}])
iex> HTTP.Headers.to_list(headers)
[{"Content-Type", "application/json"}]
Converts a HTTP.Headers struct to a map for easy lookup.
Examples
iex> headers = HTTP.Headers.new([{"Content-Type", "application/json"}, {"Authorization", "Bearer token"}])
iex> HTTP.Headers.to_map(headers)
%{"content-type" => "application/json", "authorization" => "Bearer token"}
@spec user_agent() :: String.t()
Returns the default User-Agent string used by the library.
Examples
iex> user_agent = HTTP.Headers.user_agent()
iex> user_agent =~ "Mozilla/5.0"
true
iex> user_agent =~ "http_fetch/"
true