How to Handle Response Headers with Curl
HTTP response headers contain crucial metadata about web responses, including content type, server information, caching directives, and security headers. Understanding how to capture and analyze these headers with curl is essential for effective web scraping, API testing, and debugging web applications.
Understanding HTTP Response Headers
Response headers provide valuable information about the server's response, including: - Content-Type: The media type of the response body - Content-Length: Size of the response body in bytes - Set-Cookie: Cookie information for session management - Location: Redirect destination for 3xx status codes - Cache-Control: Caching directives - Server: Information about the web server - Date: Timestamp when the response was generated
Basic Header Display with curl
Display Headers Only
Use the -I
or --head
flag to retrieve only the response headers:
curl -I https://httpbin.org/get
This sends a HEAD request and displays only the headers:
HTTP/2 200
date: Wed, 19 Jul 2025 10:30:45 GMT
content-type: application/json
content-length: 314
server: gunicorn/19.9.0
access-control-allow-origin: *
access-control-allow-credentials: true
Include Headers with Response Body
Use the -i
or --include
flag to display headers along with the response body:
curl -i https://httpbin.org/get
This shows both headers and content in a single output.
Advanced Header Handling Techniques
Save Headers to a File
Use the -D
or --dump-header
option to save headers to a file:
curl -D headers.txt https://httpbin.org/get
The headers will be saved to headers.txt
while the response body is displayed normally.
Output Headers to Separate Files
# Save headers and body to different files
curl -D response_headers.txt -o response_body.html https://example.com
Extract Specific Headers
Use grep to filter specific headers:
curl -I https://httpbin.org/get | grep -i content-type
Output:
content-type: application/json
Parsing Headers in Scripts
Bash Script Example
#!/bin/bash
# Function to extract header value
get_header() {
local url=$1
local header_name=$2
curl -s -I "$url" | grep -i "^$header_name:" | cut -d' ' -f2- | tr -d '\r'
}
# Usage examples
url="https://httpbin.org/get"
content_type=$(get_header "$url" "content-type")
server=$(get_header "$url" "server")
echo "Content-Type: $content_type"
echo "Server: $server"
Python Script for Header Processing
import subprocess
import re
def get_response_headers(url):
"""Extract all response headers using curl"""
result = subprocess.run(
['curl', '-s', '-I', url],
capture_output=True,
text=True
)
headers = {}
for line in result.stdout.split('\n'):
if ':' in line:
key, value = line.split(':', 1)
headers[key.strip().lower()] = value.strip()
return headers
# Usage
url = "https://httpbin.org/get"
headers = get_response_headers(url)
print(f"Content-Type: {headers.get('content-type', 'Not found')}")
print(f"Server: {headers.get('server', 'Not found')}")
print(f"Date: {headers.get('date', 'Not found')}")
JavaScript/Node.js Implementation
const { exec } = require('child_process');
function getResponseHeaders(url) {
return new Promise((resolve, reject) => {
exec(`curl -s -I "${url}"`, (error, stdout, stderr) => {
if (error) {
reject(error);
return;
}
const headers = {};
const lines = stdout.split('\n');
lines.forEach(line => {
if (line.includes(':')) {
const [key, ...valueParts] = line.split(':');
headers[key.trim().toLowerCase()] = valueParts.join(':').trim();
}
});
resolve(headers);
});
});
}
// Usage
(async () => {
try {
const headers = await getResponseHeaders('https://httpbin.org/get');
console.log('Content-Type:', headers['content-type']);
console.log('Server:', headers['server']);
console.log('Date:', headers['date']);
} catch (error) {
console.error('Error:', error);
}
})();
Handling Specific Header Scenarios
Following Redirects and Capturing Headers
# Follow redirects and show headers for each step
curl -I -L https://httpbin.org/redirect/3
The -L
flag follows redirects, and you'll see headers for each redirect step.
Handling Authentication Headers
# Check authentication requirements
curl -I https://httpbin.org/basic-auth/user/pass
# With authentication
curl -I -u user:pass https://httpbin.org/basic-auth/user/pass
Checking Cache Headers
# Extract cache-related headers
curl -I https://httpbin.org/cache/60 | grep -E "(cache-control|expires|etag|last-modified)"
Advanced Header Analysis
Check for Security Headers
#!/bin/bash
check_security_headers() {
local url=$1
echo "Security Headers Analysis for: $url"
echo "========================================"
headers=$(curl -s -I "$url")
# Check for important security headers
echo "Strict-Transport-Security: $(echo "$headers" | grep -i "strict-transport-security" || echo "Missing")"
echo "Content-Security-Policy: $(echo "$headers" | grep -i "content-security-policy" || echo "Missing")"
echo "X-Frame-Options: $(echo "$headers" | grep -i "x-frame-options" || echo "Missing")"
echo "X-Content-Type-Options: $(echo "$headers" | grep -i "x-content-type-options" || echo "Missing")"
}
check_security_headers "https://example.com"
Monitor Header Changes
#!/bin/bash
# Monitor headers over time
monitor_headers() {
local url=$1
local interval=${2:-60}
while true; do
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$timestamp] Checking headers for $url"
curl -s -I "$url" | grep -E "(server|date|content-length)" >> header_log.txt
echo "---" >> header_log.txt
sleep $interval
done
}
monitor_headers "https://api.example.com/status" 300
Troubleshooting Common Issues
Handle Different HTTP Versions
# Force HTTP/1.1
curl -I --http1.1 https://example.com
# Force HTTP/2
curl -I --http2 https://example.com
Deal with Malformed Headers
# More lenient parsing
curl -I --ignore-content-length https://problematic-site.com
Debug Header Issues
# Verbose output for debugging
curl -v -I https://example.com 2>&1 | grep -E "(> |< )"
Best Practices for Header Handling
- Always Check Status Codes: Parse the first line to understand response status
- Handle Case Sensitivity: HTTP headers are case-insensitive; normalize when processing
- Account for Multiple Values: Some headers can appear multiple times
- Set Timeouts: Use
--max-time
to prevent hanging requests - Follow Redirects Carefully: Use
-L
but be aware of redirect loops
Production-Ready Header Parser
#!/bin/bash
parse_response_headers() {
local url=$1
local timeout=${2:-30}
local max_redirects=${3:-5}
# Create temporary file for headers
local header_file=$(mktemp)
# Make request with error handling
if curl -s -I -L \
--max-time "$timeout" \
--max-redirs "$max_redirects" \
-D "$header_file" \
"$url" > /dev/null; then
# Parse status code
local status=$(head -n1 "$header_file" | cut -d' ' -f2)
echo "Status: $status"
# Extract common headers
echo "Content-Type: $(grep -i '^content-type:' "$header_file" | cut -d' ' -f2- | tr -d '\r')"
echo "Content-Length: $(grep -i '^content-length:' "$header_file" | cut -d' ' -f2- | tr -d '\r')"
echo "Server: $(grep -i '^server:' "$header_file" | cut -d' ' -f2- | tr -d '\r')"
else
echo "Error: Failed to retrieve headers from $url"
rm -f "$header_file"
return 1
fi
# Cleanup
rm -f "$header_file"
}
# Usage
parse_response_headers "https://httpbin.org/get"
Integration with Web Scraping Workflows
When building web scraping applications, response headers provide critical information for:
- Rate Limiting: Check
X-RateLimit-*
headers - Content Validation: Verify
Content-Type
before parsing - Caching Strategy: Use
Cache-Control
andETag
headers - Authentication Status: Monitor authentication-related headers
While curl excels at command-line header analysis, modern web scraping tools like Puppeteer for handling browser sessions or monitoring network requests in Puppeteer provide more sophisticated header handling capabilities for JavaScript-heavy applications.
Conclusion
Mastering curl's header handling capabilities is essential for web developers, system administrators, and security professionals. Whether you're debugging API responses, monitoring web services, or building automated testing scripts, the techniques covered in this guide provide a solid foundation for working with HTTP response headers effectively.
Remember to combine header analysis with proper error handling, timeout management, and security considerations to build robust applications that can handle real-world web interactions reliably.