rezo 1.0.46 → 1.0.47

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.
@@ -22,6 +22,7 @@ const { ResponseCache } = require('../cache/response-cache.cjs');
22
22
  const { getGlobalAgentPool } = require('../utils/agent-pool.cjs');
23
23
  const { StagedTimeoutManager, parseStagedTimeouts } = require('../utils/staged-timeout.cjs');
24
24
  const { handleRateLimitWait, shouldWaitOnStatus } = require('../utils/rate-limit-wait.cjs');
25
+ const { getSocketTelemetry, beginRequestContext } = require('../utils/socket-telemetry.cjs');
25
26
  const dns = require("node:dns");
26
27
  const debugLog = {
27
28
  requestStart: (config, url, method) => {
@@ -1029,149 +1030,188 @@ async function request(config, fetchOptions, requestCount, timing, _stats, respo
1029
1030
  }
1030
1031
  resolve(error);
1031
1032
  });
1032
- const isAlreadyConnected = !socket.connecting && (socket.readyState === "open" || socket.writable === true);
1033
- if (isAlreadyConnected) {
1034
- timeoutManager.clearPhase("connect");
1035
- if (timeoutManager.hasPhase("headers")) {
1036
- timeoutManager.startPhase("headers");
1037
- }
1038
- } else {
1039
- if (timeoutManager.hasPhase("connect")) {
1040
- timeoutManager.startPhase("connect");
1041
- }
1042
- }
1033
+ const reqContext = beginRequestContext(socket, isSecure);
1034
+ const telemetry = getSocketTelemetry(socket);
1043
1035
  socket.once("error", (err) => {
1044
1036
  timeoutManager.clearAll();
1045
1037
  _stats.statusOnNext = "error";
1046
1038
  const error = buildSmartError(config, fetchOptions, err);
1047
1039
  resolve(error);
1048
1040
  });
1049
- timing.dnsStart = performance.now();
1050
- config.timing.domainLookupStart = timing.dnsStart;
1051
- socket.once("lookup", (err, address, family) => {
1052
- if (!timing.dnsEnd) {
1053
- timing.dnsEnd = performance.now();
1054
- config.timing.domainLookupEnd = timing.dnsEnd;
1055
- timing.tcpStart = performance.now();
1056
- config.timing.connectStart = timing.tcpStart;
1057
- }
1058
- if (config.hooks?.onDns && config.hooks.onDns.length > 0) {
1059
- const familyNum = typeof family === "number" ? family : family === "IPv6" ? 6 : 4;
1060
- for (const hook of config.hooks.onDns) {
1061
- try {
1062
- hook({
1063
- hostname: url.hostname,
1064
- address: address || "",
1065
- family: familyNum,
1066
- duration: timing.dnsEnd - timing.dnsStart,
1067
- timestamp: Date.now()
1068
- }, config);
1069
- } catch (err) {
1070
- if (config.debug) {
1071
- console.log("[Rezo Debug] onDns hook error:", err);
1072
- }
1073
- }
1074
- }
1075
- }
1076
- });
1077
- socket.once("secureConnect", () => {
1041
+ if (reqContext.connectionReused) {
1078
1042
  timeoutManager.clearPhase("connect");
1079
1043
  if (timeoutManager.hasPhase("headers")) {
1080
1044
  timeoutManager.startPhase("headers");
1081
1045
  }
1082
- if (!timing.tlsEnd && timing.tlsStart) {
1083
- timing.tlsEnd = performance.now();
1084
- config.timing.connectEnd = timing.tlsEnd;
1046
+ if (telemetry) {
1047
+ config.timing.domainLookupStart = timing.dnsStart = performance.now();
1048
+ config.timing.domainLookupEnd = timing.dnsEnd = timing.dnsStart;
1049
+ config.timing.connectStart = timing.tcpStart = timing.dnsEnd;
1050
+ config.timing.connectEnd = timing.tcpEnd = timing.tcpStart;
1051
+ if (telemetry.network.remoteAddress) {
1052
+ config.network.remoteAddress = telemetry.network.remoteAddress;
1053
+ config.network.remotePort = telemetry.network.remotePort;
1054
+ config.network.localAddress = telemetry.network.localAddress;
1055
+ config.network.localPort = telemetry.network.localPort;
1056
+ config.network.family = telemetry.network.family;
1057
+ }
1058
+ if (isSecure && telemetry.tls) {
1059
+ config.security.tlsVersion = telemetry.tls.protocol;
1060
+ config.security.cipher = telemetry.tls.cipher;
1061
+ if (telemetry.tls.certificate) {
1062
+ config.security.certificateInfo = {
1063
+ subject: { CN: telemetry.tls.certificate.subject },
1064
+ issuer: { CN: telemetry.tls.certificate.issuer },
1065
+ validFrom: telemetry.tls.certificate.validFrom,
1066
+ validTo: telemetry.tls.certificate.validTo,
1067
+ fingerprint: telemetry.tls.certificate.fingerprint
1068
+ };
1069
+ }
1070
+ }
1071
+ config.connectionReuse = {
1072
+ reused: true,
1073
+ reuseCount: telemetry.reuse.count,
1074
+ socketAge: Date.now() - telemetry.timings.created,
1075
+ historicalDns: telemetry.timings.dnsDuration || 0,
1076
+ historicalTcp: telemetry.timings.tcpDuration || 0,
1077
+ historicalTls: telemetry.timings.tlsDuration || 0
1078
+ };
1085
1079
  }
1086
- const tls = {
1087
- cipher: socket.getCipher(),
1088
- cert: socket.getPeerCertificate(),
1089
- tlsVersion: socket.getProtocol()
1090
- };
1091
- const { cipher, cert, tlsVersion } = tls;
1092
- config.security.tlsVersion = tlsVersion;
1093
- config.security.cipher = cipher?.name;
1094
- config.security.certificateInfo = {
1095
- subject: cert.subject,
1096
- issuer: cert.issuer,
1097
- validFrom: cert.valid_from,
1098
- validTo: cert.valid_to,
1099
- fingerprint: cert.fingerprint
1100
- };
1101
- config.security.validationResults = {
1102
- certificateValid: !cert.fingerprint?.includes("error"),
1103
- hostnameMatch: cert.subject?.CN === url.hostname,
1104
- chainValid: socket.authorized === true,
1105
- authorizationError: socket.authorizationError || null
1080
+ } else {
1081
+ if (timeoutManager.hasPhase("connect")) {
1082
+ timeoutManager.startPhase("connect");
1083
+ }
1084
+ timing.dnsStart = performance.now();
1085
+ config.timing.domainLookupStart = timing.dnsStart;
1086
+ config.connectionReuse = {
1087
+ reused: false,
1088
+ reuseCount: 1
1106
1089
  };
1107
- if (config.hooks?.onTls && config.hooks.onTls.length > 0) {
1108
- for (const hook of config.hooks.onTls) {
1109
- try {
1110
- hook({
1111
- protocol: tlsVersion,
1112
- cipher: cipher?.name || "",
1113
- authorized: !socket.authorizationError,
1114
- authorizationError: socket.authorizationError,
1115
- certificate: cert ? {
1116
- subject: cert.subject?.CN || "",
1117
- issuer: cert.issuer?.CN || "",
1118
- validFrom: cert.valid_from || "",
1119
- validTo: cert.valid_to || "",
1120
- fingerprint: cert.fingerprint || ""
1121
- } : undefined,
1122
- duration: timing.tlsEnd - timing.tlsStart,
1123
- timestamp: Date.now()
1124
- }, config);
1125
- } catch (err) {
1126
- if (config.debug) {
1127
- console.log("[Rezo Debug] onTls hook error:", err);
1090
+ const populateFromTelemetry = () => {
1091
+ if (!telemetry)
1092
+ return;
1093
+ if (telemetry.timings.dnsEnd && !timing.dnsEnd) {
1094
+ timing.dnsEnd = performance.now();
1095
+ config.timing.domainLookupEnd = timing.dnsEnd;
1096
+ timing.tcpStart = performance.now();
1097
+ config.timing.connectStart = timing.tcpStart;
1098
+ if (config.hooks?.onDns && config.hooks.onDns.length > 0) {
1099
+ for (const hook of config.hooks.onDns) {
1100
+ try {
1101
+ hook({
1102
+ hostname: url.hostname,
1103
+ address: telemetry.timings.address || "",
1104
+ family: telemetry.timings.family || 4,
1105
+ duration: telemetry.timings.dnsDuration || 0,
1106
+ timestamp: Date.now()
1107
+ }, config);
1108
+ } catch (err) {
1109
+ if (config.debug) {
1110
+ console.log("[Rezo Debug] onDns hook error:", err);
1111
+ }
1112
+ }
1128
1113
  }
1129
1114
  }
1130
1115
  }
1131
- }
1132
- });
1133
- socket.once("connect", () => {
1134
- if (!isSecure) {
1135
- timeoutManager.clearPhase("connect");
1136
- if (timeoutManager.hasPhase("headers")) {
1137
- timeoutManager.startPhase("headers");
1138
- }
1139
- }
1140
- if (!timing.tcpEnd) {
1141
- timing.tcpEnd = performance.now();
1142
- config.timing.connectEnd = timing.tcpEnd;
1143
- if (isSecure) {
1144
- timing.tlsStart = performance.now();
1145
- config.timing.secureConnectionStart = timing.tlsStart;
1116
+ if (telemetry.timings.connectEnd && !timing.tcpEnd) {
1117
+ timing.tcpEnd = performance.now();
1118
+ config.timing.connectEnd = timing.tcpEnd;
1119
+ if (isSecure) {
1120
+ timing.tlsStart = performance.now();
1121
+ config.timing.secureConnectionStart = timing.tlsStart;
1122
+ }
1123
+ if (telemetry.network.remoteAddress) {
1124
+ config.network.remoteAddress = telemetry.network.remoteAddress;
1125
+ config.network.remotePort = telemetry.network.remotePort;
1126
+ config.network.localAddress = telemetry.network.localAddress;
1127
+ config.network.localPort = telemetry.network.localPort;
1128
+ config.network.family = telemetry.network.family;
1129
+ }
1130
+ if (config.hooks?.onSocket && config.hooks.onSocket.length > 0) {
1131
+ for (const hook of config.hooks.onSocket) {
1132
+ try {
1133
+ hook({
1134
+ type: "connect",
1135
+ localAddress: telemetry.network.localAddress,
1136
+ localPort: telemetry.network.localPort,
1137
+ remoteAddress: telemetry.network.remoteAddress,
1138
+ remotePort: telemetry.network.remotePort,
1139
+ timestamp: Date.now()
1140
+ }, socket);
1141
+ } catch (err) {
1142
+ if (config.debug) {
1143
+ console.log("[Rezo Debug] onSocket hook error:", err);
1144
+ }
1145
+ }
1146
+ }
1147
+ }
1148
+ if (!isSecure) {
1149
+ timeoutManager.clearPhase("connect");
1150
+ if (timeoutManager.hasPhase("headers")) {
1151
+ timeoutManager.startPhase("headers");
1152
+ }
1153
+ }
1146
1154
  }
1147
- }
1148
- const { remoteAddress, remotePort, localAddress, localPort, remoteFamily } = socket;
1149
- if (remoteAddress && !config.network.remoteAddress) {
1150
- config.network.remoteAddress = remoteAddress;
1151
- config.network.remotePort = remotePort;
1152
- config.network.localAddress = localAddress;
1153
- config.network.localPort = localPort;
1154
- config.network.family = remoteFamily;
1155
- }
1156
- if (config.hooks?.onSocket && config.hooks.onSocket.length > 0) {
1157
- for (const hook of config.hooks.onSocket) {
1158
- try {
1159
- hook({
1160
- type: "connect",
1161
- localAddress,
1162
- localPort,
1163
- remoteAddress,
1164
- remotePort,
1165
- timestamp: Date.now()
1166
- }, socket);
1167
- } catch (err) {
1168
- if (config.debug) {
1169
- console.log("[Rezo Debug] onSocket hook error:", err);
1155
+ if (isSecure && telemetry.timings.secureConnectEnd && !timing.tlsEnd) {
1156
+ timing.tlsEnd = performance.now();
1157
+ config.timing.connectEnd = timing.tlsEnd;
1158
+ timeoutManager.clearPhase("connect");
1159
+ if (timeoutManager.hasPhase("headers")) {
1160
+ timeoutManager.startPhase("headers");
1161
+ }
1162
+ if (telemetry.tls) {
1163
+ config.security.tlsVersion = telemetry.tls.protocol;
1164
+ config.security.cipher = telemetry.tls.cipher;
1165
+ config.security.certificateInfo = telemetry.tls.certificate ? {
1166
+ subject: { CN: telemetry.tls.certificate.subject },
1167
+ issuer: { CN: telemetry.tls.certificate.issuer },
1168
+ validFrom: telemetry.tls.certificate.validFrom,
1169
+ validTo: telemetry.tls.certificate.validTo,
1170
+ fingerprint: telemetry.tls.certificate.fingerprint
1171
+ } : undefined;
1172
+ config.security.validationResults = {
1173
+ certificateValid: true,
1174
+ hostnameMatch: telemetry.tls.certificate?.subject === url.hostname || false,
1175
+ chainValid: telemetry.tls.authorized === true,
1176
+ authorizationError: telemetry.tls.authorizationError ? true : false
1177
+ };
1178
+ if (config.hooks?.onTls && config.hooks.onTls.length > 0) {
1179
+ for (const hook of config.hooks.onTls) {
1180
+ try {
1181
+ hook({
1182
+ protocol: telemetry.tls.protocol || "",
1183
+ cipher: telemetry.tls.cipher || "",
1184
+ authorized: telemetry.tls.authorized !== false,
1185
+ authorizationError: telemetry.tls.authorizationError,
1186
+ certificate: telemetry.tls.certificate ? {
1187
+ subject: telemetry.tls.certificate.subject || "",
1188
+ issuer: telemetry.tls.certificate.issuer || "",
1189
+ validFrom: telemetry.tls.certificate.validFrom || "",
1190
+ validTo: telemetry.tls.certificate.validTo || "",
1191
+ fingerprint: telemetry.tls.certificate.fingerprint || ""
1192
+ } : undefined,
1193
+ duration: telemetry.timings.tlsDuration || 0,
1194
+ timestamp: Date.now()
1195
+ }, config);
1196
+ } catch (err) {
1197
+ if (config.debug) {
1198
+ console.log("[Rezo Debug] onTls hook error:", err);
1199
+ }
1200
+ }
1201
+ }
1170
1202
  }
1171
1203
  }
1172
1204
  }
1173
- }
1174
- });
1205
+ };
1206
+ const checkTelemetry = setInterval(() => {
1207
+ if (telemetry?.connected || telemetry?.closed) {
1208
+ clearInterval(checkTelemetry);
1209
+ populateFromTelemetry();
1210
+ }
1211
+ }, 1);
1212
+ socket.once("close", () => clearInterval(checkTelemetry));
1213
+ setTimeout(() => clearInterval(checkTelemetry), 30000);
1214
+ }
1175
1215
  });
1176
1216
  req.on("error", (error) => {
1177
1217
  timeoutManager.clearAll();
@@ -22,6 +22,7 @@ import { ResponseCache } from '../cache/response-cache.js';
22
22
  import { getGlobalAgentPool } from '../utils/agent-pool.js';
23
23
  import { StagedTimeoutManager, parseStagedTimeouts } from '../utils/staged-timeout.js';
24
24
  import { handleRateLimitWait, shouldWaitOnStatus } from '../utils/rate-limit-wait.js';
25
+ import { getSocketTelemetry, beginRequestContext } from '../utils/socket-telemetry.js';
25
26
  import dns from "node:dns";
26
27
  const debugLog = {
27
28
  requestStart: (config, url, method) => {
@@ -1029,149 +1030,188 @@ async function request(config, fetchOptions, requestCount, timing, _stats, respo
1029
1030
  }
1030
1031
  resolve(error);
1031
1032
  });
1032
- const isAlreadyConnected = !socket.connecting && (socket.readyState === "open" || socket.writable === true);
1033
- if (isAlreadyConnected) {
1034
- timeoutManager.clearPhase("connect");
1035
- if (timeoutManager.hasPhase("headers")) {
1036
- timeoutManager.startPhase("headers");
1037
- }
1038
- } else {
1039
- if (timeoutManager.hasPhase("connect")) {
1040
- timeoutManager.startPhase("connect");
1041
- }
1042
- }
1033
+ const reqContext = beginRequestContext(socket, isSecure);
1034
+ const telemetry = getSocketTelemetry(socket);
1043
1035
  socket.once("error", (err) => {
1044
1036
  timeoutManager.clearAll();
1045
1037
  _stats.statusOnNext = "error";
1046
1038
  const error = buildSmartError(config, fetchOptions, err);
1047
1039
  resolve(error);
1048
1040
  });
1049
- timing.dnsStart = performance.now();
1050
- config.timing.domainLookupStart = timing.dnsStart;
1051
- socket.once("lookup", (err, address, family) => {
1052
- if (!timing.dnsEnd) {
1053
- timing.dnsEnd = performance.now();
1054
- config.timing.domainLookupEnd = timing.dnsEnd;
1055
- timing.tcpStart = performance.now();
1056
- config.timing.connectStart = timing.tcpStart;
1057
- }
1058
- if (config.hooks?.onDns && config.hooks.onDns.length > 0) {
1059
- const familyNum = typeof family === "number" ? family : family === "IPv6" ? 6 : 4;
1060
- for (const hook of config.hooks.onDns) {
1061
- try {
1062
- hook({
1063
- hostname: url.hostname,
1064
- address: address || "",
1065
- family: familyNum,
1066
- duration: timing.dnsEnd - timing.dnsStart,
1067
- timestamp: Date.now()
1068
- }, config);
1069
- } catch (err) {
1070
- if (config.debug) {
1071
- console.log("[Rezo Debug] onDns hook error:", err);
1072
- }
1073
- }
1074
- }
1075
- }
1076
- });
1077
- socket.once("secureConnect", () => {
1041
+ if (reqContext.connectionReused) {
1078
1042
  timeoutManager.clearPhase("connect");
1079
1043
  if (timeoutManager.hasPhase("headers")) {
1080
1044
  timeoutManager.startPhase("headers");
1081
1045
  }
1082
- if (!timing.tlsEnd && timing.tlsStart) {
1083
- timing.tlsEnd = performance.now();
1084
- config.timing.connectEnd = timing.tlsEnd;
1046
+ if (telemetry) {
1047
+ config.timing.domainLookupStart = timing.dnsStart = performance.now();
1048
+ config.timing.domainLookupEnd = timing.dnsEnd = timing.dnsStart;
1049
+ config.timing.connectStart = timing.tcpStart = timing.dnsEnd;
1050
+ config.timing.connectEnd = timing.tcpEnd = timing.tcpStart;
1051
+ if (telemetry.network.remoteAddress) {
1052
+ config.network.remoteAddress = telemetry.network.remoteAddress;
1053
+ config.network.remotePort = telemetry.network.remotePort;
1054
+ config.network.localAddress = telemetry.network.localAddress;
1055
+ config.network.localPort = telemetry.network.localPort;
1056
+ config.network.family = telemetry.network.family;
1057
+ }
1058
+ if (isSecure && telemetry.tls) {
1059
+ config.security.tlsVersion = telemetry.tls.protocol;
1060
+ config.security.cipher = telemetry.tls.cipher;
1061
+ if (telemetry.tls.certificate) {
1062
+ config.security.certificateInfo = {
1063
+ subject: { CN: telemetry.tls.certificate.subject },
1064
+ issuer: { CN: telemetry.tls.certificate.issuer },
1065
+ validFrom: telemetry.tls.certificate.validFrom,
1066
+ validTo: telemetry.tls.certificate.validTo,
1067
+ fingerprint: telemetry.tls.certificate.fingerprint
1068
+ };
1069
+ }
1070
+ }
1071
+ config.connectionReuse = {
1072
+ reused: true,
1073
+ reuseCount: telemetry.reuse.count,
1074
+ socketAge: Date.now() - telemetry.timings.created,
1075
+ historicalDns: telemetry.timings.dnsDuration || 0,
1076
+ historicalTcp: telemetry.timings.tcpDuration || 0,
1077
+ historicalTls: telemetry.timings.tlsDuration || 0
1078
+ };
1085
1079
  }
1086
- const tls = {
1087
- cipher: socket.getCipher(),
1088
- cert: socket.getPeerCertificate(),
1089
- tlsVersion: socket.getProtocol()
1090
- };
1091
- const { cipher, cert, tlsVersion } = tls;
1092
- config.security.tlsVersion = tlsVersion;
1093
- config.security.cipher = cipher?.name;
1094
- config.security.certificateInfo = {
1095
- subject: cert.subject,
1096
- issuer: cert.issuer,
1097
- validFrom: cert.valid_from,
1098
- validTo: cert.valid_to,
1099
- fingerprint: cert.fingerprint
1100
- };
1101
- config.security.validationResults = {
1102
- certificateValid: !cert.fingerprint?.includes("error"),
1103
- hostnameMatch: cert.subject?.CN === url.hostname,
1104
- chainValid: socket.authorized === true,
1105
- authorizationError: socket.authorizationError || null
1080
+ } else {
1081
+ if (timeoutManager.hasPhase("connect")) {
1082
+ timeoutManager.startPhase("connect");
1083
+ }
1084
+ timing.dnsStart = performance.now();
1085
+ config.timing.domainLookupStart = timing.dnsStart;
1086
+ config.connectionReuse = {
1087
+ reused: false,
1088
+ reuseCount: 1
1106
1089
  };
1107
- if (config.hooks?.onTls && config.hooks.onTls.length > 0) {
1108
- for (const hook of config.hooks.onTls) {
1109
- try {
1110
- hook({
1111
- protocol: tlsVersion,
1112
- cipher: cipher?.name || "",
1113
- authorized: !socket.authorizationError,
1114
- authorizationError: socket.authorizationError,
1115
- certificate: cert ? {
1116
- subject: cert.subject?.CN || "",
1117
- issuer: cert.issuer?.CN || "",
1118
- validFrom: cert.valid_from || "",
1119
- validTo: cert.valid_to || "",
1120
- fingerprint: cert.fingerprint || ""
1121
- } : undefined,
1122
- duration: timing.tlsEnd - timing.tlsStart,
1123
- timestamp: Date.now()
1124
- }, config);
1125
- } catch (err) {
1126
- if (config.debug) {
1127
- console.log("[Rezo Debug] onTls hook error:", err);
1090
+ const populateFromTelemetry = () => {
1091
+ if (!telemetry)
1092
+ return;
1093
+ if (telemetry.timings.dnsEnd && !timing.dnsEnd) {
1094
+ timing.dnsEnd = performance.now();
1095
+ config.timing.domainLookupEnd = timing.dnsEnd;
1096
+ timing.tcpStart = performance.now();
1097
+ config.timing.connectStart = timing.tcpStart;
1098
+ if (config.hooks?.onDns && config.hooks.onDns.length > 0) {
1099
+ for (const hook of config.hooks.onDns) {
1100
+ try {
1101
+ hook({
1102
+ hostname: url.hostname,
1103
+ address: telemetry.timings.address || "",
1104
+ family: telemetry.timings.family || 4,
1105
+ duration: telemetry.timings.dnsDuration || 0,
1106
+ timestamp: Date.now()
1107
+ }, config);
1108
+ } catch (err) {
1109
+ if (config.debug) {
1110
+ console.log("[Rezo Debug] onDns hook error:", err);
1111
+ }
1112
+ }
1128
1113
  }
1129
1114
  }
1130
1115
  }
1131
- }
1132
- });
1133
- socket.once("connect", () => {
1134
- if (!isSecure) {
1135
- timeoutManager.clearPhase("connect");
1136
- if (timeoutManager.hasPhase("headers")) {
1137
- timeoutManager.startPhase("headers");
1138
- }
1139
- }
1140
- if (!timing.tcpEnd) {
1141
- timing.tcpEnd = performance.now();
1142
- config.timing.connectEnd = timing.tcpEnd;
1143
- if (isSecure) {
1144
- timing.tlsStart = performance.now();
1145
- config.timing.secureConnectionStart = timing.tlsStart;
1116
+ if (telemetry.timings.connectEnd && !timing.tcpEnd) {
1117
+ timing.tcpEnd = performance.now();
1118
+ config.timing.connectEnd = timing.tcpEnd;
1119
+ if (isSecure) {
1120
+ timing.tlsStart = performance.now();
1121
+ config.timing.secureConnectionStart = timing.tlsStart;
1122
+ }
1123
+ if (telemetry.network.remoteAddress) {
1124
+ config.network.remoteAddress = telemetry.network.remoteAddress;
1125
+ config.network.remotePort = telemetry.network.remotePort;
1126
+ config.network.localAddress = telemetry.network.localAddress;
1127
+ config.network.localPort = telemetry.network.localPort;
1128
+ config.network.family = telemetry.network.family;
1129
+ }
1130
+ if (config.hooks?.onSocket && config.hooks.onSocket.length > 0) {
1131
+ for (const hook of config.hooks.onSocket) {
1132
+ try {
1133
+ hook({
1134
+ type: "connect",
1135
+ localAddress: telemetry.network.localAddress,
1136
+ localPort: telemetry.network.localPort,
1137
+ remoteAddress: telemetry.network.remoteAddress,
1138
+ remotePort: telemetry.network.remotePort,
1139
+ timestamp: Date.now()
1140
+ }, socket);
1141
+ } catch (err) {
1142
+ if (config.debug) {
1143
+ console.log("[Rezo Debug] onSocket hook error:", err);
1144
+ }
1145
+ }
1146
+ }
1147
+ }
1148
+ if (!isSecure) {
1149
+ timeoutManager.clearPhase("connect");
1150
+ if (timeoutManager.hasPhase("headers")) {
1151
+ timeoutManager.startPhase("headers");
1152
+ }
1153
+ }
1146
1154
  }
1147
- }
1148
- const { remoteAddress, remotePort, localAddress, localPort, remoteFamily } = socket;
1149
- if (remoteAddress && !config.network.remoteAddress) {
1150
- config.network.remoteAddress = remoteAddress;
1151
- config.network.remotePort = remotePort;
1152
- config.network.localAddress = localAddress;
1153
- config.network.localPort = localPort;
1154
- config.network.family = remoteFamily;
1155
- }
1156
- if (config.hooks?.onSocket && config.hooks.onSocket.length > 0) {
1157
- for (const hook of config.hooks.onSocket) {
1158
- try {
1159
- hook({
1160
- type: "connect",
1161
- localAddress,
1162
- localPort,
1163
- remoteAddress,
1164
- remotePort,
1165
- timestamp: Date.now()
1166
- }, socket);
1167
- } catch (err) {
1168
- if (config.debug) {
1169
- console.log("[Rezo Debug] onSocket hook error:", err);
1155
+ if (isSecure && telemetry.timings.secureConnectEnd && !timing.tlsEnd) {
1156
+ timing.tlsEnd = performance.now();
1157
+ config.timing.connectEnd = timing.tlsEnd;
1158
+ timeoutManager.clearPhase("connect");
1159
+ if (timeoutManager.hasPhase("headers")) {
1160
+ timeoutManager.startPhase("headers");
1161
+ }
1162
+ if (telemetry.tls) {
1163
+ config.security.tlsVersion = telemetry.tls.protocol;
1164
+ config.security.cipher = telemetry.tls.cipher;
1165
+ config.security.certificateInfo = telemetry.tls.certificate ? {
1166
+ subject: { CN: telemetry.tls.certificate.subject },
1167
+ issuer: { CN: telemetry.tls.certificate.issuer },
1168
+ validFrom: telemetry.tls.certificate.validFrom,
1169
+ validTo: telemetry.tls.certificate.validTo,
1170
+ fingerprint: telemetry.tls.certificate.fingerprint
1171
+ } : undefined;
1172
+ config.security.validationResults = {
1173
+ certificateValid: true,
1174
+ hostnameMatch: telemetry.tls.certificate?.subject === url.hostname || false,
1175
+ chainValid: telemetry.tls.authorized === true,
1176
+ authorizationError: telemetry.tls.authorizationError ? true : false
1177
+ };
1178
+ if (config.hooks?.onTls && config.hooks.onTls.length > 0) {
1179
+ for (const hook of config.hooks.onTls) {
1180
+ try {
1181
+ hook({
1182
+ protocol: telemetry.tls.protocol || "",
1183
+ cipher: telemetry.tls.cipher || "",
1184
+ authorized: telemetry.tls.authorized !== false,
1185
+ authorizationError: telemetry.tls.authorizationError,
1186
+ certificate: telemetry.tls.certificate ? {
1187
+ subject: telemetry.tls.certificate.subject || "",
1188
+ issuer: telemetry.tls.certificate.issuer || "",
1189
+ validFrom: telemetry.tls.certificate.validFrom || "",
1190
+ validTo: telemetry.tls.certificate.validTo || "",
1191
+ fingerprint: telemetry.tls.certificate.fingerprint || ""
1192
+ } : undefined,
1193
+ duration: telemetry.timings.tlsDuration || 0,
1194
+ timestamp: Date.now()
1195
+ }, config);
1196
+ } catch (err) {
1197
+ if (config.debug) {
1198
+ console.log("[Rezo Debug] onTls hook error:", err);
1199
+ }
1200
+ }
1201
+ }
1170
1202
  }
1171
1203
  }
1172
1204
  }
1173
- }
1174
- });
1205
+ };
1206
+ const checkTelemetry = setInterval(() => {
1207
+ if (telemetry?.connected || telemetry?.closed) {
1208
+ clearInterval(checkTelemetry);
1209
+ populateFromTelemetry();
1210
+ }
1211
+ }, 1);
1212
+ socket.once("close", () => clearInterval(checkTelemetry));
1213
+ setTimeout(() => clearInterval(checkTelemetry), 30000);
1214
+ }
1175
1215
  });
1176
1216
  req.on("error", (error) => {
1177
1217
  timeoutManager.clearAll();
@@ -1,6 +1,6 @@
1
- const _mod_hql2dt = require('./picker.cjs');
2
- exports.detectRuntime = _mod_hql2dt.detectRuntime;
3
- exports.getAdapterCapabilities = _mod_hql2dt.getAdapterCapabilities;
4
- exports.buildAdapterContext = _mod_hql2dt.buildAdapterContext;
5
- exports.getAvailableAdapters = _mod_hql2dt.getAvailableAdapters;
6
- exports.selectAdapter = _mod_hql2dt.selectAdapter;;
1
+ const _mod_nhcrtu = require('./picker.cjs');
2
+ exports.detectRuntime = _mod_nhcrtu.detectRuntime;
3
+ exports.getAdapterCapabilities = _mod_nhcrtu.getAdapterCapabilities;
4
+ exports.buildAdapterContext = _mod_nhcrtu.buildAdapterContext;
5
+ exports.getAvailableAdapters = _mod_nhcrtu.getAvailableAdapters;
6
+ exports.selectAdapter = _mod_nhcrtu.selectAdapter;;
@@ -1,9 +1,9 @@
1
- const _mod_7sa5is = require('./lru-cache.cjs');
2
- exports.LRUCache = _mod_7sa5is.LRUCache;;
3
- const _mod_7a00cs = require('./dns-cache.cjs');
4
- exports.DNSCache = _mod_7a00cs.DNSCache;
5
- exports.getGlobalDNSCache = _mod_7a00cs.getGlobalDNSCache;
6
- exports.resetGlobalDNSCache = _mod_7a00cs.resetGlobalDNSCache;;
7
- const _mod_6w1tvn = require('./response-cache.cjs');
8
- exports.ResponseCache = _mod_6w1tvn.ResponseCache;
9
- exports.normalizeResponseCacheConfig = _mod_6w1tvn.normalizeResponseCacheConfig;;
1
+ const _mod_bw1z42 = require('./lru-cache.cjs');
2
+ exports.LRUCache = _mod_bw1z42.LRUCache;;
3
+ const _mod_pywm2s = require('./dns-cache.cjs');
4
+ exports.DNSCache = _mod_pywm2s.DNSCache;
5
+ exports.getGlobalDNSCache = _mod_pywm2s.getGlobalDNSCache;
6
+ exports.resetGlobalDNSCache = _mod_pywm2s.resetGlobalDNSCache;;
7
+ const _mod_1izn4c = require('./response-cache.cjs');
8
+ exports.ResponseCache = _mod_1izn4c.ResponseCache;
9
+ exports.normalizeResponseCacheConfig = _mod_1izn4c.normalizeResponseCacheConfig;;
@@ -1,40 +1,40 @@
1
- const _mod_33fvzd = require('./crawler.cjs');
2
- exports.Crawler = _mod_33fvzd.Crawler;;
3
- const _mod_1ldv58 = require('./crawler-options.cjs');
4
- exports.CrawlerOptions = _mod_1ldv58.CrawlerOptions;;
5
- const _mod_imehct = require('./plugin/robots-txt.cjs');
6
- exports.RobotsTxt = _mod_imehct.RobotsTxt;;
7
- const _mod_u0gyun = require('./plugin/file-cacher.cjs');
8
- exports.FileCacher = _mod_u0gyun.FileCacher;;
9
- const _mod_9wk5ke = require('./plugin/url-store.cjs');
10
- exports.UrlStore = _mod_9wk5ke.UrlStore;;
11
- const _mod_yqhjwv = require('./plugin/navigation-history.cjs');
12
- exports.NavigationHistory = _mod_yqhjwv.NavigationHistory;;
13
- const _mod_klxadq = require('./addon/oxylabs/index.cjs');
14
- exports.Oxylabs = _mod_klxadq.Oxylabs;;
15
- const _mod_n6jnu4 = require('./addon/oxylabs/options.cjs');
16
- exports.OXYLABS_BROWSER_TYPES = _mod_n6jnu4.OXYLABS_BROWSER_TYPES;
17
- exports.OXYLABS_COMMON_LOCALES = _mod_n6jnu4.OXYLABS_COMMON_LOCALES;
18
- exports.OXYLABS_COMMON_GEO_LOCATIONS = _mod_n6jnu4.OXYLABS_COMMON_GEO_LOCATIONS;
19
- exports.OXYLABS_US_STATES = _mod_n6jnu4.OXYLABS_US_STATES;
20
- exports.OXYLABS_EUROPEAN_COUNTRIES = _mod_n6jnu4.OXYLABS_EUROPEAN_COUNTRIES;
21
- exports.OXYLABS_ASIAN_COUNTRIES = _mod_n6jnu4.OXYLABS_ASIAN_COUNTRIES;
22
- exports.getRandomOxylabsBrowserType = _mod_n6jnu4.getRandomBrowserType;
23
- exports.getRandomOxylabsLocale = _mod_n6jnu4.getRandomLocale;
24
- exports.getRandomOxylabsGeoLocation = _mod_n6jnu4.getRandomGeoLocation;;
25
- const _mod_sjw00p = require('./addon/decodo/index.cjs');
26
- exports.Decodo = _mod_sjw00p.Decodo;;
27
- const _mod_f5prd7 = require('./addon/decodo/options.cjs');
28
- exports.DECODO_DEVICE_TYPES = _mod_f5prd7.DECODO_DEVICE_TYPES;
29
- exports.DECODO_HEADLESS_MODES = _mod_f5prd7.DECODO_HEADLESS_MODES;
30
- exports.DECODO_COMMON_LOCALES = _mod_f5prd7.DECODO_COMMON_LOCALES;
31
- exports.DECODO_COMMON_COUNTRIES = _mod_f5prd7.DECODO_COMMON_COUNTRIES;
32
- exports.DECODO_EUROPEAN_COUNTRIES = _mod_f5prd7.DECODO_EUROPEAN_COUNTRIES;
33
- exports.DECODO_ASIAN_COUNTRIES = _mod_f5prd7.DECODO_ASIAN_COUNTRIES;
34
- exports.DECODO_US_STATES = _mod_f5prd7.DECODO_US_STATES;
35
- exports.DECODO_COMMON_CITIES = _mod_f5prd7.DECODO_COMMON_CITIES;
36
- exports.getRandomDecodoDeviceType = _mod_f5prd7.getRandomDeviceType;
37
- exports.getRandomDecodoLocale = _mod_f5prd7.getRandomLocale;
38
- exports.getRandomDecodoCountry = _mod_f5prd7.getRandomCountry;
39
- exports.getRandomDecodoCity = _mod_f5prd7.getRandomCity;
40
- exports.generateDecodoSessionId = _mod_f5prd7.generateSessionId;;
1
+ const _mod_9vxiez = require('./crawler.cjs');
2
+ exports.Crawler = _mod_9vxiez.Crawler;;
3
+ const _mod_y54fdi = require('./crawler-options.cjs');
4
+ exports.CrawlerOptions = _mod_y54fdi.CrawlerOptions;;
5
+ const _mod_wq1zsf = require('./plugin/robots-txt.cjs');
6
+ exports.RobotsTxt = _mod_wq1zsf.RobotsTxt;;
7
+ const _mod_m3lb7n = require('./plugin/file-cacher.cjs');
8
+ exports.FileCacher = _mod_m3lb7n.FileCacher;;
9
+ const _mod_lp12wc = require('./plugin/url-store.cjs');
10
+ exports.UrlStore = _mod_lp12wc.UrlStore;;
11
+ const _mod_mauvz5 = require('./plugin/navigation-history.cjs');
12
+ exports.NavigationHistory = _mod_mauvz5.NavigationHistory;;
13
+ const _mod_ajlky5 = require('./addon/oxylabs/index.cjs');
14
+ exports.Oxylabs = _mod_ajlky5.Oxylabs;;
15
+ const _mod_u3qll6 = require('./addon/oxylabs/options.cjs');
16
+ exports.OXYLABS_BROWSER_TYPES = _mod_u3qll6.OXYLABS_BROWSER_TYPES;
17
+ exports.OXYLABS_COMMON_LOCALES = _mod_u3qll6.OXYLABS_COMMON_LOCALES;
18
+ exports.OXYLABS_COMMON_GEO_LOCATIONS = _mod_u3qll6.OXYLABS_COMMON_GEO_LOCATIONS;
19
+ exports.OXYLABS_US_STATES = _mod_u3qll6.OXYLABS_US_STATES;
20
+ exports.OXYLABS_EUROPEAN_COUNTRIES = _mod_u3qll6.OXYLABS_EUROPEAN_COUNTRIES;
21
+ exports.OXYLABS_ASIAN_COUNTRIES = _mod_u3qll6.OXYLABS_ASIAN_COUNTRIES;
22
+ exports.getRandomOxylabsBrowserType = _mod_u3qll6.getRandomBrowserType;
23
+ exports.getRandomOxylabsLocale = _mod_u3qll6.getRandomLocale;
24
+ exports.getRandomOxylabsGeoLocation = _mod_u3qll6.getRandomGeoLocation;;
25
+ const _mod_1qdq35 = require('./addon/decodo/index.cjs');
26
+ exports.Decodo = _mod_1qdq35.Decodo;;
27
+ const _mod_2k0fmv = require('./addon/decodo/options.cjs');
28
+ exports.DECODO_DEVICE_TYPES = _mod_2k0fmv.DECODO_DEVICE_TYPES;
29
+ exports.DECODO_HEADLESS_MODES = _mod_2k0fmv.DECODO_HEADLESS_MODES;
30
+ exports.DECODO_COMMON_LOCALES = _mod_2k0fmv.DECODO_COMMON_LOCALES;
31
+ exports.DECODO_COMMON_COUNTRIES = _mod_2k0fmv.DECODO_COMMON_COUNTRIES;
32
+ exports.DECODO_EUROPEAN_COUNTRIES = _mod_2k0fmv.DECODO_EUROPEAN_COUNTRIES;
33
+ exports.DECODO_ASIAN_COUNTRIES = _mod_2k0fmv.DECODO_ASIAN_COUNTRIES;
34
+ exports.DECODO_US_STATES = _mod_2k0fmv.DECODO_US_STATES;
35
+ exports.DECODO_COMMON_CITIES = _mod_2k0fmv.DECODO_COMMON_CITIES;
36
+ exports.getRandomDecodoDeviceType = _mod_2k0fmv.getRandomDeviceType;
37
+ exports.getRandomDecodoLocale = _mod_2k0fmv.getRandomLocale;
38
+ exports.getRandomDecodoCountry = _mod_2k0fmv.getRandomCountry;
39
+ exports.getRandomDecodoCity = _mod_2k0fmv.getRandomCity;
40
+ exports.generateDecodoSessionId = _mod_2k0fmv.generateSessionId;;
@@ -1,5 +1,5 @@
1
- const _mod_jqo3a7 = require('../crawler/crawler.cjs');
2
- exports.Crawler = _mod_jqo3a7.Crawler;;
3
- const _mod_5y7u4a = require('../crawler/crawler-options.cjs');
4
- exports.CrawlerOptions = _mod_5y7u4a.CrawlerOptions;
5
- exports.Domain = _mod_5y7u4a.Domain;;
1
+ const _mod_6eolh9 = require('../crawler/crawler.cjs');
2
+ exports.Crawler = _mod_6eolh9.Crawler;;
3
+ const _mod_28rvj3 = require('../crawler/crawler-options.cjs');
4
+ exports.CrawlerOptions = _mod_28rvj3.CrawlerOptions;
5
+ exports.Domain = _mod_28rvj3.Domain;;
package/dist/index.cjs CHANGED
@@ -1,30 +1,30 @@
1
- const _mod_vh18hs = require('./core/rezo.cjs');
2
- exports.Rezo = _mod_vh18hs.Rezo;
3
- exports.createRezoInstance = _mod_vh18hs.createRezoInstance;
4
- exports.createDefaultInstance = _mod_vh18hs.createDefaultInstance;;
5
- const _mod_o1tm8z = require('./errors/rezo-error.cjs');
6
- exports.RezoError = _mod_o1tm8z.RezoError;
7
- exports.RezoErrorCode = _mod_o1tm8z.RezoErrorCode;;
8
- const _mod_qs57sl = require('./utils/headers.cjs');
9
- exports.RezoHeaders = _mod_qs57sl.RezoHeaders;;
10
- const _mod_bcveiy = require('./utils/form-data.cjs');
11
- exports.RezoFormData = _mod_bcveiy.RezoFormData;;
12
- const _mod_j7t4t9 = require('./utils/cookies.cjs');
13
- exports.RezoCookieJar = _mod_j7t4t9.RezoCookieJar;
14
- exports.Cookie = _mod_j7t4t9.Cookie;;
15
- const _mod_cuuq7u = require('./utils/curl.cjs');
16
- exports.toCurl = _mod_cuuq7u.toCurl;
17
- exports.fromCurl = _mod_cuuq7u.fromCurl;;
18
- const _mod_psm01k = require('./core/hooks.cjs');
19
- exports.createDefaultHooks = _mod_psm01k.createDefaultHooks;
20
- exports.mergeHooks = _mod_psm01k.mergeHooks;;
21
- const _mod_x2anu4 = require('./proxy/manager.cjs');
22
- exports.ProxyManager = _mod_x2anu4.ProxyManager;;
23
- const _mod_tnhdd0 = require('./queue/index.cjs');
24
- exports.RezoQueue = _mod_tnhdd0.RezoQueue;
25
- exports.HttpQueue = _mod_tnhdd0.HttpQueue;
26
- exports.Priority = _mod_tnhdd0.Priority;
27
- exports.HttpMethodPriority = _mod_tnhdd0.HttpMethodPriority;;
1
+ const _mod_s1gca7 = require('./core/rezo.cjs');
2
+ exports.Rezo = _mod_s1gca7.Rezo;
3
+ exports.createRezoInstance = _mod_s1gca7.createRezoInstance;
4
+ exports.createDefaultInstance = _mod_s1gca7.createDefaultInstance;;
5
+ const _mod_v6gpph = require('./errors/rezo-error.cjs');
6
+ exports.RezoError = _mod_v6gpph.RezoError;
7
+ exports.RezoErrorCode = _mod_v6gpph.RezoErrorCode;;
8
+ const _mod_u3m56y = require('./utils/headers.cjs');
9
+ exports.RezoHeaders = _mod_u3m56y.RezoHeaders;;
10
+ const _mod_mswq0f = require('./utils/form-data.cjs');
11
+ exports.RezoFormData = _mod_mswq0f.RezoFormData;;
12
+ const _mod_zi4sg0 = require('./utils/cookies.cjs');
13
+ exports.RezoCookieJar = _mod_zi4sg0.RezoCookieJar;
14
+ exports.Cookie = _mod_zi4sg0.Cookie;;
15
+ const _mod_pmct8p = require('./utils/curl.cjs');
16
+ exports.toCurl = _mod_pmct8p.toCurl;
17
+ exports.fromCurl = _mod_pmct8p.fromCurl;;
18
+ const _mod_joston = require('./core/hooks.cjs');
19
+ exports.createDefaultHooks = _mod_joston.createDefaultHooks;
20
+ exports.mergeHooks = _mod_joston.mergeHooks;;
21
+ const _mod_roms61 = require('./proxy/manager.cjs');
22
+ exports.ProxyManager = _mod_roms61.ProxyManager;;
23
+ const _mod_s72k3v = require('./queue/index.cjs');
24
+ exports.RezoQueue = _mod_s72k3v.RezoQueue;
25
+ exports.HttpQueue = _mod_s72k3v.HttpQueue;
26
+ exports.Priority = _mod_s72k3v.Priority;
27
+ exports.HttpMethodPriority = _mod_s72k3v.HttpMethodPriority;;
28
28
  const { RezoError } = require('./errors/rezo-error.cjs');
29
29
  const isRezoError = exports.isRezoError = RezoError.isRezoError;
30
30
  const Cancel = exports.Cancel = RezoError;
@@ -87,8 +87,8 @@ function parseProxyResponse(socket) {
87
87
  buffered
88
88
  });
89
89
  }
90
- socket.on("error", onerror);
91
- socket.on("end", onend);
90
+ socket.once("error", onerror);
91
+ socket.once("end", onend);
92
92
  read();
93
93
  });
94
94
  }
@@ -87,8 +87,8 @@ function parseProxyResponse(socket) {
87
87
  buffered
88
88
  });
89
89
  }
90
- socket.on("error", onerror);
91
- socket.on("end", onend);
90
+ socket.once("error", onerror);
91
+ socket.once("end", onend);
92
92
  read();
93
93
  });
94
94
  }
@@ -1,10 +1,10 @@
1
- const _mod_150zmc = require('./base.cjs');
2
- exports.Agent = _mod_150zmc.Agent;;
3
- const _mod_0kmp78 = require('./http-proxy.cjs');
4
- exports.HttpProxyAgent = _mod_0kmp78.HttpProxyAgent;;
5
- const _mod_4tvb7u = require('./https-proxy.cjs');
6
- exports.HttpsProxyAgent = _mod_4tvb7u.HttpsProxyAgent;;
7
- const _mod_wgeif4 = require('./socks-proxy.cjs');
8
- exports.SocksProxyAgent = _mod_wgeif4.SocksProxyAgent;;
9
- const _mod_3nqvg8 = require('./socks-client.cjs');
10
- exports.SocksClient = _mod_3nqvg8.SocksClient;;
1
+ const _mod_zivpen = require('./base.cjs');
2
+ exports.Agent = _mod_zivpen.Agent;;
3
+ const _mod_acdvd9 = require('./http-proxy.cjs');
4
+ exports.HttpProxyAgent = _mod_acdvd9.HttpProxyAgent;;
5
+ const _mod_uuge9b = require('./https-proxy.cjs');
6
+ exports.HttpsProxyAgent = _mod_uuge9b.HttpsProxyAgent;;
7
+ const _mod_6egylw = require('./socks-proxy.cjs');
8
+ exports.SocksProxyAgent = _mod_6egylw.SocksProxyAgent;;
9
+ const _mod_6r9bok = require('./socks-client.cjs');
10
+ exports.SocksClient = _mod_6r9bok.SocksClient;;
@@ -1,9 +1,9 @@
1
1
  const { Agent, HttpProxyAgent, HttpsProxyAgent, SocksProxyAgent } = require('../internal/agents/index.cjs');
2
2
  const { parseProxyString } = require('./parse.cjs');
3
- const _mod_raejif = require('./manager.cjs');
4
- exports.ProxyManager = _mod_raejif.ProxyManager;;
5
- const _mod_4tr5da = require('./parse.cjs');
6
- exports.parseProxyString = _mod_4tr5da.parseProxyString;;
3
+ const _mod_cch0wk = require('./manager.cjs');
4
+ exports.ProxyManager = _mod_cch0wk.ProxyManager;;
5
+ const _mod_ktsrlf = require('./parse.cjs');
6
+ exports.parseProxyString = _mod_ktsrlf.parseProxyString;;
7
7
  function createOptions(uri, opts) {
8
8
  if (uri instanceof URL || typeof uri === "string") {
9
9
  return {
@@ -1,8 +1,8 @@
1
- const _mod_o7kuxe = require('./queue.cjs');
2
- exports.RezoQueue = _mod_o7kuxe.RezoQueue;;
3
- const _mod_6uv6qn = require('./http-queue.cjs');
4
- exports.HttpQueue = _mod_6uv6qn.HttpQueue;
5
- exports.extractDomain = _mod_6uv6qn.extractDomain;;
6
- const _mod_3lc2he = require('./types.cjs');
7
- exports.Priority = _mod_3lc2he.Priority;
8
- exports.HttpMethodPriority = _mod_3lc2he.HttpMethodPriority;;
1
+ const _mod_vhb3c6 = require('./queue.cjs');
2
+ exports.RezoQueue = _mod_vhb3c6.RezoQueue;;
3
+ const _mod_g8qvdd = require('./http-queue.cjs');
4
+ exports.HttpQueue = _mod_g8qvdd.HttpQueue;
5
+ exports.extractDomain = _mod_g8qvdd.extractDomain;;
6
+ const _mod_ndfksp = require('./types.cjs');
7
+ exports.Priority = _mod_ndfksp.Priority;
8
+ exports.HttpMethodPriority = _mod_ndfksp.HttpMethodPriority;;
@@ -1,11 +1,11 @@
1
- const _mod_074c53 = require('./event-emitter.cjs');
2
- exports.UniversalEventEmitter = _mod_074c53.UniversalEventEmitter;;
3
- const _mod_z5czf2 = require('./stream.cjs');
4
- exports.UniversalStreamResponse = _mod_z5czf2.UniversalStreamResponse;
5
- exports.StreamResponse = _mod_z5czf2.StreamResponse;;
6
- const _mod_n8mvxg = require('./download.cjs');
7
- exports.UniversalDownloadResponse = _mod_n8mvxg.UniversalDownloadResponse;
8
- exports.DownloadResponse = _mod_n8mvxg.DownloadResponse;;
9
- const _mod_n99wlf = require('./upload.cjs');
10
- exports.UniversalUploadResponse = _mod_n99wlf.UniversalUploadResponse;
11
- exports.UploadResponse = _mod_n99wlf.UploadResponse;;
1
+ const _mod_i1xls3 = require('./event-emitter.cjs');
2
+ exports.UniversalEventEmitter = _mod_i1xls3.UniversalEventEmitter;;
3
+ const _mod_ris11a = require('./stream.cjs');
4
+ exports.UniversalStreamResponse = _mod_ris11a.UniversalStreamResponse;
5
+ exports.StreamResponse = _mod_ris11a.StreamResponse;;
6
+ const _mod_itq9aa = require('./download.cjs');
7
+ exports.UniversalDownloadResponse = _mod_itq9aa.UniversalDownloadResponse;
8
+ exports.DownloadResponse = _mod_itq9aa.DownloadResponse;;
9
+ const _mod_c440cb = require('./upload.cjs');
10
+ exports.UniversalUploadResponse = _mod_c440cb.UniversalUploadResponse;
11
+ exports.UploadResponse = _mod_c440cb.UploadResponse;;
@@ -0,0 +1,125 @@
1
+ const socketTelemetryMap = new WeakMap;
2
+ let socketIdCounter = 0;
3
+ function instrumentSocket(socket, isSecure = false) {
4
+ const existing = socketTelemetryMap.get(socket);
5
+ if (existing) {
6
+ existing.reuse.count++;
7
+ existing.reuse.lastUsed = Date.now();
8
+ existing.reuse.isReused = true;
9
+ return existing;
10
+ }
11
+ const now = Date.now();
12
+ const telemetry = {
13
+ id: ++socketIdCounter,
14
+ timings: {
15
+ created: now
16
+ },
17
+ network: {},
18
+ reuse: {
19
+ count: 1,
20
+ lastUsed: now,
21
+ isReused: false
22
+ },
23
+ connected: false,
24
+ closed: false
25
+ };
26
+ socketTelemetryMap.set(socket, telemetry);
27
+ socket.once("lookup", (err, address, family) => {
28
+ if (!err && address) {
29
+ telemetry.timings.dnsEnd = Date.now();
30
+ telemetry.timings.dnsDuration = telemetry.timings.dnsEnd - telemetry.timings.created;
31
+ telemetry.timings.address = address;
32
+ telemetry.timings.family = typeof family === "number" ? family : family === "IPv6" ? 6 : 4;
33
+ }
34
+ });
35
+ socket.once("connect", () => {
36
+ telemetry.timings.connectEnd = Date.now();
37
+ telemetry.timings.tcpDuration = telemetry.timings.connectEnd - (telemetry.timings.dnsEnd || telemetry.timings.created);
38
+ telemetry.connected = true;
39
+ const s = socket;
40
+ telemetry.network = {
41
+ remoteAddress: s.remoteAddress,
42
+ remotePort: s.remotePort,
43
+ localAddress: s.localAddress,
44
+ localPort: s.localPort,
45
+ family: s.remoteFamily
46
+ };
47
+ });
48
+ if (isSecure) {
49
+ socket.once("secureConnect", () => {
50
+ const tlsSocket = socket;
51
+ telemetry.timings.secureConnectEnd = Date.now();
52
+ telemetry.timings.tlsDuration = telemetry.timings.secureConnectEnd - (telemetry.timings.connectEnd || telemetry.timings.created);
53
+ const cipher = tlsSocket.getCipher?.();
54
+ const cert = tlsSocket.getPeerCertificate?.();
55
+ telemetry.tls = {
56
+ protocol: tlsSocket.getProtocol?.() || undefined,
57
+ cipher: cipher?.name,
58
+ authorized: tlsSocket.authorized,
59
+ authorizationError: tlsSocket.authorizationError,
60
+ certificate: cert ? {
61
+ subject: cert.subject?.CN,
62
+ issuer: cert.issuer?.CN,
63
+ validFrom: cert.valid_from,
64
+ validTo: cert.valid_to,
65
+ fingerprint: cert.fingerprint
66
+ } : undefined
67
+ };
68
+ });
69
+ }
70
+ socket.once("close", () => {
71
+ telemetry.closed = true;
72
+ telemetry.connected = false;
73
+ });
74
+ return telemetry;
75
+ }
76
+ function getSocketTelemetry(socket) {
77
+ return socketTelemetryMap.get(socket);
78
+ }
79
+ function isSocketInstrumented(socket) {
80
+ return socketTelemetryMap.has(socket);
81
+ }
82
+ function beginRequestContext(socket, isSecure = false) {
83
+ const startTime = Date.now();
84
+ let telemetry = getSocketTelemetry(socket);
85
+ const wasInstrumented = !!telemetry;
86
+ if (!telemetry) {
87
+ telemetry = instrumentSocket(socket, isSecure);
88
+ } else {
89
+ telemetry.reuse.count++;
90
+ telemetry.reuse.lastUsed = startTime;
91
+ telemetry.reuse.isReused = true;
92
+ }
93
+ const connectionReused = wasInstrumented || telemetry.connected;
94
+ return {
95
+ startTime,
96
+ connectionReused,
97
+ socketWait: 0,
98
+ dns: connectionReused ? 0 : telemetry.timings.dnsDuration || 0,
99
+ tcp: connectionReused ? 0 : telemetry.timings.tcpDuration || 0,
100
+ tls: connectionReused ? 0 : telemetry.timings.tlsDuration || 0,
101
+ socketTimings: { ...telemetry.timings }
102
+ };
103
+ }
104
+ function getSocketReuseStats(socket) {
105
+ const telemetry = socketTelemetryMap.get(socket);
106
+ if (!telemetry)
107
+ return;
108
+ return {
109
+ count: telemetry.reuse.count,
110
+ lifetime: Date.now() - telemetry.timings.created,
111
+ isReused: telemetry.reuse.isReused
112
+ };
113
+ }
114
+ function exportTelemetryStats() {
115
+ return {
116
+ activeSocketCount: socketIdCounter
117
+ };
118
+ }
119
+
120
+ exports.instrumentSocket = instrumentSocket;
121
+ exports.getSocketTelemetry = getSocketTelemetry;
122
+ exports.isSocketInstrumented = isSocketInstrumented;
123
+ exports.beginRequestContext = beginRequestContext;
124
+ exports.getSocketReuseStats = getSocketReuseStats;
125
+ exports.exportTelemetryStats = exportTelemetryStats;
@@ -0,0 +1,118 @@
1
+ const socketTelemetryMap = new WeakMap;
2
+ let socketIdCounter = 0;
3
+ export function instrumentSocket(socket, isSecure = false) {
4
+ const existing = socketTelemetryMap.get(socket);
5
+ if (existing) {
6
+ existing.reuse.count++;
7
+ existing.reuse.lastUsed = Date.now();
8
+ existing.reuse.isReused = true;
9
+ return existing;
10
+ }
11
+ const now = Date.now();
12
+ const telemetry = {
13
+ id: ++socketIdCounter,
14
+ timings: {
15
+ created: now
16
+ },
17
+ network: {},
18
+ reuse: {
19
+ count: 1,
20
+ lastUsed: now,
21
+ isReused: false
22
+ },
23
+ connected: false,
24
+ closed: false
25
+ };
26
+ socketTelemetryMap.set(socket, telemetry);
27
+ socket.once("lookup", (err, address, family) => {
28
+ if (!err && address) {
29
+ telemetry.timings.dnsEnd = Date.now();
30
+ telemetry.timings.dnsDuration = telemetry.timings.dnsEnd - telemetry.timings.created;
31
+ telemetry.timings.address = address;
32
+ telemetry.timings.family = typeof family === "number" ? family : family === "IPv6" ? 6 : 4;
33
+ }
34
+ });
35
+ socket.once("connect", () => {
36
+ telemetry.timings.connectEnd = Date.now();
37
+ telemetry.timings.tcpDuration = telemetry.timings.connectEnd - (telemetry.timings.dnsEnd || telemetry.timings.created);
38
+ telemetry.connected = true;
39
+ const s = socket;
40
+ telemetry.network = {
41
+ remoteAddress: s.remoteAddress,
42
+ remotePort: s.remotePort,
43
+ localAddress: s.localAddress,
44
+ localPort: s.localPort,
45
+ family: s.remoteFamily
46
+ };
47
+ });
48
+ if (isSecure) {
49
+ socket.once("secureConnect", () => {
50
+ const tlsSocket = socket;
51
+ telemetry.timings.secureConnectEnd = Date.now();
52
+ telemetry.timings.tlsDuration = telemetry.timings.secureConnectEnd - (telemetry.timings.connectEnd || telemetry.timings.created);
53
+ const cipher = tlsSocket.getCipher?.();
54
+ const cert = tlsSocket.getPeerCertificate?.();
55
+ telemetry.tls = {
56
+ protocol: tlsSocket.getProtocol?.() || undefined,
57
+ cipher: cipher?.name,
58
+ authorized: tlsSocket.authorized,
59
+ authorizationError: tlsSocket.authorizationError,
60
+ certificate: cert ? {
61
+ subject: cert.subject?.CN,
62
+ issuer: cert.issuer?.CN,
63
+ validFrom: cert.valid_from,
64
+ validTo: cert.valid_to,
65
+ fingerprint: cert.fingerprint
66
+ } : undefined
67
+ };
68
+ });
69
+ }
70
+ socket.once("close", () => {
71
+ telemetry.closed = true;
72
+ telemetry.connected = false;
73
+ });
74
+ return telemetry;
75
+ }
76
+ export function getSocketTelemetry(socket) {
77
+ return socketTelemetryMap.get(socket);
78
+ }
79
+ export function isSocketInstrumented(socket) {
80
+ return socketTelemetryMap.has(socket);
81
+ }
82
+ export function beginRequestContext(socket, isSecure = false) {
83
+ const startTime = Date.now();
84
+ let telemetry = getSocketTelemetry(socket);
85
+ const wasInstrumented = !!telemetry;
86
+ if (!telemetry) {
87
+ telemetry = instrumentSocket(socket, isSecure);
88
+ } else {
89
+ telemetry.reuse.count++;
90
+ telemetry.reuse.lastUsed = startTime;
91
+ telemetry.reuse.isReused = true;
92
+ }
93
+ const connectionReused = wasInstrumented || telemetry.connected;
94
+ return {
95
+ startTime,
96
+ connectionReused,
97
+ socketWait: 0,
98
+ dns: connectionReused ? 0 : telemetry.timings.dnsDuration || 0,
99
+ tcp: connectionReused ? 0 : telemetry.timings.tcpDuration || 0,
100
+ tls: connectionReused ? 0 : telemetry.timings.tlsDuration || 0,
101
+ socketTimings: { ...telemetry.timings }
102
+ };
103
+ }
104
+ export function getSocketReuseStats(socket) {
105
+ const telemetry = socketTelemetryMap.get(socket);
106
+ if (!telemetry)
107
+ return;
108
+ return {
109
+ count: telemetry.reuse.count,
110
+ lifetime: Date.now() - telemetry.timings.created,
111
+ isReused: telemetry.reuse.isReused
112
+ };
113
+ }
114
+ export function exportTelemetryStats() {
115
+ return {
116
+ activeSocketCount: socketIdCounter
117
+ };
118
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rezo",
3
- "version": "1.0.46",
3
+ "version": "1.0.47",
4
4
  "description": "Lightning-fast, enterprise-grade HTTP client for modern JavaScript. Full HTTP/2 support, intelligent cookie management, multiple adapters (HTTP, Fetch, cURL, XHR), streaming, proxy support (HTTP/HTTPS/SOCKS), and cross-environment compatibility.",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",