rezo 1.0.19 → 1.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/curl.cjs +39 -34
- package/dist/adapters/curl.js +39 -34
- package/dist/adapters/entries/curl.d.ts +19 -18
- package/dist/adapters/entries/fetch.d.ts +19 -18
- package/dist/adapters/entries/http.d.ts +19 -18
- package/dist/adapters/entries/http2.d.ts +19 -18
- package/dist/adapters/entries/react-native.d.ts +19 -18
- package/dist/adapters/entries/xhr.d.ts +19 -18
- package/dist/adapters/fetch.cjs +42 -41
- package/dist/adapters/fetch.js +42 -41
- package/dist/adapters/http.cjs +65 -46
- package/dist/adapters/http.js +65 -46
- package/dist/adapters/http2.cjs +41 -36
- package/dist/adapters/http2.js +41 -36
- package/dist/adapters/index.cjs +6 -6
- package/dist/adapters/react-native.cjs +41 -27
- package/dist/adapters/react-native.js +41 -27
- package/dist/adapters/xhr.cjs +43 -38
- package/dist/adapters/xhr.js +43 -38
- package/dist/cache/index.cjs +13 -13
- package/dist/crawler.d.ts +19 -18
- package/dist/entries/crawler.cjs +5 -5
- package/dist/errors/rezo-error.cjs +139 -21
- package/dist/errors/rezo-error.js +138 -21
- package/dist/index.cjs +24 -24
- package/dist/index.d.ts +19 -18
- package/dist/platform/browser.d.ts +19 -18
- package/dist/platform/bun.d.ts +19 -18
- package/dist/platform/deno.d.ts +19 -18
- package/dist/platform/node.d.ts +19 -18
- package/dist/platform/react-native.d.ts +19 -18
- package/dist/platform/worker.d.ts +19 -18
- package/dist/plugin/index.cjs +36 -36
- package/dist/proxy/index.cjs +2 -2
- package/dist/queue/index.cjs +8 -8
- package/dist/utils/http-config.cjs +6 -3
- package/dist/utils/http-config.js +6 -3
- package/dist/utils/timing.cjs +90 -0
- package/dist/utils/timing.js +78 -0
- package/package.json +1 -1
package/dist/adapters/http.js
CHANGED
|
@@ -556,9 +556,9 @@ async function request(config, fetchOptions, requestCount, timing, _stats, respo
|
|
|
556
556
|
const requestOptions = buildHTTPOptions(fetchOptions, isSecure, url);
|
|
557
557
|
try {
|
|
558
558
|
const req = httpModule.request(requestOptions, async (res) => {
|
|
559
|
-
if (!
|
|
559
|
+
if (!timing.firstByteTime) {
|
|
560
560
|
timing.firstByteTime = performance.now();
|
|
561
|
-
config.timing.
|
|
561
|
+
config.timing.responseStart = timing.firstByteTime;
|
|
562
562
|
}
|
|
563
563
|
const { statusCode, statusMessage, headers, httpVersion, socket } = res;
|
|
564
564
|
const { remoteAddress, remotePort, localAddress, localPort } = socket;
|
|
@@ -588,8 +588,8 @@ async function request(config, fetchOptions, requestCount, timing, _stats, respo
|
|
|
588
588
|
contentLength: contentLength ? parseInt(contentLength, 10) : undefined,
|
|
589
589
|
cookies: cookieArray,
|
|
590
590
|
timing: {
|
|
591
|
-
firstByte: config.timing.
|
|
592
|
-
total: performance.now() - timing.startTime
|
|
591
|
+
firstByte: config.timing.responseStart - config.timing.startTime,
|
|
592
|
+
total: performance.now() - config.timing.startTime
|
|
593
593
|
}
|
|
594
594
|
};
|
|
595
595
|
eventEmitter.emit("headers", headersEvent);
|
|
@@ -674,14 +674,7 @@ async function request(config, fetchOptions, requestCount, timing, _stats, respo
|
|
|
674
674
|
finalUrl: url.toString(),
|
|
675
675
|
cookies: config.cookieJar?.cookies() || { array: [], map: {} },
|
|
676
676
|
urls: [url.toString()],
|
|
677
|
-
timing:
|
|
678
|
-
total: config.timing.durationMs || 0,
|
|
679
|
-
dns: config.timing.dnsMs,
|
|
680
|
-
tcp: config.timing.tcpMs,
|
|
681
|
-
tls: config.timing.tlsMs,
|
|
682
|
-
firstByte: config.timing.ttfbMs,
|
|
683
|
-
download: config.timing.transferMs
|
|
684
|
-
},
|
|
677
|
+
timing: getTimingDurations(config),
|
|
685
678
|
config: sanitizeConfig(config)
|
|
686
679
|
};
|
|
687
680
|
streamResult.emit("done", streamFinishEvent);
|
|
@@ -738,14 +731,10 @@ async function request(config, fetchOptions, requestCount, timing, _stats, respo
|
|
|
738
731
|
fileName: filename,
|
|
739
732
|
fileSize: contentLengthCounter,
|
|
740
733
|
timing: {
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
tcp: config.timing.tcpMs,
|
|
744
|
-
tls: config.timing.tlsMs,
|
|
745
|
-
firstByte: config.timing.ttfbMs,
|
|
746
|
-
download: config.timing.transferMs || 0
|
|
734
|
+
...getTimingDurations(config),
|
|
735
|
+
download: getTimingDurations(config).download || 0
|
|
747
736
|
},
|
|
748
|
-
averageSpeed: config.
|
|
737
|
+
averageSpeed: getTimingDurations(config).download ? contentLengthCounter / getTimingDurations(config).download * 1000 : 0,
|
|
749
738
|
config: sanitizeConfig(config)
|
|
750
739
|
};
|
|
751
740
|
downloadResult.emit("finish", finishEvent);
|
|
@@ -838,16 +827,16 @@ async function request(config, fetchOptions, requestCount, timing, _stats, respo
|
|
|
838
827
|
uploadSize: config.transfer.requestSize || 0,
|
|
839
828
|
fileName: uploadResult.fileName,
|
|
840
829
|
timing: {
|
|
841
|
-
total: config.
|
|
842
|
-
dns: config.
|
|
843
|
-
tcp: config.
|
|
844
|
-
tls: config.
|
|
845
|
-
upload: config.
|
|
846
|
-
waiting: config.
|
|
847
|
-
download: config.
|
|
830
|
+
total: getTimingDurations(config).total,
|
|
831
|
+
dns: getTimingDurations(config).dns,
|
|
832
|
+
tcp: getTimingDurations(config).tcp,
|
|
833
|
+
tls: getTimingDurations(config).tls,
|
|
834
|
+
upload: getTimingDurations(config).firstByte || 0,
|
|
835
|
+
waiting: getTimingDurations(config).download > 0 && getTimingDurations(config).firstByte > 0 ? getTimingDurations(config).download - getTimingDurations(config).firstByte : 0,
|
|
836
|
+
download: getTimingDurations(config).download
|
|
848
837
|
},
|
|
849
|
-
averageUploadSpeed: config.
|
|
850
|
-
averageDownloadSpeed: config.
|
|
838
|
+
averageUploadSpeed: getTimingDurations(config).firstByte && config.transfer.requestSize ? config.transfer.requestSize / getTimingDurations(config).firstByte * 1000 : 0,
|
|
839
|
+
averageDownloadSpeed: getTimingDurations(config).download ? contentLengthCounter / getTimingDurations(config).download * 1000 : 0,
|
|
851
840
|
config: sanitizeConfig(config)
|
|
852
841
|
};
|
|
853
842
|
uploadResult.emit("finish", uploadFinishEvent);
|
|
@@ -886,17 +875,19 @@ async function request(config, fetchOptions, requestCount, timing, _stats, respo
|
|
|
886
875
|
socket.unref();
|
|
887
876
|
}
|
|
888
877
|
timing.dnsStart = performance.now();
|
|
878
|
+
config.timing.domainLookupStart = timing.dnsStart;
|
|
889
879
|
socket.on("lookup", () => {
|
|
890
|
-
if (!
|
|
891
|
-
|
|
892
|
-
|
|
880
|
+
if (!timing.dnsEnd) {
|
|
881
|
+
timing.dnsEnd = performance.now();
|
|
882
|
+
config.timing.domainLookupEnd = timing.dnsEnd;
|
|
893
883
|
timing.tcpStart = performance.now();
|
|
884
|
+
config.timing.connectStart = timing.tcpStart;
|
|
894
885
|
}
|
|
895
886
|
});
|
|
896
887
|
socket.on("secureConnect", () => {
|
|
897
|
-
if (!
|
|
898
|
-
|
|
899
|
-
|
|
888
|
+
if (!timing.tlsEnd && timing.tlsStart) {
|
|
889
|
+
timing.tlsEnd = performance.now();
|
|
890
|
+
config.timing.connectEnd = timing.tlsEnd;
|
|
900
891
|
}
|
|
901
892
|
const tls = {
|
|
902
893
|
cipher: socket.getCipher(),
|
|
@@ -920,11 +911,13 @@ async function request(config, fetchOptions, requestCount, timing, _stats, respo
|
|
|
920
911
|
};
|
|
921
912
|
});
|
|
922
913
|
socket.on("connect", () => {
|
|
923
|
-
if (!
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
if (isSecure)
|
|
914
|
+
if (!timing.tcpEnd) {
|
|
915
|
+
timing.tcpEnd = performance.now();
|
|
916
|
+
config.timing.connectEnd = timing.tcpEnd;
|
|
917
|
+
if (isSecure) {
|
|
927
918
|
timing.tlsStart = performance.now();
|
|
919
|
+
config.timing.secureConnectionStart = timing.tlsStart;
|
|
920
|
+
}
|
|
928
921
|
}
|
|
929
922
|
const { remoteAddress, remotePort, localAddress, localPort, remoteFamily } = socket;
|
|
930
923
|
if (remoteAddress && !config.network.remoteAddress) {
|
|
@@ -995,10 +988,15 @@ async function request(config, fetchOptions, requestCount, timing, _stats, respo
|
|
|
995
988
|
});
|
|
996
989
|
}
|
|
997
990
|
function updateTiming(config, timing, contentLength, contentLengthCounter, rawHeaders) {
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
config.timing.
|
|
1001
|
-
config.timing.
|
|
991
|
+
const now = performance.now();
|
|
992
|
+
config.timing.domainLookupStart = timing.dnsStart || config.timing.startTime;
|
|
993
|
+
config.timing.domainLookupEnd = timing.dnsEnd || timing.dnsStart || config.timing.startTime;
|
|
994
|
+
config.timing.connectStart = timing.tcpStart || timing.dnsEnd || config.timing.startTime;
|
|
995
|
+
config.timing.secureConnectionStart = timing.tlsStart || 0;
|
|
996
|
+
config.timing.connectEnd = timing.tlsEnd || timing.tcpEnd || timing.tcpStart || config.timing.startTime;
|
|
997
|
+
config.timing.requestStart = timing.tlsEnd || timing.tcpEnd || config.timing.startTime;
|
|
998
|
+
config.timing.responseStart = timing.firstByteTime || config.timing.requestStart;
|
|
999
|
+
config.timing.responseEnd = now;
|
|
1002
1000
|
const bodySize = parseInt(contentLength || "0", 10) || contentLengthCounter;
|
|
1003
1001
|
config.transfer.bodySize = bodySize;
|
|
1004
1002
|
let headerSize = 0;
|
|
@@ -1031,6 +1029,17 @@ function updateTiming(config, timing, contentLength, contentLengthCounter, rawHe
|
|
|
1031
1029
|
};
|
|
1032
1030
|
}
|
|
1033
1031
|
}
|
|
1032
|
+
function getTimingDurations(config) {
|
|
1033
|
+
const t = config.timing;
|
|
1034
|
+
return {
|
|
1035
|
+
total: t.responseEnd - t.startTime,
|
|
1036
|
+
dns: t.domainLookupEnd - t.domainLookupStart,
|
|
1037
|
+
tcp: t.secureConnectionStart > 0 ? t.secureConnectionStart - t.connectStart : t.connectEnd - t.connectStart,
|
|
1038
|
+
tls: t.secureConnectionStart > 0 ? t.connectEnd - t.secureConnectionStart : undefined,
|
|
1039
|
+
firstByte: t.responseStart - t.startTime,
|
|
1040
|
+
download: t.responseEnd - t.responseStart
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1034
1043
|
let dnsCache = null;
|
|
1035
1044
|
function createDNSLookup(cache) {
|
|
1036
1045
|
return (hostname, optionsOrCallback, callbackOrUndefined) => {
|
|
@@ -1168,9 +1177,19 @@ async function setInitialConfig(config, fetchOptions, isSecure, url, httpModule,
|
|
|
1168
1177
|
browser: false,
|
|
1169
1178
|
ssl: isSecure
|
|
1170
1179
|
};
|
|
1171
|
-
const
|
|
1172
|
-
config.timing = config.timing || {
|
|
1173
|
-
|
|
1180
|
+
const startTime = performance.now();
|
|
1181
|
+
config.timing = config.timing || {
|
|
1182
|
+
startTime,
|
|
1183
|
+
domainLookupStart: startTime,
|
|
1184
|
+
domainLookupEnd: startTime,
|
|
1185
|
+
connectStart: startTime,
|
|
1186
|
+
secureConnectionStart: 0,
|
|
1187
|
+
connectEnd: startTime,
|
|
1188
|
+
requestStart: startTime,
|
|
1189
|
+
responseStart: startTime,
|
|
1190
|
+
responseEnd: startTime
|
|
1191
|
+
};
|
|
1192
|
+
config.timing.startTime = config.timing.startTime || startTime;
|
|
1174
1193
|
config.maxRedirectsReached = false;
|
|
1175
1194
|
config.responseCookies = {
|
|
1176
1195
|
array: [],
|
|
@@ -1188,7 +1207,7 @@ async function setInitialConfig(config, fetchOptions, isSecure, url, httpModule,
|
|
|
1188
1207
|
config.requestId = generateRequestId();
|
|
1189
1208
|
config.sessionId = fetchOptions.sessionId || generateSessionId();
|
|
1190
1209
|
config.traceId = generateTraceId();
|
|
1191
|
-
config.timestamp =
|
|
1210
|
+
config.timestamp = Date.now();
|
|
1192
1211
|
config.trackingData = {};
|
|
1193
1212
|
config.transfer = {
|
|
1194
1213
|
requestSize: 0,
|
package/dist/adapters/http2.cjs
CHANGED
|
@@ -200,6 +200,30 @@ class Http2SessionPool {
|
|
|
200
200
|
this.closeAllSessions();
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
|
+
function updateTiming(config, timing, contentLengthCounter) {
|
|
204
|
+
const now = performance.now();
|
|
205
|
+
config.timing.domainLookupStart = timing.dnsStart || config.timing.startTime;
|
|
206
|
+
config.timing.domainLookupEnd = timing.dnsEnd || timing.dnsStart || config.timing.startTime;
|
|
207
|
+
config.timing.connectStart = timing.tcpStart || timing.dnsEnd || config.timing.startTime;
|
|
208
|
+
config.timing.secureConnectionStart = timing.tlsStart || 0;
|
|
209
|
+
config.timing.connectEnd = timing.tcpEnd || timing.tlsEnd || timing.tcpStart || config.timing.startTime;
|
|
210
|
+
config.timing.requestStart = timing.tcpEnd || config.timing.startTime;
|
|
211
|
+
config.timing.responseStart = timing.firstByteTime || config.timing.requestStart;
|
|
212
|
+
config.timing.responseEnd = now;
|
|
213
|
+
config.transfer.bodySize = contentLengthCounter;
|
|
214
|
+
config.transfer.responseSize = contentLengthCounter;
|
|
215
|
+
}
|
|
216
|
+
function getTimingDurations(config) {
|
|
217
|
+
const t = config.timing;
|
|
218
|
+
return {
|
|
219
|
+
total: t.responseEnd - t.startTime,
|
|
220
|
+
dns: t.domainLookupEnd - t.domainLookupStart,
|
|
221
|
+
tcp: t.secureConnectionStart > 0 ? t.secureConnectionStart - t.connectStart : t.connectEnd - t.connectStart,
|
|
222
|
+
tls: t.secureConnectionStart > 0 ? t.connectEnd - t.secureConnectionStart : undefined,
|
|
223
|
+
firstByte: t.responseStart - t.startTime,
|
|
224
|
+
download: t.responseEnd - t.responseStart
|
|
225
|
+
};
|
|
226
|
+
}
|
|
203
227
|
const responseCacheInstances = new Map;
|
|
204
228
|
function getCacheConfigKey(option) {
|
|
205
229
|
if (option === true)
|
|
@@ -489,10 +513,11 @@ async function executeHttp2Request(fetchOptions, config, options, perform, fs, s
|
|
|
489
513
|
const maxRetries = config?.retry?.maxRetries || 0;
|
|
490
514
|
const incrementDelay = config?.retry?.incrementDelay || false;
|
|
491
515
|
const statusCodes = config?.retry?.statusCodes;
|
|
516
|
+
const startTime = performance.now();
|
|
492
517
|
const timing = {
|
|
493
|
-
startTime
|
|
494
|
-
startTimestamp: Date.now()
|
|
518
|
+
startTime
|
|
495
519
|
};
|
|
520
|
+
config.timing.startTime = startTime;
|
|
496
521
|
const ABSOLUTE_MAX_ATTEMPTS = 50;
|
|
497
522
|
const visitedUrls = new Set;
|
|
498
523
|
let totalAttempts = 0;
|
|
@@ -662,7 +687,6 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
662
687
|
config.isSecure = isSecure;
|
|
663
688
|
config.finalUrl = url.href;
|
|
664
689
|
config.network.protocol = "h2";
|
|
665
|
-
config.timing.startTimestamp = timing.startTimestamp;
|
|
666
690
|
}
|
|
667
691
|
const headers = {
|
|
668
692
|
[http2.constants.HTTP2_HEADER_METHOD]: fetchOptions.method.toUpperCase(),
|
|
@@ -739,9 +763,9 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
739
763
|
responseHeaders = headers;
|
|
740
764
|
status = Number(headers[http2.constants.HTTP2_HEADER_STATUS]) || 200;
|
|
741
765
|
statusText = getStatusText(status);
|
|
742
|
-
if (!
|
|
766
|
+
if (!timing.firstByteTime) {
|
|
743
767
|
timing.firstByteTime = performance.now();
|
|
744
|
-
config.timing.
|
|
768
|
+
config.timing.responseStart = timing.firstByteTime;
|
|
745
769
|
}
|
|
746
770
|
const location = headers["location"];
|
|
747
771
|
const isRedirect = status >= 300 && status < 400 && location;
|
|
@@ -760,8 +784,8 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
760
784
|
contentLength: headers["content-length"] ? parseInt(headers["content-length"], 10) : undefined,
|
|
761
785
|
cookies: config.responseCookies?.array || [],
|
|
762
786
|
timing: {
|
|
763
|
-
firstByte: config.timing.
|
|
764
|
-
total: performance.now() - timing.startTime
|
|
787
|
+
firstByte: config.timing.responseStart - config.timing.startTime,
|
|
788
|
+
total: performance.now() - config.timing.startTime
|
|
765
789
|
}
|
|
766
790
|
};
|
|
767
791
|
eventEmitter.emit("headers", headersEvent);
|
|
@@ -798,9 +822,7 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
798
822
|
}
|
|
799
823
|
});
|
|
800
824
|
req.on("end", async () => {
|
|
801
|
-
config
|
|
802
|
-
config.timing.durationMs = performance.now() - timing.startTime;
|
|
803
|
-
config.timing.transferMs = timing.firstByteTime ? performance.now() - timing.firstByteTime : config.timing.durationMs;
|
|
825
|
+
updateTiming(config, timing, contentLengthCounter);
|
|
804
826
|
if (!config.transfer) {
|
|
805
827
|
config.transfer = { requestSize: 0, responseSize: 0, headerSize: 0, bodySize: 0 };
|
|
806
828
|
}
|
|
@@ -820,8 +842,6 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
820
842
|
config.transfer.requestSize = Buffer.byteLength(JSON.stringify(body), "utf8");
|
|
821
843
|
}
|
|
822
844
|
}
|
|
823
|
-
config.transfer.bodySize = contentLengthCounter;
|
|
824
|
-
config.transfer.responseSize = contentLengthCounter;
|
|
825
845
|
(sessionPool || Http2SessionPool.getInstance()).releaseSession(url);
|
|
826
846
|
if (_stats.statusOnNext === "redirect") {
|
|
827
847
|
const partialResponse = {
|
|
@@ -920,14 +940,10 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
920
940
|
fileName: config.fileName,
|
|
921
941
|
fileSize: responseBody.length,
|
|
922
942
|
timing: {
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
tcp: config.timing.tcpMs,
|
|
926
|
-
tls: config.timing.tlsMs,
|
|
927
|
-
firstByte: config.timing.ttfbMs,
|
|
928
|
-
download: config.timing.transferMs || 0
|
|
943
|
+
...getTimingDurations(config),
|
|
944
|
+
download: getTimingDurations(config).download || 0
|
|
929
945
|
},
|
|
930
|
-
averageSpeed: config.
|
|
946
|
+
averageSpeed: getTimingDurations(config).download ? responseBody.length / getTimingDurations(config).download * 1000 : 0,
|
|
931
947
|
config: sanitizeConfig(config)
|
|
932
948
|
};
|
|
933
949
|
downloadResult.emit("finish", downloadFinishEvent);
|
|
@@ -962,14 +978,7 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
962
978
|
finalUrl: url.href,
|
|
963
979
|
cookies: config.responseCookies || { array: [], serialized: [], netscape: "", string: "", setCookiesString: [] },
|
|
964
980
|
urls: buildUrlTree(config, url.href),
|
|
965
|
-
timing:
|
|
966
|
-
total: config.timing.durationMs || 0,
|
|
967
|
-
dns: config.timing.dnsMs,
|
|
968
|
-
tcp: config.timing.tcpMs,
|
|
969
|
-
tls: config.timing.tlsMs,
|
|
970
|
-
firstByte: config.timing.ttfbMs,
|
|
971
|
-
download: config.timing.transferMs
|
|
972
|
-
},
|
|
981
|
+
timing: getTimingDurations(config),
|
|
973
982
|
config: sanitizeConfig(config)
|
|
974
983
|
};
|
|
975
984
|
streamResult.emit("finish", streamFinishEvent);
|
|
@@ -992,16 +1001,12 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
992
1001
|
urls: buildUrlTree(config, url.href),
|
|
993
1002
|
uploadSize: config.transfer.requestSize || 0,
|
|
994
1003
|
timing: {
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
tls: config.timing.tlsMs,
|
|
999
|
-
upload: config.timing.transferMs || 0,
|
|
1000
|
-
waiting: config.timing.ttfbMs || 0,
|
|
1001
|
-
download: config.timing.transferMs
|
|
1004
|
+
...getTimingDurations(config),
|
|
1005
|
+
upload: getTimingDurations(config).firstByte || 0,
|
|
1006
|
+
waiting: getTimingDurations(config).download > 0 && getTimingDurations(config).firstByte > 0 ? getTimingDurations(config).download - getTimingDurations(config).firstByte : 0
|
|
1002
1007
|
},
|
|
1003
|
-
averageUploadSpeed: config.
|
|
1004
|
-
averageDownloadSpeed: config.
|
|
1008
|
+
averageUploadSpeed: getTimingDurations(config).firstByte && config.transfer.requestSize ? config.transfer.requestSize / getTimingDurations(config).firstByte * 1000 : 0,
|
|
1009
|
+
averageDownloadSpeed: getTimingDurations(config).download ? contentLengthCounter / getTimingDurations(config).download * 1000 : 0,
|
|
1005
1010
|
config: sanitizeConfig(config)
|
|
1006
1011
|
};
|
|
1007
1012
|
uploadResult.emit("finish", uploadFinishEvent);
|
package/dist/adapters/http2.js
CHANGED
|
@@ -200,6 +200,30 @@ class Http2SessionPool {
|
|
|
200
200
|
this.closeAllSessions();
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
|
+
function updateTiming(config, timing, contentLengthCounter) {
|
|
204
|
+
const now = performance.now();
|
|
205
|
+
config.timing.domainLookupStart = timing.dnsStart || config.timing.startTime;
|
|
206
|
+
config.timing.domainLookupEnd = timing.dnsEnd || timing.dnsStart || config.timing.startTime;
|
|
207
|
+
config.timing.connectStart = timing.tcpStart || timing.dnsEnd || config.timing.startTime;
|
|
208
|
+
config.timing.secureConnectionStart = timing.tlsStart || 0;
|
|
209
|
+
config.timing.connectEnd = timing.tcpEnd || timing.tlsEnd || timing.tcpStart || config.timing.startTime;
|
|
210
|
+
config.timing.requestStart = timing.tcpEnd || config.timing.startTime;
|
|
211
|
+
config.timing.responseStart = timing.firstByteTime || config.timing.requestStart;
|
|
212
|
+
config.timing.responseEnd = now;
|
|
213
|
+
config.transfer.bodySize = contentLengthCounter;
|
|
214
|
+
config.transfer.responseSize = contentLengthCounter;
|
|
215
|
+
}
|
|
216
|
+
function getTimingDurations(config) {
|
|
217
|
+
const t = config.timing;
|
|
218
|
+
return {
|
|
219
|
+
total: t.responseEnd - t.startTime,
|
|
220
|
+
dns: t.domainLookupEnd - t.domainLookupStart,
|
|
221
|
+
tcp: t.secureConnectionStart > 0 ? t.secureConnectionStart - t.connectStart : t.connectEnd - t.connectStart,
|
|
222
|
+
tls: t.secureConnectionStart > 0 ? t.connectEnd - t.secureConnectionStart : undefined,
|
|
223
|
+
firstByte: t.responseStart - t.startTime,
|
|
224
|
+
download: t.responseEnd - t.responseStart
|
|
225
|
+
};
|
|
226
|
+
}
|
|
203
227
|
const responseCacheInstances = new Map;
|
|
204
228
|
function getCacheConfigKey(option) {
|
|
205
229
|
if (option === true)
|
|
@@ -489,10 +513,11 @@ async function executeHttp2Request(fetchOptions, config, options, perform, fs, s
|
|
|
489
513
|
const maxRetries = config?.retry?.maxRetries || 0;
|
|
490
514
|
const incrementDelay = config?.retry?.incrementDelay || false;
|
|
491
515
|
const statusCodes = config?.retry?.statusCodes;
|
|
516
|
+
const startTime = performance.now();
|
|
492
517
|
const timing = {
|
|
493
|
-
startTime
|
|
494
|
-
startTimestamp: Date.now()
|
|
518
|
+
startTime
|
|
495
519
|
};
|
|
520
|
+
config.timing.startTime = startTime;
|
|
496
521
|
const ABSOLUTE_MAX_ATTEMPTS = 50;
|
|
497
522
|
const visitedUrls = new Set;
|
|
498
523
|
let totalAttempts = 0;
|
|
@@ -662,7 +687,6 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
662
687
|
config.isSecure = isSecure;
|
|
663
688
|
config.finalUrl = url.href;
|
|
664
689
|
config.network.protocol = "h2";
|
|
665
|
-
config.timing.startTimestamp = timing.startTimestamp;
|
|
666
690
|
}
|
|
667
691
|
const headers = {
|
|
668
692
|
[http2.constants.HTTP2_HEADER_METHOD]: fetchOptions.method.toUpperCase(),
|
|
@@ -739,9 +763,9 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
739
763
|
responseHeaders = headers;
|
|
740
764
|
status = Number(headers[http2.constants.HTTP2_HEADER_STATUS]) || 200;
|
|
741
765
|
statusText = getStatusText(status);
|
|
742
|
-
if (!
|
|
766
|
+
if (!timing.firstByteTime) {
|
|
743
767
|
timing.firstByteTime = performance.now();
|
|
744
|
-
config.timing.
|
|
768
|
+
config.timing.responseStart = timing.firstByteTime;
|
|
745
769
|
}
|
|
746
770
|
const location = headers["location"];
|
|
747
771
|
const isRedirect = status >= 300 && status < 400 && location;
|
|
@@ -760,8 +784,8 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
760
784
|
contentLength: headers["content-length"] ? parseInt(headers["content-length"], 10) : undefined,
|
|
761
785
|
cookies: config.responseCookies?.array || [],
|
|
762
786
|
timing: {
|
|
763
|
-
firstByte: config.timing.
|
|
764
|
-
total: performance.now() - timing.startTime
|
|
787
|
+
firstByte: config.timing.responseStart - config.timing.startTime,
|
|
788
|
+
total: performance.now() - config.timing.startTime
|
|
765
789
|
}
|
|
766
790
|
};
|
|
767
791
|
eventEmitter.emit("headers", headersEvent);
|
|
@@ -798,9 +822,7 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
798
822
|
}
|
|
799
823
|
});
|
|
800
824
|
req.on("end", async () => {
|
|
801
|
-
config
|
|
802
|
-
config.timing.durationMs = performance.now() - timing.startTime;
|
|
803
|
-
config.timing.transferMs = timing.firstByteTime ? performance.now() - timing.firstByteTime : config.timing.durationMs;
|
|
825
|
+
updateTiming(config, timing, contentLengthCounter);
|
|
804
826
|
if (!config.transfer) {
|
|
805
827
|
config.transfer = { requestSize: 0, responseSize: 0, headerSize: 0, bodySize: 0 };
|
|
806
828
|
}
|
|
@@ -820,8 +842,6 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
820
842
|
config.transfer.requestSize = Buffer.byteLength(JSON.stringify(body), "utf8");
|
|
821
843
|
}
|
|
822
844
|
}
|
|
823
|
-
config.transfer.bodySize = contentLengthCounter;
|
|
824
|
-
config.transfer.responseSize = contentLengthCounter;
|
|
825
845
|
(sessionPool || Http2SessionPool.getInstance()).releaseSession(url);
|
|
826
846
|
if (_stats.statusOnNext === "redirect") {
|
|
827
847
|
const partialResponse = {
|
|
@@ -920,14 +940,10 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
920
940
|
fileName: config.fileName,
|
|
921
941
|
fileSize: responseBody.length,
|
|
922
942
|
timing: {
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
tcp: config.timing.tcpMs,
|
|
926
|
-
tls: config.timing.tlsMs,
|
|
927
|
-
firstByte: config.timing.ttfbMs,
|
|
928
|
-
download: config.timing.transferMs || 0
|
|
943
|
+
...getTimingDurations(config),
|
|
944
|
+
download: getTimingDurations(config).download || 0
|
|
929
945
|
},
|
|
930
|
-
averageSpeed: config.
|
|
946
|
+
averageSpeed: getTimingDurations(config).download ? responseBody.length / getTimingDurations(config).download * 1000 : 0,
|
|
931
947
|
config: sanitizeConfig(config)
|
|
932
948
|
};
|
|
933
949
|
downloadResult.emit("finish", downloadFinishEvent);
|
|
@@ -962,14 +978,7 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
962
978
|
finalUrl: url.href,
|
|
963
979
|
cookies: config.responseCookies || { array: [], serialized: [], netscape: "", string: "", setCookiesString: [] },
|
|
964
980
|
urls: buildUrlTree(config, url.href),
|
|
965
|
-
timing:
|
|
966
|
-
total: config.timing.durationMs || 0,
|
|
967
|
-
dns: config.timing.dnsMs,
|
|
968
|
-
tcp: config.timing.tcpMs,
|
|
969
|
-
tls: config.timing.tlsMs,
|
|
970
|
-
firstByte: config.timing.ttfbMs,
|
|
971
|
-
download: config.timing.transferMs
|
|
972
|
-
},
|
|
981
|
+
timing: getTimingDurations(config),
|
|
973
982
|
config: sanitizeConfig(config)
|
|
974
983
|
};
|
|
975
984
|
streamResult.emit("finish", streamFinishEvent);
|
|
@@ -992,16 +1001,12 @@ async function executeHttp2Stream(config, fetchOptions, requestCount, timing, _s
|
|
|
992
1001
|
urls: buildUrlTree(config, url.href),
|
|
993
1002
|
uploadSize: config.transfer.requestSize || 0,
|
|
994
1003
|
timing: {
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
tls: config.timing.tlsMs,
|
|
999
|
-
upload: config.timing.transferMs || 0,
|
|
1000
|
-
waiting: config.timing.ttfbMs || 0,
|
|
1001
|
-
download: config.timing.transferMs
|
|
1004
|
+
...getTimingDurations(config),
|
|
1005
|
+
upload: getTimingDurations(config).firstByte || 0,
|
|
1006
|
+
waiting: getTimingDurations(config).download > 0 && getTimingDurations(config).firstByte > 0 ? getTimingDurations(config).download - getTimingDurations(config).firstByte : 0
|
|
1002
1007
|
},
|
|
1003
|
-
averageUploadSpeed: config.
|
|
1004
|
-
averageDownloadSpeed: config.
|
|
1008
|
+
averageUploadSpeed: getTimingDurations(config).firstByte && config.transfer.requestSize ? config.transfer.requestSize / getTimingDurations(config).firstByte * 1000 : 0,
|
|
1009
|
+
averageDownloadSpeed: getTimingDurations(config).download ? contentLengthCounter / getTimingDurations(config).download * 1000 : 0,
|
|
1005
1010
|
config: sanitizeConfig(config)
|
|
1006
1011
|
};
|
|
1007
1012
|
uploadResult.emit("finish", uploadFinishEvent);
|
package/dist/adapters/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const
|
|
2
|
-
exports.detectRuntime =
|
|
3
|
-
exports.getAdapterCapabilities =
|
|
4
|
-
exports.buildAdapterContext =
|
|
5
|
-
exports.getAvailableAdapters =
|
|
6
|
-
exports.selectAdapter =
|
|
1
|
+
const _mod_cotolp = require('./picker.cjs');
|
|
2
|
+
exports.detectRuntime = _mod_cotolp.detectRuntime;
|
|
3
|
+
exports.getAdapterCapabilities = _mod_cotolp.getAdapterCapabilities;
|
|
4
|
+
exports.buildAdapterContext = _mod_cotolp.buildAdapterContext;
|
|
5
|
+
exports.getAvailableAdapters = _mod_cotolp.getAvailableAdapters;
|
|
6
|
+
exports.selectAdapter = _mod_cotolp.selectAdapter;;
|
|
@@ -17,6 +17,30 @@ const Environment = {
|
|
|
17
17
|
hasFormData: typeof FormData !== "undefined",
|
|
18
18
|
hasAbortController: typeof AbortController !== "undefined"
|
|
19
19
|
};
|
|
20
|
+
function updateTiming(config, timing, bodySize) {
|
|
21
|
+
const now = performance.now();
|
|
22
|
+
config.timing.domainLookupStart = config.timing.startTime;
|
|
23
|
+
config.timing.domainLookupEnd = config.timing.startTime;
|
|
24
|
+
config.timing.connectStart = config.timing.startTime;
|
|
25
|
+
config.timing.secureConnectionStart = 0;
|
|
26
|
+
config.timing.connectEnd = config.timing.startTime;
|
|
27
|
+
config.timing.requestStart = config.timing.startTime;
|
|
28
|
+
config.timing.responseStart = timing.firstByteTime || config.timing.startTime;
|
|
29
|
+
config.timing.responseEnd = now;
|
|
30
|
+
config.transfer.bodySize = bodySize;
|
|
31
|
+
config.transfer.responseSize = bodySize;
|
|
32
|
+
}
|
|
33
|
+
function getTimingDurations(config) {
|
|
34
|
+
const t = config.timing;
|
|
35
|
+
return {
|
|
36
|
+
total: t.responseEnd - t.startTime,
|
|
37
|
+
dns: t.domainLookupEnd - t.domainLookupStart,
|
|
38
|
+
tcp: t.secureConnectionStart > 0 ? t.secureConnectionStart - t.connectStart : t.connectEnd - t.connectStart,
|
|
39
|
+
tls: t.secureConnectionStart > 0 ? t.connectEnd - t.secureConnectionStart : undefined,
|
|
40
|
+
firstByte: t.responseStart - t.startTime,
|
|
41
|
+
download: t.responseEnd - t.responseStart
|
|
42
|
+
};
|
|
43
|
+
}
|
|
20
44
|
const responseCacheInstances = new Map;
|
|
21
45
|
function getCacheConfigKey(option) {
|
|
22
46
|
if (option === true)
|
|
@@ -227,10 +251,11 @@ async function executeFetchRequest(fetchOptions, config, options, perform, strea
|
|
|
227
251
|
const maxRetries = config?.retry?.maxRetries || 0;
|
|
228
252
|
const incrementDelay = config?.retry?.incrementDelay || false;
|
|
229
253
|
const statusCodes = config?.retry?.statusCodes;
|
|
254
|
+
const startTime = performance.now();
|
|
230
255
|
const timing = {
|
|
231
|
-
startTime
|
|
232
|
-
startTimestamp: Date.now()
|
|
256
|
+
startTime
|
|
233
257
|
};
|
|
258
|
+
config.timing.startTime = startTime;
|
|
234
259
|
const ABSOLUTE_MAX_ATTEMPTS = 50;
|
|
235
260
|
let totalAttempts = 0;
|
|
236
261
|
config.setSignal();
|
|
@@ -294,7 +319,6 @@ async function executeSingleRequest(config, fetchOptions, timing, streamResult,
|
|
|
294
319
|
config.isSecure = isSecure;
|
|
295
320
|
config.finalUrl = url;
|
|
296
321
|
config.network.protocol = isSecure ? "https" : "http";
|
|
297
|
-
config.timing.startTimestamp = timing.startTimestamp;
|
|
298
322
|
const reqHeaders = fetchOptions.headers instanceof RezoHeaders ? fetchOptions.headers.toObject() : fetchOptions.headers || {};
|
|
299
323
|
const headers = toFetchHeaders(reqHeaders);
|
|
300
324
|
const eventEmitter = streamResult || downloadResult || uploadResult;
|
|
@@ -347,9 +371,9 @@ async function executeSingleRequest(config, fetchOptions, timing, streamResult,
|
|
|
347
371
|
if (timeoutId)
|
|
348
372
|
clearTimeout(timeoutId);
|
|
349
373
|
}
|
|
350
|
-
if (!
|
|
374
|
+
if (!timing.firstByteTime) {
|
|
351
375
|
timing.firstByteTime = performance.now();
|
|
352
|
-
config.timing.
|
|
376
|
+
config.timing.responseStart = timing.firstByteTime;
|
|
353
377
|
}
|
|
354
378
|
const status = response.status;
|
|
355
379
|
const statusText = response.statusText;
|
|
@@ -373,8 +397,8 @@ async function executeSingleRequest(config, fetchOptions, timing, streamResult,
|
|
|
373
397
|
contentLength: contentLength ? parseInt(contentLength, 10) : undefined,
|
|
374
398
|
cookies: cookies.array,
|
|
375
399
|
timing: {
|
|
376
|
-
firstByte: config.timing.
|
|
377
|
-
total: performance.now() - timing.startTime
|
|
400
|
+
firstByte: config.timing.responseStart - config.timing.startTime,
|
|
401
|
+
total: performance.now() - config.timing.startTime
|
|
378
402
|
}
|
|
379
403
|
};
|
|
380
404
|
eventEmitter.emit("headers", headersEvent);
|
|
@@ -428,11 +452,7 @@ async function executeSingleRequest(config, fetchOptions, timing, streamResult,
|
|
|
428
452
|
bodySize = text.length;
|
|
429
453
|
}
|
|
430
454
|
}
|
|
431
|
-
config
|
|
432
|
-
config.timing.durationMs = performance.now() - timing.startTime;
|
|
433
|
-
config.timing.transferMs = timing.firstByteTime ? performance.now() - timing.firstByteTime : config.timing.durationMs;
|
|
434
|
-
config.transfer.bodySize = bodySize;
|
|
435
|
-
config.transfer.responseSize = bodySize;
|
|
455
|
+
updateTiming(config, timing, bodySize);
|
|
436
456
|
if (status >= 400) {
|
|
437
457
|
const error = builErrorFromResponse(`HTTP Error ${status}: ${statusText}`, {
|
|
438
458
|
status,
|
|
@@ -466,11 +486,7 @@ async function executeSingleRequest(config, fetchOptions, timing, streamResult,
|
|
|
466
486
|
finalUrl: url,
|
|
467
487
|
cookies,
|
|
468
488
|
urls: buildUrlTree(config, url),
|
|
469
|
-
timing:
|
|
470
|
-
total: config.timing.durationMs || 0,
|
|
471
|
-
firstByte: config.timing.ttfbMs,
|
|
472
|
-
download: config.timing.transferMs
|
|
473
|
-
},
|
|
489
|
+
timing: getTimingDurations(config),
|
|
474
490
|
config: sanitizeConfig(config)
|
|
475
491
|
};
|
|
476
492
|
streamResult.emit("finish", streamFinishEvent);
|
|
@@ -491,11 +507,10 @@ async function executeSingleRequest(config, fetchOptions, timing, streamResult,
|
|
|
491
507
|
fileName: config.fileName || "",
|
|
492
508
|
fileSize: bodySize,
|
|
493
509
|
timing: {
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
download: config.timing.transferMs || 0
|
|
510
|
+
...getTimingDurations(config),
|
|
511
|
+
download: getTimingDurations(config).download || 0
|
|
497
512
|
},
|
|
498
|
-
averageSpeed: config.
|
|
513
|
+
averageSpeed: getTimingDurations(config).download ? bodySize / getTimingDurations(config).download * 1000 : 0,
|
|
499
514
|
config: sanitizeConfig(config)
|
|
500
515
|
};
|
|
501
516
|
downloadResult.emit("finish", downloadFinishEvent);
|
|
@@ -517,13 +532,12 @@ async function executeSingleRequest(config, fetchOptions, timing, streamResult,
|
|
|
517
532
|
urls: buildUrlTree(config, url),
|
|
518
533
|
uploadSize: config.transfer.requestSize || 0,
|
|
519
534
|
timing: {
|
|
520
|
-
|
|
521
|
-
upload: config.
|
|
522
|
-
waiting: config.
|
|
523
|
-
download: config.timing.transferMs
|
|
535
|
+
...getTimingDurations(config),
|
|
536
|
+
upload: getTimingDurations(config).firstByte || 0,
|
|
537
|
+
waiting: getTimingDurations(config).download > 0 && getTimingDurations(config).firstByte > 0 ? getTimingDurations(config).download - getTimingDurations(config).firstByte : 0
|
|
524
538
|
},
|
|
525
|
-
averageUploadSpeed: config.
|
|
526
|
-
averageDownloadSpeed: config.
|
|
539
|
+
averageUploadSpeed: getTimingDurations(config).firstByte && config.transfer.requestSize ? config.transfer.requestSize / getTimingDurations(config).firstByte * 1000 : 0,
|
|
540
|
+
averageDownloadSpeed: getTimingDurations(config).download ? bodySize / getTimingDurations(config).download * 1000 : 0,
|
|
527
541
|
config: sanitizeConfig(config)
|
|
528
542
|
};
|
|
529
543
|
uploadResult.emit("finish", uploadFinishEvent);
|