etag-middleware
HTTP ETag middleware.
Compliant with RFC 9110, 8.8.3. ETag.
Middleware
For a definition of Universal HTTP middleware, see the http-middleware project.
Usage
From the response, calculate the ETag and add it to the ETag
header.
import { etag } from "https://deno.land/x/etag_middleware@$VERSION/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
const middleware = etag();
declare const request: Request;
declare const handler: () => Response;
const response = await middleware(request, handler);
assertEquals(
response.headers.get("etag"),
`W/"<hex:SHA-1:Content-Type::body>"`,
);
yield:
ETag: W/"<hex:SHA-1:Content-Type::body>"
The Default ETag is a hexadecimal representation of the SHA-1 digest of the
response body and Content-Type
.
This is a weak validator.
ETag computation
The ETag is computed from the body and the response header.
By default, it is a hash of the stream of body and specific headers.
This satisfies most of the requirements for a strong validator. However, no single middleware can guarantee that the following requirements will be met:
For example, if the origin server sends the same validator for a representation with a gzip content coding applied as it does for a representation with no content coding, then that validator is weak.
For this reason, the default is to compute as a weak validator.
ETag Strategy
ETag computation strategy.
Name | Type | Default | Description |
---|---|---|---|
weak | boolean |
true |
Wether the etag is weak or not. |
algorithm | "SHA-1" | "SHA-256" | "SHA-384" | "SHA-512" |
"SHA-1" |
Hash algorithm. |
headers | string[] |
["content-type"] |
Semantically significant header related with the representation data. |
Weak
The weak
field specifies whether ETag is a weak validator or not.
Middleware by itself cannot guarantee that it is a strong validator.
This is because the body and Content-Encoding
can be changed by other
processes after the ETag computing.
If immutability can be guaranteed, it can be changed to a strong validator.
import { etag } from "https://deno.land/x/etag_middleware@$VERSION/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
const middleware = etag({ weak: false });
declare const request: Request;
declare const handler: () => Response;
const response = await middleware(request, handler);
assertEquals(response.headers.get("etag"), `"<hex:SHA-1:Content-Type::body>"`);
Algorithm
Specifies the algorithm of the hash function. Default is SHA-1
.
import { etag } from "https://deno.land/x/etag_middleware@$VERSION/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
const middleware = etag({ algorithm: "SHA-256" });
declare const request: Request;
declare const handler: () => Response;
const response = await middleware(request, handler);
assertEquals(
response.headers.get("etag"),
`W/"<hex:SHA-256:Content-Type::body>"`,
);
Headers
Additional metadata to uniquely identify representation data.
Default is ["content-type"]
.
The strong validator requires uniqueness to include metadata such as
Content-Type
in addition to the body text.
By adding a header, a hash value is computed from the stream of the body and the specified header.
import { etag } from "https://deno.land/x/etag_middleware@$VERSION/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
const middleware = etag({ headers: [] });
declare const request: Request;
declare const handler: () => Response;
const response = await middleware(request, handler);
assertEquals(response.headers.get("etag"), `W/"<hex:SHA-256:body>"`);
Effects
Middleware will effect following:
- HTTP Headers
- ETag
Conditions
Middleware will execute only if the following conditions are met:
- Response body is successful(
2xx
) status code - Response body exists
- Response body is readable
ETag
header does not exist in response
API
All APIs can be found in the deno doc.
License
Copyright © 2023-present httpland.
Released under the MIT license