Skip to content

Commit 2a21563

Browse files
authored
Merge pull request #7 from flickr/esm
Move codebase to esm
2 parents d887db2 + c190705 commit 2a21563

File tree

10 files changed

+175
-101
lines changed

10 files changed

+175
-101
lines changed

.eslintrc.js .eslintrc.cjs

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module.exports = {
88
},
99

1010
parserOptions: {
11+
sourceType: 'module',
1112
ecmaVersion: 8
1213
},
1314

README.md

+38-6
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ $ npm install incoming-message-hash --save
1313
This example demonstrates how the hashing function returns a different hash based on the IncomingMessage's method, path, query string, headers and body.
1414

1515
``` js
16-
var hash = require('incoming-message-hash');
17-
var http = require('http');
16+
import hash from 'incoming-message-hash'
17+
import { createServer } from 'http'
1818

19-
http.createServer(function (req, res) {
20-
req.pipe(hash()).pipe(res);
21-
}).listen(4567, function () {
19+
createServer((req, res) => {
20+
req.pipe(hash()).pipe(res)
21+
}).listen(4567, () => {
2222
console.log('Server is listening on port 4567');
23-
});
23+
})
2424
```
2525

2626
``` bash
@@ -50,16 +50,48 @@ var hash = require('incoming-message-hash');
5050

5151
Returns a new [crypto.Hash][] stream using the specified algorithm and encoding (defaults to "md5" and "hex"). You can pipe your [http.IncomingMessage][] in and get a hash back.
5252

53+
```js
54+
import hash from 'incoming-message-hash'
55+
import { createServer } from 'http'
56+
57+
createServer((req, res) => {
58+
req.pipe(hash()).pipe(res)
59+
})
60+
```
5361

5462
### hash.sync(req, body[, algorithm='md5'[, encoding='hex']])
5563

5664
Synchronous version of `hash()` that accepts an [http.IncomingMessage][] and its body and returns the hash. You must buffer up the request body yourself if you wish to use this method.
5765

66+
```js
67+
import { promise } from 'incoming-message-hash'
68+
import { createServer } from 'http'
69+
70+
createServer(async function (req, res) {
71+
let body = ''
72+
73+
req.on('data', chunk => body += String(chunk))
74+
75+
req.on('end', () => {
76+
res.end(sync(req, body))
77+
})
78+
})
79+
```
80+
5881
### hash.promise(req[, algorithm='md5'[, encoding='hex]])
5982

6083
Asynchronous version of `hash()` that accepts an [http.IncomingMessage][] and
6184
buffers the body up for you.
6285

86+
```js
87+
import { promise } from 'incoming-message-hash'
88+
import { createServer } from 'http'
89+
90+
createServer(async (req, res) => {
91+
res.end(await promise(req))
92+
})
93+
```
94+
6395
## license
6496

6597
This software is free to use under the MIT license. See the [LICENSE][] file for license text and copyright information.

hook.sh

-2
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,3 @@ set -ex
44

55
npm run lint
66
npm run test
7-
8-
node package.json

index.js

+97-20
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,116 @@
11
// Copyright 2021 SmugMug, Inc.
22
// Licensed under the terms of the MIT license. Please see LICENSE file in the project root for terms.
33

4-
var crypto = require('crypto');
5-
var url = require('url');
6-
7-
module.exports = createStream;
8-
9-
function createStream(algorithm, encoding) {
10-
var hash = createHash(algorithm);
4+
import { createHash } from 'crypto';
5+
import { parse } from 'url';
6+
7+
8+
/**
9+
* The default digest algorithm to use
10+
* @see https://nodejs.org/dist/latest-v16.x/docs/api/crypto.html#cryptocreatehashalgorithm-options
11+
*/
12+
13+
const DEFAULT_ALGORITHM = 'md5';
14+
15+
/**
16+
* The default digest encoding to return
17+
* @type {BufferEncoding}
18+
*/
19+
20+
const DEFAULT_ENCODING = 'hex';
21+
22+
/**
23+
* Returns a new `crypto.Hash` stream using the specified algorithm and encoding
24+
* (defaults to "md5" and "hex"). You can pipe your `http.IncomingMessage` in
25+
* and get a hash back.
26+
*
27+
* @param {string} algorithm
28+
* @param {BufferEncoding} encoding
29+
* @returns {import('crypto').Hash}
30+
* @example
31+
*
32+
* import hash from 'incoming-message-hash'
33+
* import { createServer } from 'http'
34+
*
35+
* createServer((req, res) => {
36+
* req.pipe(hash()).pipe(res)
37+
* })
38+
*/
39+
40+
export default function createStream(algorithm = DEFAULT_ALGORITHM, encoding = DEFAULT_ENCODING) {
41+
const hash = createHash(algorithm);
1142

1243
hash.on('pipe', function (req) {
1344
updateHash(hash, req);
1445
});
1546

16-
hash.setEncoding(encoding || 'hex');
47+
hash.setEncoding(encoding);
1748

1849
return hash;
1950
}
2051

21-
createStream.sync = function (req, body, algorithm, encoding) {
22-
var hash = createHash(algorithm);
52+
// backwards-compatibility
53+
createStream.sync = sync;
54+
createStream.promise = promise;
55+
56+
/**
57+
* Synchronous version of `hash()` that accepts an http.IncomingMessage and its
58+
* body and returns the hash. You must buffer up the request body yourself
59+
* if you wish to use this method.
60+
61+
* @param {import('http').IncomingMessage} req
62+
* @param {string|Buffer} body
63+
* @param {string} algorithm
64+
* @param {BufferEncoding} encoding
65+
* @async
66+
* @returns {string}
67+
* @example
68+
*
69+
* import { promise } from 'incoming-message-hash'
70+
* import { createServer } from 'http'
71+
*
72+
* createServer(async function (req, res) {
73+
* let body = ''
74+
*
75+
* req.on('data', chunk => body += String(chunk))
76+
*
77+
* req.on('end', () => {
78+
* res.end(sync(req, body))
79+
* })
80+
* })
81+
*/
82+
83+
export function sync(req, body, algorithm = DEFAULT_ALGORITHM, encoding = DEFAULT_ENCODING) {
84+
const hash = createHash(algorithm);
2385

2486
updateHash(hash, req);
2587

2688
hash.write(body);
2789

28-
return hash.digest(encoding || 'hex');
29-
};
90+
return hash.digest(encoding);
91+
}
3092

31-
createStream.promise = function (req, algorithm, encoding) {
32-
var hash = createHash(algorithm);
93+
/**
94+
* Asynchronous version of `hash()` that accepts an `http.IncomingMessage` and
95+
* buffers the request body up for you.
96+
*
97+
* @param {import('http').IncomingMessage} req
98+
* @param {string} algorithm
99+
* @param {BufferEncoding} encoding
100+
* @async
101+
* @returns {Promise<string>}
102+
* @example
103+
*
104+
* import { promise } from 'incoming-message-hash'
105+
* import { createServer } from 'http'
106+
*
107+
* createServer(async (req, res) => {
108+
* res.end(await promise(req))
109+
* })
110+
*/
111+
112+
export function promise(req, algorithm = DEFAULT_ALGORITHM, encoding = DEFAULT_ENCODING) {
113+
const hash = createHash(algorithm);
33114

34115
updateHash(hash, req);
35116

@@ -43,17 +124,13 @@ createStream.promise = function (req, algorithm, encoding) {
43124
});
44125

45126
req.on('end', function () {
46-
resolve(hash.digest(encoding || 'hex'));
127+
resolve(hash.digest(encoding));
47128
});
48129
});
49-
};
50-
51-
function createHash(algorithm) {
52-
return crypto.createHash(algorithm || 'md5');
53130
}
54131

55132
function updateHash(hash, req) {
56-
var parts = url.parse(req.url, true);
133+
const parts = parse(req.url, true);
57134

58135
hash.update(req.httpVersion);
59136
hash.update(req.method);

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"version": "4.1.0",
44
"description": "Generate a one-way hash from an http.IncomingMessage",
55
"main": "index.js",
6+
"type": "module",
67
"engines": {
78
"node": ">=12"
89
},

test/fixture.js

-34
This file was deleted.

test/harness.js

+30-31
Original file line numberDiff line numberDiff line change
@@ -3,87 +3,86 @@
33

44
/* eslint-env mocha */
55

6-
var request = require('supertest');
7-
var fixture = require('./fixture');
6+
import request from 'supertest';
87

98
/**
109
* Shared expectations for each version of the hash API.
1110
*/
1211

13-
module.exports = function (app) {
12+
export default function (app) {
1413

15-
it('hashes an http.IncomingMessage', function (done) {
16-
request(app())
14+
it('hashes an http.IncomingMessage', function () {
15+
return request(app())
1716
.get('/')
1817
.set('host', 'localhost:4567')
1918
.set('user-agent', 'node-superagent/1.3.0')
20-
.expect(fixture[this.test.title], done);
19+
.expect('09a3df93c944461cee09969f2a4bb848');
2120
});
2221

23-
it('produces a different hash for a different path', function (done) {
24-
request(app())
22+
it('produces a different hash for a different path', function () {
23+
return request(app())
2524
.get('/quux')
2625
.set('host', 'localhost:4567')
2726
.set('user-agent', 'node-superagent/1.3.0')
28-
.expect(fixture[this.test.title], done);
27+
.expect('85713c266b81f0be1d61b281405bafc0');
2928
});
3029

31-
it('produces a different hash for a different query string', function (done) {
32-
request(app())
30+
it('produces a different hash for a different query string', function () {
31+
return request(app())
3332
.get('/?foo=1&bar=2')
3433
.set('host', 'localhost:4567')
3534
.set('user-agent', 'node-superagent/1.3.0')
36-
.expect(fixture[this.test.title], done);
35+
.expect('2f8a8a2c8b6f286e65848160ba8c6ab1');
3736
});
3837

39-
it('produces the same hash for different ordered query params', function (done) {
40-
request(app())
38+
it('produces the same hash for different ordered query params', function () {
39+
return request(app())
4140
.get('/?bar=2&foo=1')
4241
.set('host', 'localhost:4567')
4342
.set('user-agent', 'node-superagent/1.3.0')
44-
.expect(fixture[this.test.title], done);
43+
.expect('2f8a8a2c8b6f286e65848160ba8c6ab1');
4544
});
4645

47-
it('produces a different hash for a different method', function (done) {
48-
request(app())
46+
it('produces a different hash for a different method', function () {
47+
return request(app())
4948
.post('/')
5049
.set('host', 'localhost:4567')
5150
.set('user-agent', 'node-superagent/1.3.0')
52-
.expect(fixture[this.test.title], done);
51+
.expect('6db371c210f891e15229c3a9470da6a6');
5352
});
5453

55-
it('produces a different hash for different headers', function (done) {
56-
request(app())
54+
it('produces a different hash for different headers', function () {
55+
return request(app())
5756
.get('/')
5857
.set('host', 'localhost:4567')
5958
.set('user-agent', 'node-superagent/1.3.0')
6059
.set('x-foo', 'bar')
61-
.expect(fixture[this.test.title], done);
60+
.expect('46e486ddb60f2236f77c8bbe29d6c760');
6261
});
6362

64-
it('produces a different hash for a different post body', function (done) {
65-
request(app())
63+
it('produces a different hash for a different post body', function () {
64+
return request(app())
6665
.post('/')
6766
.set('host', 'localhost:4567')
6867
.set('user-agent', 'node-superagent/1.3.0')
6968
.send('yay')
70-
.expect(fixture[this.test.title], done);
69+
.expect('e84cf2827fbc172a5957e3b29a1f47d5');
7170
});
7271

73-
it('can use a different hash algorithm', function (done) {
74-
request(app('sha1'))
72+
it('can use a different hash algorithm', function () {
73+
return request(app('sha1'))
7574
.get('/')
7675
.set('host', 'localhost:4567')
7776
.set('user-agent', 'node-superagent/1.3.0')
78-
.expect(fixture[this.test.title], done);
77+
.expect("d8b3b0f8af8babb29291719b3bbbaa45b1aaaa85");
7978
});
8079

81-
it('can use a different encoding', function (done) {
82-
request(app('md5', 'base64'))
80+
it('can use a different encoding', function () {
81+
return request(app('md5', 'base64'))
8382
.get('/')
8483
.set('host', 'localhost:4567')
8584
.set('user-agent', 'node-superagent/1.3.0')
86-
.expect(fixture[this.test.title], done);
85+
.expect('CaPfk8lERhzuCZafKku4SA==');
8786
});
8887

89-
};
88+
}

0 commit comments

Comments
 (0)