1 | 'use strict';
|
2 |
|
3 | const deferToConnect = require('defer-to-connect');
|
4 |
|
5 | module.exports = request => {
|
6 | const timings = {
|
7 | start: Date.now(),
|
8 | socket: null,
|
9 | lookup: null,
|
10 | connect: null,
|
11 | upload: null,
|
12 | response: null,
|
13 | end: null,
|
14 | error: null,
|
15 | phases: {
|
16 | wait: null,
|
17 | dns: null,
|
18 | tcp: null,
|
19 | request: null,
|
20 | firstByte: null,
|
21 | download: null,
|
22 | total: null
|
23 | }
|
24 | };
|
25 |
|
26 | const handleError = origin => {
|
27 | const emit = origin.emit.bind(origin);
|
28 | origin.emit = (event, ...args) => {
|
29 |
|
30 | if (event === 'error') {
|
31 | timings.error = Date.now();
|
32 | timings.phases.total = timings.error - timings.start;
|
33 | }
|
34 |
|
35 |
|
36 | return emit(event, ...args);
|
37 | };
|
38 | };
|
39 |
|
40 | handleError(request);
|
41 |
|
42 | request.once('socket', socket => {
|
43 | timings.socket = Date.now();
|
44 | timings.phases.wait = timings.socket - timings.start;
|
45 |
|
46 | const lookupListener = () => {
|
47 | timings.lookup = Date.now();
|
48 | timings.phases.dns = timings.lookup - timings.socket;
|
49 | };
|
50 |
|
51 | socket.once('lookup', lookupListener);
|
52 |
|
53 | deferToConnect(socket, () => {
|
54 | timings.connect = Date.now();
|
55 |
|
56 | if (timings.lookup === null) {
|
57 | socket.removeListener('lookup', lookupListener);
|
58 | timings.lookup = timings.connect;
|
59 | timings.phases.dns = timings.lookup - timings.socket;
|
60 | }
|
61 |
|
62 | timings.phases.tcp = timings.connect - timings.lookup;
|
63 | });
|
64 | });
|
65 |
|
66 | request.once('finish', () => {
|
67 | timings.upload = Date.now();
|
68 | timings.phases.request = timings.upload - timings.connect;
|
69 | });
|
70 |
|
71 | request.once('response', response => {
|
72 | timings.response = Date.now();
|
73 | timings.phases.firstByte = timings.response - timings.upload;
|
74 |
|
75 | handleError(response);
|
76 |
|
77 | response.once('end', () => {
|
78 | timings.end = Date.now();
|
79 | timings.phases.download = timings.end - timings.response;
|
80 | timings.phases.total = timings.end - timings.start;
|
81 | });
|
82 | });
|
83 |
|
84 | return timings;
|
85 | };
|