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
ETagheader 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
