@@ -9,21 +9,20 @@ import crypto from './crypto.js';
99 * Creates a value suitable for the HTTP `Digest` header.
1010 *
1111 * @param {object } options - The options to use.
12- * @param {string|object|Blob|Uint8Array } [options.data] - Input body to be
13- * hashed (typically a request body).
12+ * @param {string|object|Blob|Uint8Array } [options.data] - The data to be
13+ * hashed (a request or response body).
1414 * @param {string } [options.algorithm] - Hash algorithm to use.
1515 * (e.g. 'sha256').
16- * @param {boolean } [options.useMultihash] - Whether to encode via multihash.
17- * If false, the hash will be base64 encoded (non-url).
16+ * @param {boolean } [options.useMultihash=true ] - Whether to encode via
17+ * multihash; if false, the hash will be base64- encoded (non-url).
1818 *
1919 * @returns {Promise<string> } Resolves to `Digest` header value.
2020 */
2121export async function createHeaderValue ( {
2222 data, algorithm = 'sha256' , useMultihash = true
2323} = { } ) {
24- const body = _normalizeData ( data ) ;
2524 const { key, encodedDigest} = await _createHeaderValueComponents ( {
26- body , algorithm, useMultihash
25+ data , algorithm, useMultihash
2726 } ) ;
2827 return `${ key } =${ encodedDigest } ` ;
2928}
@@ -32,7 +31,8 @@ export async function createHeaderValue({
3231 * Verifies the HTTP `Digest` header value against the given HTTP body `data`.
3332 *
3433 * @param {object } options - The options to use.
35- * @param {string|object|Blob } options.data - The data to be verified.
34+ * @param {string|object|Blob|Uint8Array } options.data - The data to be
35+ * verified (a request or response body).
3636 * @param {string } options.headerValue - The digest header value to verify
3737 * the data against.
3838 *
@@ -42,35 +42,21 @@ export async function createHeaderValue({
4242export async function verifyHeaderValue ( { data, headerValue} ) {
4343 try {
4444 const { key, algorithm, encodedDigest} = _parseHeaderValue ( headerValue ) ;
45- const body = _normalizeData ( data ) ;
46- const { encodedDigest : expectedDigest } = await _createHeaderValueComponents (
47- { body , algorithm , useMultihash : key === 'mh' } ) ;
45+ const { encodedDigest : expectedDigest } = await _createHeaderValueComponents ( {
46+ data , algorithm , useMultihash : key === 'mh'
47+ } ) ;
4848 return { verified : encodedDigest === expectedDigest } ;
4949 } catch ( error ) {
5050 return { verified : false , error} ;
5151 }
5252}
5353
54- /**
55- * Creates the digest header components.
56- *
57- * @param {object } options - The options to use.
58- * @param {Blob } options.body - The request body.
59- * @param {string } [options.algorithm] - The hash algorithm to use.
60- * @param {boolean } [options.useMultihash=true] - Whether to serialize digest
61- * using multihash or not.
62- *
63- * @returns {Promise<object> } - The header key and encoded digest in an object.
64- */
6554async function _createHeaderValueComponents ( {
66- body , algorithm = 'sha256' , useMultihash = true
55+ data , algorithm = 'sha256' , useMultihash = true
6756} ) {
6857 if ( algorithm !== 'sha256' ) {
6958 throw new Error ( `Algorithm "${ algorithm } " is not supported.` ) ;
7059 }
71- // `Blob.bytes()` is only available in node.js 22+;
72- // fallback to `Blob.arrayBuffer()`
73- const data = await ( body ?. bytes ?. ( ) ?? body . arrayBuffer ( ) ) ;
7460 const digest = await _getDigest ( { data, algorithm} ) ;
7561 if ( useMultihash ) {
7662 return { key : 'mh' , encodedDigest : _createMultihash ( { digest} ) } ;
@@ -112,25 +98,25 @@ function _parseHeaderValue(headerValue) {
11298}
11399
114100async function _getDigest ( { data, algorithm} ) {
101+ data = await _normalizeData ( data ) ;
115102 if ( algorithm === 'sha256' ) {
116103 return new Uint8Array ( await crypto . subtle . digest ( { name : 'SHA-256' } , data ) ) ;
117104 }
118105 throw new Error ( `Algorithm "${ algorithm } " is not unsupported.` ) ;
119106}
120107
121- // normalize all inputs to a Uint8Array for hashing
122- function _normalizeData ( data ) {
108+ // normalize all inputs to a ` Uint8Array` for hashing
109+ async function _normalizeData ( data ) {
123110 if ( data instanceof Uint8Array ) {
124- return new Blob ( [ /** @type {ArrayBuffer } */ ( data . buffer ) ] ) ;
125- }
126- if ( data instanceof ArrayBuffer ) {
127- return new Blob ( [ data ] ) ;
111+ return data ;
128112 }
129- if ( typeof data === 'string' ) {
130- return new Blob ( [ data ] , { type : 'application/json' } ) ;
113+ if ( data instanceof Blob ) {
114+ // `Blob.bytes()` is only available in node.js 22+;
115+ // fallback to `Blob.arrayBuffer()`
116+ return data ?. bytes ?. ( ) ?? data . arrayBuffer ( ) ;
131117 }
132- if ( typeof data ?. arrayBuffer === 'function ') {
133- return data ;
118+ if ( typeof data !== 'string ') {
119+ data = JSON . stringify ( data ) ;
134120 }
135- return new Blob ( [ JSON . stringify ( data ) ] , { type : 'application/json' } ) ;
121+ return ( new TextEncoder ( ) ) . encode ( data ) ;
136122}
0 commit comments