bdy 1.24.0 → 1.24.1-dev
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/distTs/package.json
CHANGED
|
@@ -9,6 +9,7 @@ const uuid_1 = require("uuid");
|
|
|
9
9
|
const http_1 = __importDefault(require("http"));
|
|
10
10
|
const texts_1 = require("../../texts");
|
|
11
11
|
const tunnel_1 = require("../../types/tunnel");
|
|
12
|
+
const utils_1 = require("../../utils");
|
|
12
13
|
class ServerHttp1 extends events_1.default {
|
|
13
14
|
server;
|
|
14
15
|
host;
|
|
@@ -16,6 +17,14 @@ class ServerHttp1 extends events_1.default {
|
|
|
16
17
|
super();
|
|
17
18
|
this.host = host;
|
|
18
19
|
this.server = http_1.default.createServer((req, res) => this.processRequest(req, res));
|
|
20
|
+
// Backstop, not the primary bound - and that ordering is the whole point of the number. A
|
|
21
|
+
// channel is now bound to a CLIENT connection on the worker side, so it goes idle exactly when
|
|
22
|
+
// that connection does and the worker releases it there. This has to stay ABOVE the worker's own
|
|
23
|
+
// client keep-alive (node's 5s default on its h1 server) so the worker always decides first;
|
|
24
|
+
// reaping ahead of it would close a channel whose connection is still in use, which is precisely
|
|
25
|
+
// how node's 5s default here used to kill live client connections. Same invariant the h2 side
|
|
26
|
+
// already keeps with TUNNEL_HTTP2_SESSION_IDLE_TIMEOUT above the worker's session idle timeout.
|
|
27
|
+
this.server.keepAliveTimeout = utils_1.TUNNEL_HTTP1_CHANNEL_KEEPALIVE;
|
|
19
28
|
this.server.on('connection', (socket) => {
|
|
20
29
|
socket.id = (0, uuid_1.v4)();
|
|
21
30
|
this.emit(tunnel_1.TUNNEL_HTTP_SOCKET.OPEN, socket);
|
|
@@ -187,6 +187,15 @@ class SshClient extends events_1.default {
|
|
|
187
187
|
triggerStream(tunnel_1.TUNNEL_SSH_EVENT.STREAM_HTTP1, ip);
|
|
188
188
|
return;
|
|
189
189
|
}
|
|
190
|
+
if (type === tunnel_1.TUNNEL_SOCKET_TYPE.HTTP1_SHARED) {
|
|
191
|
+
logger_1.default.debug((0, texts_1.LOG_DETECTED_STREAM)('HTTP1_SHARED'));
|
|
192
|
+
// Same h1 path as above - only where the client address comes from differs, and requestIp()
|
|
193
|
+
// already asks the channel rather than the protocol, so this flag is the whole change. The
|
|
194
|
+
// handshake IP is a placeholder here.
|
|
195
|
+
stream.sharedIp = true;
|
|
196
|
+
triggerStream(tunnel_1.TUNNEL_SSH_EVENT.STREAM_HTTP1, ip);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
190
199
|
if (type === tunnel_1.TUNNEL_SOCKET_TYPE.HTTP2) {
|
|
191
200
|
logger_1.default.debug((0, texts_1.LOG_DETECTED_STREAM)('HTTP2'));
|
|
192
201
|
triggerStream(tunnel_1.TUNNEL_SSH_EVENT.STREAM_HTTP2, ip);
|
|
@@ -119,6 +119,12 @@ var TUNNEL_SOCKET_TYPE;
|
|
|
119
119
|
// agent that advertised the capability in its SSH ident - types 0-4 keep working forever, since
|
|
120
120
|
// old workers will be opening them for a long time.
|
|
121
121
|
TUNNEL_SOCKET_TYPE[TUNNEL_SOCKET_TYPE["HTTP2_SHARED"] = 5] = "HTTP2_SHARED";
|
|
122
|
+
// Same channel as HTTP1, and the address travels per request for the same reason as on type 5 -
|
|
123
|
+
// except here what makes the frame's IP field unusable is not many clients at once but time: the
|
|
124
|
+
// worker binds this channel to a client CONNECTION rather than to a single request, so the frame
|
|
125
|
+
// would only ever describe the request that opened it. Behind a proxy that multiplexes clients,
|
|
126
|
+
// consecutive requests on one connection belong to different ones.
|
|
127
|
+
TUNNEL_SOCKET_TYPE[TUNNEL_SOCKET_TYPE["HTTP1_SHARED"] = 6] = "HTTP1_SHARED";
|
|
122
128
|
})(TUNNEL_SOCKET_TYPE || (exports.TUNNEL_SOCKET_TYPE = TUNNEL_SOCKET_TYPE = {}));
|
|
123
129
|
var TUNNEL_REGION;
|
|
124
130
|
(function (TUNNEL_REGION) {
|
package/distTs/src/utils.js
CHANGED
|
@@ -36,9 +36,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.
|
|
40
|
-
exports.
|
|
41
|
-
exports.findArtifactReadme = exports.isPathInside = exports.getComposerReadmePath = void 0;
|
|
39
|
+
exports.TARGET_HTTP_REGEX = exports.TARGET_TCP_TLS_REGEX = exports.ApiErrorTunnelsDisabled = exports.ApiErrorWorkspaceFlagged = exports.ApiErrorTunnelLimitReached = exports.ApiErrorAgentLimitReached = exports.ApiErrorDomainRestricted = exports.ApiErrorTargetInvalid = exports.ApiErrorWrongToken = exports.ApiErrorFailedToConnect = exports.ApiErrorAgentNotFound = exports.ARTIFACT_AUTH_TYPE = exports.TARGET_EXEC_STATUS = exports.TARGET_SCOPE = exports.ARTIFACT_TYPE = exports.SANDBOX_SNAPSHOT_STATUS = exports.SANDBOX_APP_STATUS = exports.SANDBOX_SETUP_STATUS = exports.SANDBOX_EXEC_STATUS = exports.SANDBOX_EXEC_RUNTIME = exports.SANDBOX_STATUS = exports.REST_API_ENDPOINT = exports.REST_API_REGION = exports.DEFAULT_SANDBOX_CP_USER = exports.ARTIFACT_DEFAULT_VERSION = exports.SUGGESTED_BROWSER_VERSION = exports.AGENT_UPDATE_STATUS_TTL_MS = exports.AGENT_UPDATE_PROBATION_MS = exports.AGENT_UPDATE_MAX_ATTEMPTS = exports.AGENT_FETCH_RETRY_MAX = exports.AGENT_FETCH_RETRY_MIN = exports.SSH_HANDSHAKE_TIMEOUT = exports.DEFAULT_TIMEOUT = exports.getSshIdent = exports.TUNNEL_SSH_IDENT_SHARED_H1 = exports.TUNNEL_SSH_IDENT_SHARED_H2 = exports.TUNNEL_CLIENT_IP_HEADER = exports.TUNNEL_HTTP2_SHED_LOG_INTERVAL = exports.TUNNEL_HTTP2_MAX_SESSIONS = exports.TUNNEL_HTTP1_CHANNEL_KEEPALIVE = exports.TUNNEL_HTTP2_SESSION_IDLE_TIMEOUT = exports.TUNNEL_HTTP_RETRY_AFTER = exports.TUNNEL_HTTP_MAX_INFLIGHT = exports.TUNNEL_HTTP_CB_MIN_REQUESTS = exports.TUNNEL_HTTP_CB_WINDOW = exports.TUNNEL_MAX_REQUEST_SIZE_TO_SYNC = exports.TUNNEL_HTTP_LOG_MAX_REQUESTS = exports.TUNNEL_HTTP_LOG_MAX_BODY = exports.TUNNEL_HTTP_RATE_WINDOW = exports.TUNNEL_HTTP_RATE_LIMIT = void 0;
|
|
40
|
+
exports.ARTIFACT_README_SIZE_LIMIT = exports.filterIgnoredEntries = exports.parseIgnorePatterns = exports.ARTIFACT_IGNORE_DEFAULT = exports.createZip = exports.getGitName = exports.getGitEmail = exports.MCP_TOOL_CATEGORIES = exports.getBasicCommandTls = exports.getBasicCommandHttp = exports.getBasicCommandSandboxEndpoint = exports.getBasicCommandTcp = exports.getCurrentUser = exports.getServiceUser = exports.getRealTargetHost = exports.isWindows = exports.isLinux = exports.isOsx = exports.isDocker = exports.truncate = exports.sleep = exports.getLatestVersion = exports.getVersionEnv = exports.getCurrentVersionWithoutEnv = exports.isVersionNewer = exports.getVersionWithoutEnv = exports.parseVersion = exports.getVersion = exports.isInstalledByChoco = exports.isInstalledByApt = exports.isInstalledByBrew = exports.isInstalledByNpm = exports.isNpmGlobalWritable = exports.isPathWritable = exports.tryGetEmail = exports.execLocally = exports.getHomeDirectory = exports.HOME_DIR_NAME = exports.chownToHomeOwner = exports.isDomainAvailable = exports.sandboxScopeOptions = exports.newCommand = exports.formatBytes = exports.formatHelp = exports.getPlatform = exports.getHostname = exports.isStringRegExp = exports.getWorkingDir = exports.getRootDir = exports.TARGET_ONLY_PORT_REGEX = void 0;
|
|
41
|
+
exports.findArtifactReadme = exports.isPathInside = exports.getComposerReadmePath = exports.parseComposerJson = exports.ARTIFACT_README_NAMES = void 0;
|
|
42
42
|
exports.apiErrorCodeToClass = apiErrorCodeToClass;
|
|
43
43
|
exports.isFile = isFile;
|
|
44
44
|
exports.getAppWorkspaceUrl = getAppWorkspaceUrl;
|
|
@@ -86,6 +86,17 @@ exports.TUNNEL_HTTP_RETRY_AFTER = 30;
|
|
|
86
86
|
// Idle timeout sits above the worker's 60s so a healthy worker closes its side first and this
|
|
87
87
|
// timer only fires against a worker that never reaps.
|
|
88
88
|
exports.TUNNEL_HTTP2_SESSION_IDLE_TIMEOUT = 75000;
|
|
89
|
+
// The h1 equivalent, and the same ordering rule: node's 5s default on the channel server sat BELOW
|
|
90
|
+
// the worker's client keep-alive, so the agent reaped channels the worker still had connections for.
|
|
91
|
+
// Explicit, above it, and only ever a backstop - a healthy worker releases a channel when the client
|
|
92
|
+
// connection it is bound to goes away (worker/src/pipe.js, PipeHttp1.release).
|
|
93
|
+
//
|
|
94
|
+
// This number describes the CHANNEL and nothing else. node puts it on every response as
|
|
95
|
+
// `Keep-Alive: timeout=20`, and the worker strips that on the way to the client
|
|
96
|
+
// (PIPE_RESPONSE_HOP_HEADERS) precisely so it cannot be read as a promise about the client's own
|
|
97
|
+
// connection - which the worker closes on its own, much sooner. Raising it here without that strip
|
|
98
|
+
// in place tells clients to park connections that are already gone.
|
|
99
|
+
exports.TUNNEL_HTTP1_CHANNEL_KEEPALIVE = 20000;
|
|
89
100
|
// Above the worker's global cap (2000): the worker sheds first, this only catches what slips
|
|
90
101
|
// through (multiple workers, old workers, caps overshoot under a burst).
|
|
91
102
|
exports.TUNNEL_HTTP2_MAX_SESSIONS = 4000;
|
|
@@ -106,7 +117,12 @@ exports.TUNNEL_CLIENT_IP_HEADER = 'x-bdy-client-ip';
|
|
|
106
117
|
// one). Per SSH connection, so an updated agent gets the new mode on its next reconnect rather
|
|
107
118
|
// than when its tunnel record is recreated. RFC 4253: printable ASCII, no spaces, no minus.
|
|
108
119
|
exports.TUNNEL_SSH_IDENT_SHARED_H2 = 'hip1';
|
|
109
|
-
|
|
120
|
+
// The same announcement for TUNNEL_SOCKET_TYPE.HTTP1_SHARED, and deliberately a second token rather
|
|
121
|
+
// than a new meaning for the one above: agents advertising hip1 alone are already in the field and
|
|
122
|
+
// destroy an h1 channel of a type they do not know, so the worker has to be able to tell the two
|
|
123
|
+
// generations apart.
|
|
124
|
+
exports.TUNNEL_SSH_IDENT_SHARED_H1 = 'h1s1';
|
|
125
|
+
const getSshIdent = () => `bdy_${(0, exports.getVersionWithoutEnv)((0, exports.getVersion)())}_${exports.TUNNEL_SSH_IDENT_SHARED_H2}_${exports.TUNNEL_SSH_IDENT_SHARED_H1}`;
|
|
110
126
|
exports.getSshIdent = getSshIdent;
|
|
111
127
|
exports.DEFAULT_TIMEOUT = 30;
|
|
112
128
|
exports.SSH_HANDSHAKE_TIMEOUT = 10000;
|