Skip to content

Commit a7b98ea

Browse files
committed
Upgrade dependencies & add new tls phase
1 parent 26e6c22 commit a7b98ea

File tree

6 files changed

+102
-44
lines changed

6 files changed

+102
-44
lines changed

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
language: node_js
22
node_js:
3-
- '11'
3+
- '13'
4+
- '12'
45
- '10'
5-
- '8'
66
after_success: npm run coveralls

README.md

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Yarn:
2121
```js
2222
'use strict';
2323
const https = require('https');
24-
const timer = require('@szmarczak/http-timer').default;
24+
const timer = require('@szmarczak/http-timer');
2525

2626
const request = https.get('https://httpbin.org/anything');
2727
const timings = timer(request);
@@ -33,21 +33,25 @@ request.on('response', response => {
3333
});
3434
});
3535

36-
// { start: 1535708511443,
37-
// socket: 1535708511444,
38-
// lookup: 1535708511444,
39-
// connect: 1535708511582,
40-
// upload: 1535708511887,
41-
// response: 1535708512037,
42-
// end: 1535708512040,
43-
// phases:
44-
// { wait: 1,
45-
// dns: 0,
46-
// tcp: 138,
47-
// request: 305,
48-
// firstByte: 150,
49-
// download: 3,
50-
// total: 597 } }
36+
// {
37+
// start: 1572712180361,
38+
// socket: 1572712180362,
39+
// lookup: 1572712180415,
40+
// connect: 1572712180571,
41+
// upload: 1572712180884,
42+
// response: 1572712181037,
43+
// end: 1572712181039,
44+
// error: null,
45+
// phases: {
46+
// wait: 1,
47+
// dns: 53,
48+
// tcp: 156,
49+
// request: 313,
50+
// firstByte: 153,
51+
// download: 2,
52+
// total: 678
53+
// }
54+
// }
5155
```
5256

5357
## API
@@ -60,6 +64,7 @@ Returns: `Object`
6064
- `socket` - Time when a socket was assigned to the request.
6165
- `lookup` - Time when the DNS lookup finished.
6266
- `connect` - Time when the socket successfully connected.
67+
- `secureConnect` - Time when the socket securely connected.
6368
- `upload` - Time when the request finished uploading.
6469
- `response` - Time when the request fired the `response` event.
6570
- `end` - Time when the response fired the `end` event.
@@ -68,12 +73,13 @@ Returns: `Object`
6873
- `wait` - `timings.socket - timings.start`
6974
- `dns` - `timings.lookup - timings.socket`
7075
- `tcp` - `timings.connect - timings.lookup`
71-
- `request` - `timings.upload - timings.connect`
76+
- `tls` - ``timings.secureConnect - timings.connect`
77+
- `request` - `timings.upload - (timings.secureConnect || timings.connect)`
7278
- `firstByte` - `timings.response - timings.upload`
7379
- `download` - `timings.end - timings.response`
7480
- `total` - `timings.end - timings.start` or `timings.error - timings.start`
7581

76-
If something is not measured yet, it will be `undefined`.
82+
If something has not been measured yet, it will be `undefined`.
7783

7884
**Note**: The time is a `number` representing the milliseconds elapsed since the UNIX epoch.
7985

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "Timings for HTTP requests",
55
"main": "dist",
66
"engines": {
7-
"node": ">=8"
7+
"node": ">=10"
88
},
99
"scripts": {
1010
"test": "xo && nyc ava",
@@ -32,7 +32,7 @@
3232
},
3333
"homepage": "https://github.com/szmarczak/http-timer#readme",
3434
"dependencies": {
35-
"defer-to-connect": "^1.0.2"
35+
"defer-to-connect": "^1.1.0"
3636
},
3737
"devDependencies": {
3838
"@sindresorhus/tsconfig": "^0.3.0",

source/index.ts

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import {EventEmitter} from 'events';
22
import {Socket} from 'net';
33
import {ClientRequest, IncomingMessage} from 'http';
4-
// @ts-ignore
5-
import deferToConnect = require('defer-to-connect');
4+
import deferToConnect from 'defer-to-connect';
65

76
export interface Timings {
87
start: number;
98
socket?: number;
109
lookup?: number;
1110
connect?: number;
11+
secureConnect?: number;
1212
upload?: number;
1313
response?: number;
1414
end?: number;
@@ -17,19 +17,21 @@ export interface Timings {
1717
wait?: number;
1818
dns?: number;
1919
tcp?: number;
20+
tls?: number;
2021
request?: number;
2122
firstByte?: number;
2223
download?: number;
2324
total?: number;
2425
};
2526
}
2627

27-
export default (request: ClientRequest): Timings => {
28+
const timer = (request: ClientRequest): Timings => {
2829
const timings: Timings = {
2930
start: Date.now(),
3031
socket: undefined,
3132
lookup: undefined,
3233
connect: undefined,
34+
secureConnect: undefined,
3335
upload: undefined,
3436
response: undefined,
3537
end: undefined,
@@ -38,6 +40,7 @@ export default (request: ClientRequest): Timings => {
3840
wait: undefined,
3941
dns: undefined,
4042
tcp: undefined,
43+
tls: undefined,
4144
request: undefined,
4245
firstByte: undefined,
4346
download: undefined,
@@ -74,25 +77,31 @@ export default (request: ClientRequest): Timings => {
7477

7578
socket.prependOnceListener('lookup', lookupListener);
7679

77-
deferToConnect(socket, () => {
78-
timings.connect = Date.now();
80+
deferToConnect(socket, {
81+
connect: () => {
82+
timings.connect = Date.now();
7983

80-
if (timings.lookup === undefined) {
81-
socket.removeListener('lookup', lookupListener);
82-
timings.lookup = timings.connect;
83-
timings.phases.dns = timings.lookup - timings.socket!;
84-
}
84+
if (timings.lookup === undefined) {
85+
socket.removeListener('lookup', lookupListener);
86+
timings.lookup = timings.connect;
87+
timings.phases.dns = timings.lookup - timings.socket!;
88+
}
8589

86-
timings.phases.tcp = timings.connect - timings.lookup;
90+
timings.phases.tcp = timings.connect - timings.lookup;
8791

88-
// This callback is called before flushing any data,
89-
// so we don't need to set `timings.phases.request` here.
92+
// This callback is called before flushing any data,
93+
// so we don't need to set `timings.phases.request` here.
94+
},
95+
secureConnect: () => {
96+
timings.secureConnect = Date.now();
97+
timings.phases.tls = timings.secureConnect - timings.connect!;
98+
}
9099
});
91100
});
92101

93102
request.prependOnceListener('finish', () => {
94103
timings.upload = Date.now();
95-
timings.phases.request = timings.upload - timings.connect!;
104+
timings.phases.request = timings.upload - (timings.secureConnect || timings.connect!);
96105
});
97106

98107
request.prependOnceListener('response', (response: IncomingMessage): void => {
@@ -110,3 +119,9 @@ export default (request: ClientRequest): Timings => {
110119

111120
return timings;
112121
};
122+
123+
export default timer;
124+
125+
// For CommonJS default export support
126+
module.exports = timer;
127+
module.exports.default = timer;

test.ts

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import EventEmitter from 'events';
2-
import http, {ClientRequest, IncomingMessage, RequestOptions} from 'http';
2+
import http, {ClientRequest, IncomingMessage} from 'http';
33
import https from 'https';
44
import {AddressInfo} from 'net';
5-
import {parse as parseUrl, URL} from 'url'; // eslint-disable-line node/no-deprecated-api
65
import util from 'util';
76
import pEvent from 'p-event';
87
import test from 'ava';
@@ -52,9 +51,21 @@ test('by default everything is set to undefined', t => {
5251
t.is(timings.socket, undefined);
5352
t.is(timings.lookup, undefined);
5453
t.is(timings.connect, undefined);
54+
t.is(timings.secureConnect, undefined);
5555
t.is(timings.response, undefined);
5656
t.is(timings.end, undefined);
5757
t.is(timings.error, undefined);
58+
59+
t.deepEqual(timings.phases, {
60+
wait: undefined,
61+
dns: undefined,
62+
tcp: undefined,
63+
tls: undefined,
64+
request: undefined,
65+
firstByte: undefined,
66+
download: undefined,
67+
total: undefined
68+
});
5869
});
5970

6071
test('timings', async t => {
@@ -68,6 +79,7 @@ test('timings', async t => {
6879
t.is(typeof timings.socket, 'number');
6980
t.is(typeof timings.lookup, 'number');
7081
t.is(typeof timings.connect, 'number');
82+
t.is(typeof timings.secureConnect, 'number');
7183
t.is(typeof timings.upload, 'number');
7284
t.is(typeof timings.response, 'number');
7385
t.is(typeof timings.end, 'number');
@@ -83,14 +95,16 @@ test('phases', async t => {
8395
t.is(typeof timings.phases.wait, 'number');
8496
t.is(typeof timings.phases.dns, 'number');
8597
t.is(typeof timings.phases.tcp, 'number');
98+
t.is(typeof timings.phases.tls, 'number');
8699
t.is(typeof timings.phases.firstByte, 'number');
87100
t.is(typeof timings.phases.download, 'number');
88101
t.is(typeof timings.phases.total, 'number');
89102

90103
t.is(timings.phases.wait, timings.socket! - timings.start);
91104
t.is(timings.phases.dns, timings.lookup! - timings.socket!);
92105
t.is(timings.phases.tcp, timings.connect! - timings.lookup!);
93-
t.is(timings.phases.request, timings.upload! - timings.connect!);
106+
t.is(timings.phases.tls, timings.secureConnect! - timings.connect!);
107+
t.is(timings.phases.request, timings.upload! - timings.secureConnect!);
94108
t.is(timings.phases.firstByte, timings.response! - timings.upload!);
95109
t.is(timings.phases.download, timings.end! - timings.response!);
96110
t.is(timings.phases.total, timings.end! - timings.start);
@@ -105,10 +119,9 @@ test('no memory leak (`lookup` event)', async t => {
105119
});
106120

107121
test('sets `total` on request error', async t => {
108-
const request = http.get({
109-
...parseUrl(server.url!),
122+
const request = http.get(server.url!, {
110123
timeout: 1
111-
} as RequestOptions);
124+
});
112125
request.on('timeout', () => {
113126
request.abort();
114127
});
@@ -147,7 +160,7 @@ test('doesn\'t throw when someone used `.prependOnceListener()`', t => {
147160
});
148161

149162
test('sensible timings', async t => {
150-
const {timings, request} = makeRequest('http://google.com');
163+
const {timings, request} = makeRequest('https://google.com');
151164
const now = Date.now();
152165

153166
const response = await pEvent(request, 'response');
@@ -157,12 +170,14 @@ test('sensible timings', async t => {
157170
t.true(timings.socket! >= now);
158171
t.true(timings.lookup! >= now);
159172
t.true(timings.connect! >= now);
173+
t.true(timings.secureConnect! >= now);
160174
t.true(timings.response! >= now);
161175
t.true(timings.end! >= now);
162176
t.is(timings.error, undefined);
163177
t.true(timings.phases.wait! < 1000);
164178
t.true(timings.phases.dns! < 1000);
165179
t.true(timings.phases.tcp! < 1000);
180+
t.true(timings.phases.tls! < 1000);
166181
t.true(timings.phases.request! < 1000);
167182
t.true(timings.phases.firstByte! < 1000);
168183
t.true(timings.phases.download! < 1000);
@@ -185,3 +200,25 @@ test('prepends once listeners', async t => {
185200
await promise;
186201
request.abort();
187202
});
203+
204+
test('`tls` phase for https requests', async t => {
205+
const {request, timings} = makeRequest('https://google.com');
206+
207+
const response = await pEvent(request, 'response');
208+
response.resume();
209+
await pEvent(response, 'end');
210+
211+
t.is(typeof timings.secureConnect, 'number');
212+
t.is(typeof timings.phases.tls, 'number');
213+
});
214+
215+
test('no `tls` phase for http requests', async t => {
216+
const {request, timings} = makeRequest(server.url);
217+
218+
const response = await pEvent(request, 'response');
219+
response.resume();
220+
await pEvent(response, 'end');
221+
222+
t.is(timings.secureConnect, undefined);
223+
t.is(timings.phases.tls, undefined);
224+
});

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"extends": "@sindresorhus/tsconfig",
33
"compilerOptions": {
44
"outDir": "dist",
5-
"target": "es2017" // Node.js 8
5+
"target": "es2018" // Node.js 10
66
},
77
"include": [
88
"source"

0 commit comments

Comments
 (0)