Home / References / ESP32 Library / WebServer Library
Description
The responseHeader()
method is used to retrieve HTTP response header values that have been previously set using the sendHeader()
method. This method allows you to access specific header information that will be sent to clients in the HTTP response. It’s particularly useful for debugging HTTP responses, implementing conditional logic based on response headers, logging server activity, and validating that the correct headers are being sent to clients. The method provides two ways to access headers: by name (case-insensitive) or by index position, making it flexible for different programming scenarios. This functionality is essential for creating robust web applications that need to inspect or modify response headers before they are sent to the client.
Syntax and Usage
The responseHeader()
method can be used in two different ways:
- By header name:
server.responseHeader(headerName)
– Retrieves the value of a specific response header by its name (case-insensitive). Returns an empty string if the header doesn’t exist. - By header index:
server.responseHeader(index)
– Retrieves the value of a response header at a specific index position. Useful for iterating through all response headers.
For practical applications and examples of this method, please consult the “Example Code” section on this page. This section provides comprehensive guidance to help you better understand and apply the method effectively.
Arguments
This webpage is part of the Comprehensive Guide to the ESP32 Arduino Core Library, accessible on AvantMaker.com.
- headerName (String) – The name of the HTTP response header to retrieve. This is case-insensitive, so “Content-Type”, “content-type”, and “CONTENT-TYPE” will all match the same header.
- index (int) – The zero-based index of the response header to retrieve. Use with
responseHeaders()
method to determine the total number of available headers before accessing by index.
Return Value
The responseHeader()
method returns a const String&
containing the value of the requested response header. If the header is not found (when using header name) or if the index is out of range, the method returns an empty string (“”).
Example Code
Response Header Inspector and Validator
This example demonstrates how to use the responseHeader()
method to inspect and validate HTTP response headers before they are sent to clients. The server shows how to access headers by name and index, and provides detailed information about header management for debugging and quality assurance purposes.
How to use this example: Upload this code to your ESP32 and replace the WiFi credentials. After connecting, access different endpoints to see header inspection in action: http://ESP32_IP/
for the main dashboard, http://ESP32_IP/api/secure
for security headers, http://ESP32_IP/api/cached
for caching headers, and http://ESP32_IP/inspect
for detailed header analysis. The server logs header information to both the Serial Monitor and the web response, making it easy to debug and validate response configurations.
/*
* Author: Avant Maker
* Date: June 18, 2025
* Version: 1.0
* License: MIT
*
* Description:
* This example demonstrates how to use the responseHeader() method to
* inspect and validate HTTP response headers before they are sent to clients.
* The server shows how to access headers by name and index, and provides
* detailed information about header management for debugging and quality
* assurance purposes.
*
* How to use this example:
* Upload this code to your ESP32 and replace the WiFi credentials.
* After connecting, access different endpoints to see header inspection in action:
* http://ESP32_IP/ for the main dashboard, http://ESP32_IP/api/secure for
* security headers, http://ESP32_IP/api/cached for caching headers, and
* http://ESP32_IP/inspect for detailed header analysis. The server logs header
* information to both the Serial Monitor and the web response.
*
* Code Source:
* This example code is sourced from the Comprehensive Guide
* to the ESP32 Arduino Core Library, accessible on AvantMaker.com.
* For additional code examples and in-depth documentation related to
* the ESP32 Arduino Core Library, please visit:
*
* https://avantmaker.com/home/all-about-esp32-arduino-core-library/
*
* AvantMaker.com, your premier destination for all things
* DIY, AI, IoT, Smart Home, and STEM projects. We are dedicated
* to empowering makers, learners, and enthusiasts with
* the resources they need to bring their nnovative ideas to life.
*/
#include <WiFi.h>
#include <WebServer.h>
const char* ssid = "your_SSID"; // Replace with your Wi-Fi SSID
const char* password = "your_PASSWORD"; // Replace with your Wi-Fi password
WebServer server(80);
// Statistics for header tracking
struct HeaderStats {
unsigned long totalRequests = 0;
unsigned long totalResponseHeaders = 0;
String mostCommonHeader = "";
int mostCommonCount = 0;
} stats;
void logHeaderInspection(const String& endpoint) {
Serial.println("=== Response Header Inspection ===");
Serial.println("Endpoint: " + endpoint);
Serial.println("Total Response Headers: " + String(server.responseHeaders()));
// Log all headers by index
for (int i = 0; i < server.responseHeaders(); i++) {
String headerName = server.responseHeaderName(i);
String headerValue = server.responseHeader(i);
Serial.println("Header[" + String(i) + "]: " + headerName + " = " + headerValue);
}
// Check specific headers by name
String contentType = server.responseHeader("Content-Type");
if (contentType.length() > 0) {
Serial.println("Content-Type found: " + contentType);
}
Serial.println("==================================");
}
void handleRoot() {
// Add custom headers for this response
server.sendHeader("X-Server-Info", "ESP32 Response Header Inspector");
server.sendHeader("X-Version", "1.0");
server.sendHeader("X-Request-ID", String(millis()));
server.sendHeader("X-Build-Date", "2025-06-18");
// Inspect headers before sending response
logHeaderInspection("/");
String html = "<!DOCTYPE html><html><head>";
html += "<title>AvantMaker ESP32 Response Header Inspector</title>";
html += "<meta name='viewport' content='width=device-width, initial-scale=1'>";
html += "<style>";
html += "body{font-family:Arial,sans-serif;margin:20px;background:#f8f9fa;}";
html += ".container{max-width:900px;margin:0 auto;background:white;padding:30px;border-radius:10px;box-shadow:0 2px 10px rgba(0,0,0,0.1);}";
html += ".header-info{background:#e3f2fd;padding:20px;border-radius:8px;margin:20px 0;border-left:4px solid #1976d2;}";
html += ".button{background:#1976d2;color:white;padding:12px 24px;border:none;border-radius:6px;cursor:pointer;margin:8px;text-decoration:none;display:inline-block;}";
html += ".button:hover{background:#1565c0;}";
html += ".stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:15px;margin:20px 0;}";
html += ".stat-card{background:#f5f5f5;padding:15px;border-radius:6px;text-align:center;}";
html += ".stat-number{font-size:1.5em;font-weight:bold;color:#1976d2;}";
html += "</style></head><body>";
html += "<div class='container'>";
html += "<h1>AvantMaker ESP32 Response Header Inspector</h1>";
html += "<p>This tool demonstrates the responseHeader() method for inspecting HTTP response headers.</p>";
// Display current response headers using responseHeader() method
html += "<div class='header-info'>";
html += "<h3>Current Response Headers (accessed by name):</h3>";
html += "<ul>";
// Access specific headers by name using responseHeader()
String serverInfo = server.responseHeader("X-Server-Info");
if (serverInfo.length() > 0) {
html += "<li><strong>X-Server-Info:</strong> " + serverInfo + "</li>";
}
String version = server.responseHeader("X-Version");
if (version.length() > 0) {
html += "<li><strong>X-Version:</strong> " + version + "</li>";
}
String requestId = server.responseHeader("X-Request-ID");
if (requestId.length() > 0) {
html += "<li><strong>X-Request-ID:</strong> " + requestId + "</li>";
}
html += "</ul></div>";
// Display statistics
html += "<div class='stats'>";
html += "<div class='stat-card'><div class='stat-number'>" + String(server.responseHeaders()) + "</div>Response Headers</div>";
html += "<div class='stat-card'><div class='stat-number'>" + String(stats.totalRequests) + "</div>Total Requests</div>";
html += "<div class='stat-card'><div class='stat-number'>" + String(millis()/1000) + "s</div>Uptime</div>";
html += "</div>";
// Test endpoints
html += "<h3>Test Different Header Configurations:</h3>";
html += "<a href='/api/secure' class='button'>Security Headers</a>";
html += "<a href='/api/cached' class='button'>Caching Headers</a>";
html += "<a href='/inspect' class='button'>Header Inspector</a>";
html += "<a href='/api/cors' class='button'>CORS Headers</a>";
html += "</div></body></html>";
stats.totalRequests++;
server.send(200, "text/html", html);
}
void handleSecureAPI() {
// Add comprehensive security headers
server.sendHeader("X-Content-Type-Options", "nosniff");
server.sendHeader("X-Frame-Options", "DENY");
server.sendHeader("X-XSS-Protection", "1; mode=block");
server.sendHeader("Strict-Transport-Security", "max-age=31536000; includeSubDomains");
server.sendHeader("Content-Security-Policy", "default-src 'self'; script-src 'self' 'unsafe-inline'");
server.sendHeader("Referrer-Policy", "strict-origin-when-cross-origin");
// Inspect security headers before sending
logHeaderInspection("/api/secure");
String json = "{";
json += "\"message\":\"Secure API endpoint with comprehensive security headers\",";
json += "\"headerCount\":" + String(server.responseHeaders()) + ",";
json += "\"securityHeaders\":[";
// Use responseHeader() to verify security headers are set
if (server.responseHeader("X-Content-Type-Options").length() > 0) {
json += "\"X-Content-Type-Options\",";
}
if (server.responseHeader("X-Frame-Options").length() > 0) {
json += "\"X-Frame-Options\",";
}
if (server.responseHeader("Strict-Transport-Security").length() > 0) {
json += "\"Strict-Transport-Security\",";
}
// Remove trailing comma if any headers were added
if (json.endsWith(",")) {
json = json.substring(0, json.length() - 1);
}
json += "],";
json += "\"timestamp\":" + String(millis()) + ",";
json += "\"cspPolicy\":\"" + server.responseHeader("Content-Security-Policy") + "\"";
json += "}";
stats.totalRequests++;
server.send(200, "application/json", json);
}
void handleCachedAPI() {
// Add caching headers
server.sendHeader("Cache-Control", "public, max-age=3600, must-revalidate");
server.sendHeader("Expires", "Thu, 18 Jun 2025 12:00:00 GMT");
server.sendHeader("Last-Modified", "Wed, 17 Jun 2025 10:00:00 GMT");
server.sendHeader("ETag", "\"esp32-cached-v1-" + String(millis()) + "\"");
server.sendHeader("Vary", "Accept-Encoding, User-Agent");
logHeaderInspection("/api/cached");
String json = "{";
json += "\"message\":\"Cached API response with optimized headers\",";
json += "\"headerCount\":" + String(server.responseHeaders()) + ",";
json += "\"cacheControl\":\"" + server.responseHeader("Cache-Control") + "\",";
json += "\"etag\":\"" + server.responseHeader("ETag") + "\",";
json += "\"expires\":\"" + server.responseHeader("Expires") + "\",";
json += "\"lastModified\":\"" + server.responseHeader("Last-Modified") + "\",";
json += "\"timestamp\":" + String(millis());
json += "}";
stats.totalRequests++;
server.send(200, "application/json", json);
}
void handleCORSAPI() {
// Add CORS headers
server.sendHeader("Access-Control-Allow-Origin", "*");
server.sendHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
server.sendHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Requested-With");
server.sendHeader("Access-Control-Max-Age", "86400");
server.sendHeader("Access-Control-Expose-Headers", "X-Total-Count, X-Page-Count");
logHeaderInspection("/api/cors");
String json = "{";
json += "\"message\":\"CORS-enabled API endpoint\",";
json += "\"headerCount\":" + String(server.responseHeaders()) + ",";
json += "\"allowOrigin\":\"" + server.responseHeader("Access-Control-Allow-Origin") + "\",";
json += "\"allowMethods\":\"" + server.responseHeader("Access-Control-Allow-Methods") + "\",";
json += "\"maxAge\":\"" + server.responseHeader("Access-Control-Max-Age") + "\",";
json += "\"timestamp\":" + String(millis());
json += "}";
stats.totalRequests++;
server.send(200, "application/json", json);
}
void handleInspect() {
// Add inspection headers
server.sendHeader("X-Inspector", "Active");
server.sendHeader("X-Debug-Mode", "Enabled");
server.sendHeader("X-Response-Time", String(millis()) + "ms");
logHeaderInspection("/inspect");
String response = "Response Header Detailed Analysis\n";
response += "==================================\n\n";
int headerCount = server.responseHeaders();
response += "Total Response Headers: " + String(headerCount) + "\n\n";
// Iterate through all headers using both methods
response += "Headers accessed by INDEX:\n";
response += "--------------------------\n";
for (int i = 0; i < headerCount; i++) {
String headerName = server.responseHeaderName(i);
String headerValue = server.responseHeader(i);
response += "[" + String(i) + "] " + headerName + ": " + headerValue + "\n";
}
response += "\nHeaders accessed by NAME:\n";
response += "-------------------------\n";
// Test specific headers by name
String inspector = server.responseHeader("X-Inspector");
if (inspector.length() > 0) {
response += "X-Inspector: " + inspector + "\n";
}
String debugMode = server.responseHeader("X-Debug-Mode");
if (debugMode.length() > 0) {
response += "X-Debug-Mode: " + debugMode + "\n";
}
String responseTime = server.responseHeader("X-Response-Time");
if (responseTime.length() > 0) {
response += "X-Response-Time: " + responseTime + "\n";
}
// Test case sensitivity
response += "\nCase Sensitivity Test:\n";
response += "----------------------\n";
response += "x-inspector (lowercase): " + server.responseHeader("x-inspector") + "\n";
response += "X-INSPECTOR (uppercase): " + server.responseHeader("X-INSPECTOR") + "\n";
response += "X-Inspector (mixed case): " + server.responseHeader("X-Inspector") + "\n";
response += "\nNon-existent header test: '" + server.responseHeader("Non-Existent-Header") + "'\n";
stats.totalRequests++;
server.send(200, "text/plain", response);
}
void setup() {
Serial.begin(115200);
// Connect to WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi...");
}
Serial.println("WiFi connected!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
// Set up route handlers
server.on("/", handleRoot);
server.on("/api/secure", handleSecureAPI);
server.on("/api/cached", handleCachedAPI);
server.on("/api/cors", handleCORSAPI);
server.on("/inspect", handleInspect);
// Start server
server.begin();
Serial.println("HTTP server started");
Serial.println("Response Header Inspector available at: http://" + WiFi.localIP().toString());
Serial.println("Check Serial Monitor for detailed header inspection logs");
}
void loop() {
server.handleClient();
// Optional: Print periodic statistics
static unsigned long lastPrint = 0;
if (millis() - lastPrint > 60000) { // Every 60 seconds
lastPrint = millis();
Serial.println("Stats - Total Requests: " + String(stats.totalRequests) +
", Free Heap: " + String(ESP.getFreeHeap()));
}
}
For more ESP32 development resources and tutorials, visit AvantMaker.com
ESP32 Library Index
- ESP32 WiFi Library
- ESP32 WiFiClient Library
- ESP32 HTTPClient Library
- ESP32 WiFiClientSecure Library
- ESP32 AsyncUDP Librarry
- ESP32 WebServer Library
- Server Operation
- Client Hnadling
- Routing and Handlers
- Authentication
- Request Information
- Request Header Management
- Response Information
- Server Configuration
- Which ESP32 Boards are Recommended for Learners
- How to Copy Codes from AvantMaker.com
- What is SPIFFS and how to upload files to it?
- What is LIttleFS and how to upload files to it?
Ready to experiment and explore more about ESP32? Visit our website’s All About ESP32 Resources Hub, packed with tutorials, guides, and tools to inspire your maker journey. Experiment, explore, and elevate your skills with everything you need to master this powerful microcontroller platform!