FastAPI RFC 3230 Digest Header Middleware
Introduction
This package provides a FastAPI middleware that enforces RFC 3230 Digest headers for HTTP requests. It validates the Digest header against the request body, ensuring message integrity and allowing you to specify which digest algorithms are accepted.
Installation
Install via pip:
pip install fastapi-rfc3230-digest-header-middleware
Usage Example
Add the middleware to your FastAPI app:
from fastapi import FastAPI, Request
from fastapi_rfc3230_digest_header_middleware import Middleware
app = FastAPI()
app.add_middleware(Middleware)
@app.post("/echo")
async def echo(request: Request):
body = await request.body()
return body
This will require all POST requests to /echo to include a valid Digest
header matching the request body. If the client sends an invalid request, the
server will respond with a 422 Unprocessable Entity error and include details
about the validation failure. The response will also include a Want-Digest header
indicating the accepted digest algorithms.
Client side
Sending requests with Digest Header
The client must compute the digest of the request body using one of the accepted
algorithms and include it in the Digest header. For example, to compute a
SHA-256 digest in Python you can use the rfc3230-digest-headers package:
from rfc3230_digest_headers import create_digest
body = b"Hello, World!"
digest_header = create_digest(body)
headers = {"Digest": digest_header.header_value}
if you want to manually create the header, you can do it like this:
import hashlib
import base64
body = b"Hello, World!"
sha256_digest = hashlib.sha256(body).digest()
digest_value = base64.b64encode(sha256_digest).decode('utf-8')
digest_header = f"SHA-256={digest_value}"
headers = {"Digest": digest_header}
Client side handling of Want-Digest Header
The client should also be able to handle the Want-Digest header in case of a 422 response. The rfc3230-digest-headers package can help with parsing this header as well.
from rfc3230_digest_headers import create_digest
want_digest_header = response.headers.get("Want-Digest", "")
# The `digest_value` will include the appropriate digests according to the server's Want-Digest header
digest_header = create_digest(body, want_digest_header)
Configuration
You can customize which digest algorithms are allowed or provide a custom callback to extract the bytes to validate:
Allow Only Specific Algorithms
from fastapi import FastAPI, Request
from fastapi_rfc3230_digest_header_middleware import Middleware
from rfc3230_digest_headers import DigestHeaderAlgorithm
qvalues = {
DigestHeaderAlgorithm.SHA256: None, # allow SHA-256
DigestHeaderAlgorithm.MD5: 0.0, # explicitly reject MD5
}
app = FastAPI()
app.add_middleware(Middleware, qvalues=qvalues)
@app.post("/echo")
async def echo(request: Request):
body = await request.body()
return body
Custom Instance Bytes Callback
The instance are the bytes the server and client agreed on to include in the
digest. By default, this is the entire request body, but instance of a request
may not always be the request body. You can provide a custom callback to extract
the bytes to validate:
async def get_instance_bytes(request: Request) -> bytes:
# Default instance bytes logic
return await request.body()
app = FastAPI()
app.add_middleware(Middleware, instance_bytes_callback=get_instance_bytes)
License
MIT License
Metadata
Release files for fastapi-rfc3230-digest-header-middleware 1.0.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fastapi_rfc3230_digest_header_middleware-1.0.3.tar.gz | 4.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fastapi_rfc3230_digest_header_middleware-1.0.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 10.0 kB
Release files / fastapi_rfc3230_digest_header_middleware-1.0.3.tar.gz
| Download URL | fastapi_rfc3230_digest_header_middleware-1.0.3.tar.gz |
|---|---|
| Size | 4.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a49e008c436ed531417d00abf941a0965abb2789e506c66458ebfcfab9ffae9b
|
|
BLAKE2b-256 checksum How to use checksums |
ae83410becf3ff1ce8c6895d83a54bab8c22ce6eacda85c06cd6f0a4b330a7ad
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 25, 2025.
Transparency logRelease files / fastapi_rfc3230_digest_header_middleware-1.0.3-py3-none-any.whl
| Download URL | fastapi_rfc3230_digest_header_middleware-1.0.3-py3-none-any.whl |
|---|---|
| Size | 5.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6ac39840c8cc25fcf89b6c222578e30637f77ba75542c1af21be0b3eadc7c8e6
|
|
BLAKE2b-256 checksum How to use checksums |
0c0a2254909a340dcb1b2cd355a63be1eae9d39a6ba80289685637b2ba11f2af
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 25, 2025.
Transparency log