rezo 1.0.46 → 1.0.48

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_a37jii = require('./picker.cjs');
2
+ exports.detectRuntime = _mod_a37jii.detectRuntime;
3
+ exports.getAdapterCapabilities = _mod_a37jii.getAdapterCapabilities;
4
+ exports.buildAdapterContext = _mod_a37jii.buildAdapterContext;
5
+ exports.getAvailableAdapters = _mod_a37jii.getAvailableAdapters;
6
+ exports.selectAdapter = _mod_a37jii.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_0jnjce = require('./lru-cache.cjs');
2
+ exports.LRUCache = _mod_0jnjce.LRUCache;;
3
+ const _mod_1v6y7w = require('./dns-cache.cjs');
4
+ exports.DNSCache = _mod_1v6y7w.DNSCache;
5
+ exports.getGlobalDNSCache = _mod_1v6y7w.getGlobalDNSCache;
6
+ exports.resetGlobalDNSCache = _mod_1v6y7w.resetGlobalDNSCache;;
7
+ const _mod_nkze1k = require('./response-cache.cjs');
8
+ exports.ResponseCache = _mod_nkze1k.ResponseCache;
9
+ exports.normalizeResponseCacheConfig = _mod_nkze1k.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_56vwcu = require('./crawler.cjs');
2
+ exports.Crawler = _mod_56vwcu.Crawler;;
3
+ const _mod_h99hvt = require('./crawler-options.cjs');
4
+ exports.CrawlerOptions = _mod_h99hvt.CrawlerOptions;;
5
+ const _mod_5m68qr = require('./plugin/robots-txt.cjs');
6
+ exports.RobotsTxt = _mod_5m68qr.RobotsTxt;;
7
+ const _mod_dk3aqb = require('./plugin/file-cacher.cjs');
8
+ exports.FileCacher = _mod_dk3aqb.FileCacher;;
9
+ const _mod_spb1ch = require('./plugin/url-store.cjs');
10
+ exports.UrlStore = _mod_spb1ch.UrlStore;;
11
+ const _mod_0xawx9 = require('./plugin/navigation-history.cjs');
12
+ exports.NavigationHistory = _mod_0xawx9.NavigationHistory;;
13
+ const _mod_oiprum = require('./addon/oxylabs/index.cjs');
14
+ exports.Oxylabs = _mod_oiprum.Oxylabs;;
15
+ const _mod_hwvks8 = require('./addon/oxylabs/options.cjs');
16
+ exports.OXYLABS_BROWSER_TYPES = _mod_hwvks8.OXYLABS_BROWSER_TYPES;
17
+ exports.OXYLABS_COMMON_LOCALES = _mod_hwvks8.OXYLABS_COMMON_LOCALES;
18
+ exports.OXYLABS_COMMON_GEO_LOCATIONS = _mod_hwvks8.OXYLABS_COMMON_GEO_LOCATIONS;
19
+ exports.OXYLABS_US_STATES = _mod_hwvks8.OXYLABS_US_STATES;
20
+ exports.OXYLABS_EUROPEAN_COUNTRIES = _mod_hwvks8.OXYLABS_EUROPEAN_COUNTRIES;
21
+ exports.OXYLABS_ASIAN_COUNTRIES = _mod_hwvks8.OXYLABS_ASIAN_COUNTRIES;
22
+ exports.getRandomOxylabsBrowserType = _mod_hwvks8.getRandomBrowserType;
23
+ exports.getRandomOxylabsLocale = _mod_hwvks8.getRandomLocale;
24
+ exports.getRandomOxylabsGeoLocation = _mod_hwvks8.getRandomGeoLocation;;
25
+ const _mod_ca1m5c = require('./addon/decodo/index.cjs');
26
+ exports.Decodo = _mod_ca1m5c.Decodo;;
27
+ const _mod_lbuqqj = require('./addon/decodo/options.cjs');
28
+ exports.DECODO_DEVICE_TYPES = _mod_lbuqqj.DECODO_DEVICE_TYPES;
29
+ exports.DECODO_HEADLESS_MODES = _mod_lbuqqj.DECODO_HEADLESS_MODES;
30
+ exports.DECODO_COMMON_LOCALES = _mod_lbuqqj.DECODO_COMMON_LOCALES;
31
+ exports.DECODO_COMMON_COUNTRIES = _mod_lbuqqj.DECODO_COMMON_COUNTRIES;
32
+ exports.DECODO_EUROPEAN_COUNTRIES = _mod_lbuqqj.DECODO_EUROPEAN_COUNTRIES;
33
+ exports.DECODO_ASIAN_COUNTRIES = _mod_lbuqqj.DECODO_ASIAN_COUNTRIES;
34
+ exports.DECODO_US_STATES = _mod_lbuqqj.DECODO_US_STATES;
35
+ exports.DECODO_COMMON_CITIES = _mod_lbuqqj.DECODO_COMMON_CITIES;
36
+ exports.getRandomDecodoDeviceType = _mod_lbuqqj.getRandomDeviceType;
37
+ exports.getRandomDecodoLocale = _mod_lbuqqj.getRandomLocale;
38
+ exports.getRandomDecodoCountry = _mod_lbuqqj.getRandomCountry;
39
+ exports.getRandomDecodoCity = _mod_lbuqqj.getRandomCity;
40
+ exports.generateDecodoSessionId = _mod_lbuqqj.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_waz4sw = require('../crawler/crawler.cjs');
2
+ exports.Crawler = _mod_waz4sw.Crawler;;
3
+ const _mod_qyuee2 = require('../crawler/crawler-options.cjs');
4
+ exports.CrawlerOptions = _mod_qyuee2.CrawlerOptions;
5
+ exports.Domain = _mod_qyuee2.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_7il99s = require('./core/rezo.cjs');
2
+ exports.Rezo = _mod_7il99s.Rezo;
3
+ exports.createRezoInstance = _mod_7il99s.createRezoInstance;
4
+ exports.createDefaultInstance = _mod_7il99s.createDefaultInstance;;
5
+ const _mod_n9wbzo = require('./errors/rezo-error.cjs');
6
+ exports.RezoError = _mod_n9wbzo.RezoError;
7
+ exports.RezoErrorCode = _mod_n9wbzo.RezoErrorCode;;
8
+ const _mod_fy79qn = require('./utils/headers.cjs');
9
+ exports.RezoHeaders = _mod_fy79qn.RezoHeaders;;
10
+ const _mod_5gvi4h = require('./utils/form-data.cjs');
11
+ exports.RezoFormData = _mod_5gvi4h.RezoFormData;;
12
+ const _mod_mcuya6 = require('./utils/cookies.cjs');
13
+ exports.RezoCookieJar = _mod_mcuya6.RezoCookieJar;
14
+ exports.Cookie = _mod_mcuya6.Cookie;;
15
+ const _mod_hmicpp = require('./utils/curl.cjs');
16
+ exports.toCurl = _mod_hmicpp.toCurl;
17
+ exports.fromCurl = _mod_hmicpp.fromCurl;;
18
+ const _mod_3zsuqz = require('./core/hooks.cjs');
19
+ exports.createDefaultHooks = _mod_3zsuqz.createDefaultHooks;
20
+ exports.mergeHooks = _mod_3zsuqz.mergeHooks;;
21
+ const _mod_i74vh6 = require('./proxy/manager.cjs');
22
+ exports.ProxyManager = _mod_i74vh6.ProxyManager;;
23
+ const _mod_5fkx2u = require('./queue/index.cjs');
24
+ exports.RezoQueue = _mod_5fkx2u.RezoQueue;
25
+ exports.HttpQueue = _mod_5fkx2u.HttpQueue;
26
+ exports.Priority = _mod_5fkx2u.Priority;
27
+ exports.HttpMethodPriority = _mod_5fkx2u.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_xr0vvt = require('./base.cjs');
2
+ exports.Agent = _mod_xr0vvt.Agent;;
3
+ const _mod_nlrzxh = require('./http-proxy.cjs');
4
+ exports.HttpProxyAgent = _mod_nlrzxh.HttpProxyAgent;;
5
+ const _mod_uqm4jj = require('./https-proxy.cjs');
6
+ exports.HttpsProxyAgent = _mod_uqm4jj.HttpsProxyAgent;;
7
+ const _mod_4fqugo = require('./socks-proxy.cjs');
8
+ exports.SocksProxyAgent = _mod_4fqugo.SocksProxyAgent;;
9
+ const _mod_mm3lh3 = require('./socks-client.cjs');
10
+ exports.SocksClient = _mod_mm3lh3.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_wf8q6g = require('./manager.cjs');
4
+ exports.ProxyManager = _mod_wf8q6g.ProxyManager;;
5
+ const _mod_hbrvhh = require('./parse.cjs');
6
+ exports.parseProxyString = _mod_hbrvhh.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_ljk8ks = require('./queue.cjs');
2
+ exports.RezoQueue = _mod_ljk8ks.RezoQueue;;
3
+ const _mod_skj1a9 = require('./http-queue.cjs');
4
+ exports.HttpQueue = _mod_skj1a9.HttpQueue;
5
+ exports.extractDomain = _mod_skj1a9.extractDomain;;
6
+ const _mod_8n2ck2 = require('./types.cjs');
7
+ exports.Priority = _mod_8n2ck2.Priority;
8
+ exports.HttpMethodPriority = _mod_8n2ck2.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_8yhhmv = require('./event-emitter.cjs');
2
+ exports.UniversalEventEmitter = _mod_8yhhmv.UniversalEventEmitter;;
3
+ const _mod_lh5z8y = require('./stream.cjs');
4
+ exports.UniversalStreamResponse = _mod_lh5z8y.UniversalStreamResponse;
5
+ exports.StreamResponse = _mod_lh5z8y.StreamResponse;;
6
+ const _mod_236eww = require('./download.cjs');
7
+ exports.UniversalDownloadResponse = _mod_236eww.UniversalDownloadResponse;
8
+ exports.DownloadResponse = _mod_236eww.DownloadResponse;;
9
+ const _mod_vv2nu8 = require('./upload.cjs');
10
+ exports.UniversalUploadResponse = _mod_vv2nu8.UniversalUploadResponse;
11
+ exports.UploadResponse = _mod_vv2nu8.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.48",
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",