How to Mock HTTP Responses to Verify HSTS Headers in Python

This code demonstrates how to use unittest.mock to intercept and capture HTTP response headers, specifically the Strict-Transport-Security header, from a mocked HTTPServer handler for security validation.

Medium Python 3.9+ Aug 9, 2026 Auth & security at scale 13 views 0 copies

Python code

24 lines
Python 3.9+
from http.server import BaseHTTPRequestHandler, HTTPServer
from unittest.mock import patch

class StrictTransportMock(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Strict-Transport-Security", "max-age=31536000; includeSubDomains")
        self.end_headers()
        self.wfile.write(b"Secure response")

    def log_message(self, format, *args):
        pass

def check_hsts_header(handler):
    response_headers = {}
    with patch.object(handler, 'send_header', side_effect=lambda k, v: response_headers.update({k: v})):
        handler.do_GET()
    return response_headers.get("Strict-Transport-Security")

if __name__ == "__main__":
    mock_handler = StrictTransportMock.__new__(StrictTransportMock)
    hsts_value = check_hsts_header(mock_handler)
    print(f"HSTS header: {hsts_value}")
    print(f"Is valid: {'max-age=31536000' in hsts_value and 'includeSubDomains' in hsts_value}")

Output

stdout
HSTS header: max-age=31536000; includeSubDomains
Is valid: True

How it works

The StrictTransportMock class defines a minimal HTTP handler that, when do_GET is invoked, simulates a secure response with an HSTS header. The check_hsts_header function uses patch.object to replace the send_header method on the handler instance, capturing each header key-value pair into a dictionary instead of actually sending them over the wire. This allows you to assert the presence and correctness of the HSTS header without starting a real server. The log_message override suppresses request logging, keeping test output clean. The script instantiates the handler without calling __init__ (via __new__) to avoid the network setup, runs do_GET, and prints whether the HSTS header meets the required max-age and includeSubDomains criteria.

Common mistakes

  • Forgetting to call `end_headers()` in the mock handler, which breaks the header-capture logic.
  • Using `patch` without `object` when patching a method on an instance, causing a TypeError.
  • Not overriding `log_message`, leading to noisy test output from the standard logger.

Variations

  1. Use `requests_mock` to intercept real HTTP calls and inspect response headers in integration tests.
  2. Use `unittest.mock.Mock(wraps=handler)` to automatically forward calls while capturing headers.

Real-world use cases

  • Unit-testing security middleware that must always emit HSTS headers in response to HTTP requests.
  • Verifying that a reverse-proxy or app server configuration sends the correct Strict-Transport-Security header in CI pipelines.
  • Simulating HTTPS responses in a test harness to validate client-side certificate pinning or redirect logic.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Auth & security at scale

Related tutorials and quizzes for this topic.