socket-function 1.2.17 → 1.2.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +3 -0
- package/package.json +1 -1
- package/src/https.d.ts +3 -0
- package/src/https.ts +15 -0
- package/src/networking.ts +3 -1
- package/src/upreal.ts +4 -13
- package/src/websocketFactory.ts +8 -1
package/index.d.ts
CHANGED
package/package.json
CHANGED
package/src/https.d.ts
CHANGED
package/src/https.ts
CHANGED
|
@@ -47,6 +47,8 @@ export function httpsRequest(
|
|
|
47
47
|
config?: {
|
|
48
48
|
headers?: { [key: string]: string | undefined },
|
|
49
49
|
cancel?: Promise<void>;
|
|
50
|
+
// Populated with the response headers once they arrive, so the caller can read them.
|
|
51
|
+
outHeaders?: { [key: string]: string | undefined };
|
|
50
52
|
}
|
|
51
53
|
): Promise<Buffer> {
|
|
52
54
|
if (isNode()) {
|
|
@@ -96,6 +98,12 @@ export function httpsRequest(
|
|
|
96
98
|
autoSelectFamily: true,
|
|
97
99
|
} as https.RequestOptions,
|
|
98
100
|
async httpResponse => {
|
|
101
|
+
if (config?.outHeaders) {
|
|
102
|
+
for (let [key, value] of Object.entries(httpResponse.headers)) {
|
|
103
|
+
config.outHeaders[key] = Array.isArray(value) ? value.join(", ") : value;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
99
107
|
let data: Buffer[] = [];
|
|
100
108
|
httpResponse.on("data", chunk => {
|
|
101
109
|
data.push(chunk);
|
|
@@ -158,6 +166,13 @@ export function httpsRequest(
|
|
|
158
166
|
}
|
|
159
167
|
return new Promise((resolve, reject) => {
|
|
160
168
|
request.onload = () => {
|
|
169
|
+
if (config?.outHeaders) {
|
|
170
|
+
for (let line of request.getAllResponseHeaders().trim().split(/[\r\n]+/)) {
|
|
171
|
+
let index = line.indexOf(":");
|
|
172
|
+
if (index < 0) continue;
|
|
173
|
+
config.outHeaders[line.slice(0, index).trim().toLowerCase()] = line.slice(index + 1).trim();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
161
176
|
if (!request.status.toString().startsWith("2")) {
|
|
162
177
|
try {
|
|
163
178
|
// It should be an error.stack. But if it isn't... just throw the status text...
|
package/src/networking.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import net from "net";
|
|
2
2
|
import { lazy } from "./caching";
|
|
3
3
|
import { httpsRequest } from "./https";
|
|
4
|
+
import { dnsCacheLookup } from "./dnsCache";
|
|
4
5
|
import { measureWrap } from "./profiling/measure";
|
|
5
6
|
|
|
6
7
|
export const testTCPIsListening = measureWrap(async function testTCPIsListening(host: string, port: number): Promise<boolean> {
|
|
7
8
|
// We need to establish a TCP connection, then close it? Yeah... so it is
|
|
8
9
|
// not even a SocketFunction call, because it can't be, because that woule be TLS,
|
|
9
10
|
// which we can't do with an ip!
|
|
10
|
-
|
|
11
|
+
// Resolve through our DNS cache rather than getaddrinfo, to avoid glibc's sticky failure cache.
|
|
12
|
+
let socket = net.connect({ host, port, lookup: dnsCacheLookup });
|
|
11
13
|
return new Promise((resolve) => {
|
|
12
14
|
socket.on("connect", () => {
|
|
13
15
|
socket.end();
|
package/src/upreal.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from "fs";
|
|
2
2
|
import * as path from "path";
|
|
3
|
-
import * as https from "https";
|
|
4
3
|
import { spawn } from "child_process";
|
|
4
|
+
import { httpsRequest } from "./https";
|
|
5
5
|
|
|
6
6
|
// Dependency sections in package.json that upreal is willing to update, in the order we search them.
|
|
7
7
|
const DEP_SECTIONS = [
|
|
@@ -86,18 +86,9 @@ async function getLatestVersion(packageName: string): Promise<string> {
|
|
|
86
86
|
: encodeURIComponent(packageName);
|
|
87
87
|
let url = `https://registry.npmjs.org/${encodedName}/latest`;
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
res.resume();
|
|
93
|
-
reject(new Error(`Registry returned ${res.statusCode} for ${url}`));
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
let chunks: Buffer[] = [];
|
|
97
|
-
res.on("data", chunk => chunks.push(chunk));
|
|
98
|
-
res.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
|
|
99
|
-
}).on("error", reject);
|
|
100
|
-
});
|
|
89
|
+
// Via httpsRequest so registry lookups go through the DNS cache (and its re-resolve/retry), rather
|
|
90
|
+
// than getaddrinfo, which caches certain failures forever.
|
|
91
|
+
let body = (await httpsRequest(url)).toString("utf8");
|
|
101
92
|
|
|
102
93
|
let parsed = JSON.parse(body) as { version?: string };
|
|
103
94
|
if (!parsed.version) {
|
package/src/websocketFactory.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { isNode } from "./misc";
|
|
|
3
3
|
import { SenderInterface } from "./CallFactory";
|
|
4
4
|
import { getTrustedCertificates } from "./certStore";
|
|
5
5
|
import { getNodeIdLocation } from "./nodeCache";
|
|
6
|
+
import { dnsCacheLookup } from "./dnsCache";
|
|
6
7
|
import debugbreak from "debugbreak";
|
|
7
8
|
import { SocketFunction } from "../SocketFunction";
|
|
8
9
|
import type * as ws from "ws";
|
|
@@ -44,7 +45,13 @@ export function createWebsocketFactory(): WebsocketFactory {
|
|
|
44
45
|
const ws = require("ws") as typeof import("ws");
|
|
45
46
|
let webSocket = new ws.WebSocket(`wss://${address}:${port}`, proposedProtocols, {
|
|
46
47
|
ca: getTrustedCertificates(),
|
|
47
|
-
|
|
48
|
+
// Resolve through our DNS cache instead of getaddrinfo, to avoid glibc's sticky failure
|
|
49
|
+
// cache. ws forwards these to the underlying tls/https connect. We don't get httpsRequest's
|
|
50
|
+
// connection-level re-resolve+retry here, but the DNS-level retries, positive cache, and
|
|
51
|
+
// negative cache still apply, and CallFactory's reconnect picks up a re-resolved address.
|
|
52
|
+
lookup: dnsCacheLookup,
|
|
53
|
+
autoSelectFamily: true,
|
|
54
|
+
} as ws.ClientOptions);
|
|
48
55
|
|
|
49
56
|
// NOTE: Little setup is done here, because Sometimes websockets are created here,
|
|
50
57
|
// and sometimes via incoming connections, We should do most setup in
|