bdy 1.23.8-master → 1.23.9-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 +1 -1
- package/distTs/src/logThrottle.js +57 -0
- package/distTs/src/texts.js +17 -10
- package/distTs/src/tunnel/http/auth.js +2 -7
- package/distTs/src/tunnel/http/ip.js +31 -0
- package/distTs/src/tunnel/http/log.js +2 -8
- package/distTs/src/tunnel/http.js +5 -9
- package/distTs/src/tunnel/server/http1.js +55 -2
- package/distTs/src/tunnel/server/http2.js +89 -2
- package/distTs/src/tunnel/ssh/client.js +14 -0
- package/distTs/src/types/tunnel.js +6 -0
- package/distTs/src/utils.js +31 -2
- package/package.json +1 -1
package/distTs/package.json
CHANGED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
class LogThrottle {
|
|
4
|
+
interval;
|
|
5
|
+
reports = new Map();
|
|
6
|
+
onFlush;
|
|
7
|
+
timer = null;
|
|
8
|
+
// onFlush(kind, suppressed) - optional. Without it the tail of a burst is lost, which is fine for
|
|
9
|
+
// a throttle whose caller reports the count some other way, and wrong for every current caller.
|
|
10
|
+
constructor(interval, onFlush) {
|
|
11
|
+
this.interval = interval;
|
|
12
|
+
this.onFlush = onFlush || null;
|
|
13
|
+
if (this.onFlush) {
|
|
14
|
+
// unref: this sweep must never be the reason the agent stays alive after its tunnel is gone.
|
|
15
|
+
this.timer = setInterval(() => this.flush(), interval);
|
|
16
|
+
if (this.timer.unref)
|
|
17
|
+
this.timer.unref();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
hit(kind) {
|
|
21
|
+
const now = Date.now();
|
|
22
|
+
const last = this.reports.get(kind);
|
|
23
|
+
if (last && now - last.at < this.interval) {
|
|
24
|
+
last.suppressed += 1;
|
|
25
|
+
return -1;
|
|
26
|
+
}
|
|
27
|
+
const suppressed = last ? last.suppressed : 0;
|
|
28
|
+
this.reports.set(kind, { at: now, suppressed: 0 });
|
|
29
|
+
return suppressed;
|
|
30
|
+
}
|
|
31
|
+
// Only kinds whose window has fully elapsed: one still inside its window is not quiet yet, and
|
|
32
|
+
// the next hit will carry its count the normal way. Deleting while iterating a Map is safe.
|
|
33
|
+
flush() {
|
|
34
|
+
if (!this.onFlush)
|
|
35
|
+
return;
|
|
36
|
+
const now = Date.now();
|
|
37
|
+
for (const [kind, last] of this.reports) {
|
|
38
|
+
if (now - last.at < this.interval)
|
|
39
|
+
continue;
|
|
40
|
+
if (!last.suppressed) {
|
|
41
|
+
this.reports.delete(kind);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const { suppressed } = last;
|
|
45
|
+
last.suppressed = 0;
|
|
46
|
+
last.at = now;
|
|
47
|
+
this.onFlush(kind, suppressed);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
stop() {
|
|
51
|
+
if (!this.timer)
|
|
52
|
+
return;
|
|
53
|
+
clearInterval(this.timer);
|
|
54
|
+
this.timer = null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.default = LogThrottle;
|
package/distTs/src/texts.js
CHANGED
|
@@ -9,16 +9,16 @@ exports.TXT_ARTIFACT_UNZIPPING_COUNT = exports.TXT_ARTIFACT_UNZIPPED = exports.T
|
|
|
9
9
|
exports.OPTION_FORMAT = exports.OPTION_VERSION = exports.OPTION_PIPELINE_RUN_NO_FOLLOW = exports.OPTION_PIPELINE_RUN_NO_WAIT = exports.OPTION_PIPELINE_RUN_ACTION = exports.OPTION_REST_API_TOKEN = exports.OPTION_ARTIFACT_DOWNLOAD_REPLACE = exports.OPTION_ARTIFACT_DOWNLOAD_MERGE = exports.OPTION_ARTIFACT_PUBLISH_OVERWRITE_VERSION = exports.OPTION_ARTIFACT_VERSION_AGENT_NOTE = exports.OPTION_ARTIFACT_VERSION_NOTE = exports.OPTION_ARTIFACT_VERSION_FROM = exports.OPTION_ARTIFACT_PUBLISH_CREATE = exports.OPTION_ARTIFACT_ID = exports.OPTION_ARTIFACT_DOWNLOAD_PATH = exports.OPTION_ARTIFACT_PUBLISH_PATH = exports.OPTION_PIPELINE_RUN_ACTION_ID = exports.OPTION_PIPELINE_RUN_ID = exports.OPTION_PIPELINE_YAML = exports.TXT_PIPELINE_DELETED = exports.TXT_PIPELINE_DELETE_CONFIRM = exports.TXT_PIPELINE_UPDATED = exports.TXT_PIPELINE_CREATED = exports.OPTION_PIPELINE_NAME = exports.OPTION_PIPELINE_IDENTIFIER = exports.OPTION_PIPELINE_RUN_ARTIFACT = exports.OPTION_PIPELINE_RUN_ENVIRONMENT = exports.OPTION_PIPELINE_RUN_DELAY = exports.OPTION_PIPELINE_RUN_PAYLOAD = exports.ERR_RUN_PAYLOAD_TOO_MANY_FILES = exports.ERR_RUN_PAYLOAD_NOT_UPLOADED = exports.ERR_RUN_PAYLOAD_TOO_LARGE = exports.ERR_RUN_PAYLOAD_NO_ENTRIES = exports.ERR_RUN_VAR_FILE_INVALID = exports.ERR_RUN_VAR_FILE_NOT_FOUND = exports.OPTION_RUN_SINGLE_VAR_FILE = exports.OPTION_RUN_VAR_FILE = exports.OPTION_RUN_VAR = exports.OPTION_PIPELINE_RUN_PRIORITY = exports.OPTION_PIPELINE_RUN_CLEAR_CACHE = exports.OPTION_PIPELINE_RUN_REFRESH = exports.OPTION_PIPELINE_RUN_COMMENT = exports.OPTION_PIPELINE_RUN_PULL_REQUEST = exports.OPTION_PIPELINE_RUN_REVISION = exports.OPTION_PIPELINE_RUN_TAG = exports.OPTION_PIPELINE_RUN_BRANCH = exports.OPTION_REST_API_REGION = exports.OPTION_REST_API_ENDPOINT = exports.OPTION_DEFAULT_REGION = exports.OPTION_REGION = void 0;
|
|
10
10
|
exports.OPTION_COMPARE_URLS = exports.OPTION_COMPARE_RESPECT_ROBOTS = exports.OPTION_COMPARE_FOLLOW = exports.OPTION_EXEC_PARALLEL = exports.OPTION_EXEC_ONE_BY_ONE = exports.OPTION_EXEC_SKIP_DISCOVERY = exports.OPTION_EXEC_COMMAND = exports.OPTION_AGENT_DEBUG = exports.OPTION_AGENT_PORT = exports.OPTION_AGENT_TAG = exports.OPTION_AGENT_TUNNELING = exports.OPTION_AGENT_PROXY = exports.OPTION_AGENT_TARGET = exports.OPTION_PASS = exports.OPTION_APP = exports.OPTION_USER = exports.OPTION_AGENT_TOKEN = exports.OPTION_AGENT_START = exports.OPTION_AGENT_ID = exports.OPTION_ID = exports.OPTION_NAME = exports.OPTION_TARGET = exports.OPTION_TLS_TERMINATE = exports.OPTION_TLS_CA = exports.OPTION_TLS_CERT = exports.OPTION_TLS_KEY = exports.OPTION_HTTP_CIRCUIT_BREAKER = exports.OPTION_HTTP_COMPRESSION = exports.OPTION_HTTP_2 = exports.OPTION_HTTP_VERIFY = exports.OPTION_HTTP_LOG = exports.OPTION_HTTP_AUTH_BUDDY = exports.OPTION_HTTP_AUTH = exports.OPTION_HTTP_HOST = exports.OPTION_CONFIRM_DOMAIN_BUY = exports.OPTION_CONFIRM_FORCE = exports.OPTION_FORCE = exports.OPTION_TOKEN = exports.OPTION_TIMEOUT = exports.OPTION_FOLLOW = exports.OPTION_SERVE = exports.OPTION_HEADER_USER_AGENT = exports.OPTION_RESPONSE_HEADER = exports.OPTION_HEADER = exports.OPTION_WHITELIST = exports.OPTION_REST_API_PER_PAGE = exports.OPTION_REST_API_PAGE = exports.OPTION_REST_API_PROJECT = exports.OPTION_REST_API_WORKSPACE = exports.OPTION_FORMAT_JSONL = void 0;
|
|
11
11
|
exports.LOG_REGISTERING_TUNNEL = exports.LOG_GETTING_AGENT = exports.LOG_UNREGISTERING_AGENT = exports.LOG_REGION_DETECTED = exports.LOG_AGENT_REGISTERED = exports.LOG_SOCKET_DISCONNECTED = exports.LOG_SOCKET_CONNECTED = exports.LOG_AGENT_NSSM_CLEARING = exports.LOG_AGENT_NSSM_EXTRACTING = exports.LOG_AGENT_NSSM_DOWNLOADING = exports.LOG_AGENT_ENABLED = exports.LOG_AGENT_STARTING_SYSTEM = exports.LOG_AGENT_STOPPING_SYSTEM = exports.LOG_AGENT_ENABLING_SYSTEM = exports.LOG_AGENT_SYSTEM_SERVICE_CONFIG = exports.LOG_AGENT_EXTRACTING_ARCHIVE = exports.LOG_AGENT_DOWNLOADING_ARCHIVE = exports.LOG_AGENT_SYSTEM_DIR = exports.LOG_ERROR_SAVING_AGENT_LOCAL_CONFIG = exports.LOG_ERROR_REMOVING_AGENT_STANDALONE_LOCK_FILE = exports.LOG_ERROR_SAVING_AGENT_STANDALONE_CONFIG = exports.LOG_ERROR_SAVING_AGENT_SYSTEM_CONFIG = exports.LOG_SAVING_AGENT_LOCAL_CONFIG = exports.LOG_REMOVING_AGENT_PROC_ID = exports.LOG_SAVING_AGENT_PROC_ID = exports.LOG_SAVING_AGENT_SYSTEM_CONFIG = exports.LOG_REGISTERING_AGENT = exports.OPTION_CRAWL_OUTPUT_TYPES = exports.OPTION_CRAWL_OUTPUT_DIR = exports.OPTION_CRAWL_DELAY = exports.OPTION_CRAWL_LOCAL_STORAGE = exports.OPTION_CRAWL_DEVICES = exports.OPTION_CRAWL_BROWSERS = exports.OPTION_CRAWL_COLOR_SCHEME = exports.OPTION_CRAWL_XPATH_SELECTOR = exports.OPTION_CRAWL_CSS_SELECTOR = exports.OPTION_CRAWL_FULL_PAGE = exports.OPTION_CRAWL_QUALITY = exports.OPTION_CRAWL_OUTPUT_TYPE = exports.OPTION_CRAWL_FOLLOW = exports.OPTION_CRAWL_URL = exports.OPTION_COMPARE_WAIT_FOR = exports.OPTION_COMPARE_DELAY = exports.OPTION_COMPARE_HEADER = exports.OPTION_COMPARE_COOKIE = exports.OPTION_COMPARE_IGNORE = exports.OPTION_COMPARE_IGNORE_URLS = exports.OPTION_COMPARE_DRY_RUN = exports.OPTION_COMPARE_URLS_FILE = exports.OPTION_COMPARE_SITEMAP = void 0;
|
|
12
|
-
exports.
|
|
13
|
-
exports.
|
|
14
|
-
exports.
|
|
15
|
-
exports.
|
|
16
|
-
exports.
|
|
17
|
-
exports.
|
|
18
|
-
exports.
|
|
19
|
-
exports.
|
|
20
|
-
exports.
|
|
21
|
-
exports.EXAMPLE_CRAWL_LINK = exports.EXAMPLE_CRAWL_RUN = exports.EXAMPLE_TESTS_CAPTURE = exports.EXAMPLE_TESTS_VISUAL_SESSION_CLOSE = exports.EXAMPLE_TESTS_VISUAL_SESSION_CREATE = exports.EXAMPLE_TESTS_VISUAL_LINK = exports.EXAMPLE_TESTS_VISUAL_UPLOAD = exports.EXAMPLE_TESTS_VISUAL_SETUP = exports.EXAMPLE_TESTS_UNIT_LINK = exports.EXAMPLE_TESTS_UNIT_UPLOAD = exports.EXAMPLE_ARTIFACT_VERSION_DELETE = exports.EXAMPLE_ARTIFACT_VERSION_GET = exports.EXAMPLE_ARTIFACT_VERSION_LIST = exports.EXAMPLE_ARTIFACT_CREATE = exports.EXAMPLE_ARTIFACT_DELETE = exports.EXAMPLE_ARTIFACT_DOWNLOAD = exports.EXAMPLE_ARTIFACT_PUBLISH = exports.EXAMPLE_ARTIFACT_VERSION_CREATE = exports.EXAMPLE_PIPELINE_RUN_RETRY = exports.EXAMPLE_PIPELINE_RUN_LIST = exports.EXAMPLE_PIPELINE_LIST = exports.EXAMPLE_PIPELINE_YML = exports.EXAMPLE_PIPELINE_GET = exports.EXAMPLE_PIPELINE_UPDATE = exports.EXAMPLE_PIPELINE_DELETE = exports.EXAMPLE_PIPELINE_CREATE = exports.EXAMPLE_PIPELINE_RUN_CANCEL = exports.EXAMPLE_PIPELINE_RUN_APPLY = exports.EXAMPLE_PIPELINE_RUN_LOGS = exports.EXAMPLE_PIPELINE_RUN_JSONL = exports.EXAMPLE_PIPELINE_RUN_STATUS = exports.EXAMPLE_PIPELINE_RUN_START = exports.EXAMPLE_SANDBOX_ENDPOINT_LIST = exports.EXAMPLE_SANDBOX_ENDPOINT_GET = exports.EXAMPLE_SANDBOX_ENDPOINT_DELETE = exports.EXAMPLE_SANDBOX_ENDPOINT_CREATE = exports.EXAMPLE_SANDBOX_SNAPSHOT_LIST = exports.EXAMPLE_SANDBOX_SNAPSHOT_GET = exports.EXAMPLE_SANDBOX_SNAPSHOT_DELETE = exports.EXAMPLE_SANDBOX_SNAPSHOT_CREATE = exports.EXAMPLE_SANDBOX_EXEC_STATUS = void 0;
|
|
12
|
+
exports.LOG_TUNNEL_IDENTIFIED = exports.LOG_TUNNEL_DISCONNECTED = exports.LOG_TUNNEL_FAILED = exports.LOG_TUNNEL_CONNECTED = exports.LOG_AGENT_STARTED = exports.LOG_AGENT_UPDATE_ROLLBACK_MISSING = exports.LOG_AGENT_UPDATE_NOT_AN_AGENT = exports.LOG_AGENT_UPDATE_ROLLBACK_ACKED = exports.LOG_AGENT_UPDATE_ROLLED_BACK = exports.LOG_AGENT_UPDATE_ATTEMPT = exports.LOG_AGENT_UPDATE_COMMITTED = exports.LOG_AGENT_UPDATE_BINARY_INVALID = exports.ERR_AGENT_UPDATE_IN_PROGRESS = exports.LOG_AGENT_UPDATE_UNINSTALLED = exports.LOG_AGENT_UPDATE_VERSION_MISMATCH = exports.LOG_AGENT_UPDATE_FAILED = exports.LOG_AGENT_UPDATE_SWAPPED = exports.LOG_AGENT_UPDATE_NOT_NEEDED = exports.LOG_AGENT_UPDATE_NO_ADMIN = exports.LOG_AGENT_UPDATE_STANDALONE = exports.LOG_AGENT_UPDATE_REQUESTED = exports.LOG_AGENT_RIGHTS_SKIPPED = exports.LOG_AGENT_RIGHTS_DIR_SKIPPED = exports.LOG_AGENT_SERVER_STARTED = exports.LOG_ERROR_STARTING_AGENT_SERVER = exports.LOG_SSH_CONNECTION = exports.LOG_LATE_TARGET_ERROR = exports.LOG_LATE_CHANNEL_ERROR = exports.LOG_HANDSHAKE_TIMEOUT = exports.LOG_WRONG_STREAM = exports.LOG_DETECTED_STREAM = exports.LOG_HTTP2_SESSION_TIMEOUT = exports.LOG_HTTP2_SESSION_SHED_TAIL = exports.LOG_HTTP2_SESSION_SHED = exports.LOG_HTTP2_REQUEST = exports.LOG_HTTP2_CONNECTION = exports.LOG_HTTP1_REQUEST = exports.LOG_HTTP1_CONNECTION = exports.LOG_ERROR = exports.LOG_STOPPING_TUNNEL = exports.LOG_STARTING_TUNNEL = exports.LOG_ENABLING_AGENT_TUNNELING = exports.LOG_ENABLING_AGENT_PROXY = exports.LOG_ENABLING_AGENT_TARGET = exports.LOG_DISABLING_AGENT_TUNNELING = exports.LOG_DISABLING_AGENT_PROXY = exports.LOG_DISABLING_AGENT_TARGET = exports.LOG_REMOVING_TUNNEL = exports.LOG_TUNNEL_REGISTERED = exports.LOG_ERROR_WHILE_REFRESHING_AGENT = void 0;
|
|
13
|
+
exports.OPTION_SANDBOX_INSTALL_COMMANDS = exports.OPTION_SANDBOX_RESOURCES = exports.OPTION_SANDBOX_OS = exports.OPTION_SANDBOX_AGENT_NOTE = exports.OPTION_SANDBOX_NOTE = exports.OPTION_SANDBOX_NAME = exports.OPTION_SANDBOX_IDENTIFIER = exports.DESC_COMMAND_SANDBOX_SSH = exports.DESC_COMMAND_SANDBOX_APP = exports.DESC_COMMAND_SANDBOX_EXEC = exports.DESC_COMMAND_SANDBOX_STATUS = exports.DESC_COMMAND_SANDBOX_LOGS = exports.DESC_COMMAND_SANDBOX_RESTART = exports.DESC_COMMAND_SANDBOX_STOP = exports.DESC_COMMAND_SANDBOX_START = exports.DESC_COMMAND_SANDBOX_DESTROY = exports.DESC_COMMAND_SANDBOX_GET = exports.DESC_COMMAND_SANDBOX_LIST = exports.DESC_COMMAND_SANDBOX_UPDATE = exports.DESC_COMMAND_SANDBOX_GET_YAML = exports.DESC_COMMAND_SANDBOX_CREATE = exports.DESC_COMMAND_SANDBOX = exports.DEBUG_WAIT_FOR_IDLE_TIMEOUT = exports.DEBUG_WAIT_FOR_IDLE = exports.DEBUG_RESOURCE_DISCOVERY_TIMEOUT = exports.DEBUG_AUTO_WIDTH = exports.DEBUG_AUTO_SCROLL = exports.DEBUG_RESOURCE_CRAWLING_URL = exports.DEBUG_SNAPSHOT_PROCESSING = exports.DEBUG_SNAPSHOTS_PROCESSING = exports.DEBUG_EXEC_COMMAND = exports.DEBUG_EXEC_TEST_COMMAND = exports.LOG_INSTALLED_BROWSER = exports.LOG_SESSION_LINK = exports.LOG_SENDING_DATA = exports.LOG_SENDING_REQUEST = exports.LOG_PROCESSING_SNAPSHOTS = exports.LOG_RUNNING_EXEC_COMMAND = exports.LOG_TUNNEL_SSH_STREAM = exports.LOG_TUNNEL_TLS_AGENT_STREAM = exports.LOG_TUNNEL_TLS_REGION_STREAM = exports.LOG_TUNNEL_TLS_TARGET_STREAM = exports.LOG_TUNNEL_HTTP2_STREAM = exports.LOG_TUNNEL_HTTP1_STREAM = exports.LOG_TUNNEL_TCP_STREAM = exports.LOG_TUNNEL_HTTP_WRONG_USER_AGENTS = exports.LOG_TUNNEL_HTTP_CIRCUIT_BREAKER_OPEN = exports.LOG_TUNNEL_HTTP_MAX_INFLIGHT = exports.LOG_TUNNEL_HTTP_RATE_LIMIT = exports.LOG_TUNNEL_HTTP_WRON_AUTH = void 0;
|
|
14
|
+
exports.DESC_COMMAND_SANDBOX_EXEC_STATUS = exports.DESC_COMMAND_SANDBOX_EXEC_LIST = exports.DESC_COMMAND_SANDBOX_APP_REMOVE = exports.DESC_COMMAND_SANDBOX_APP_ADD = exports.DESC_COMMAND_SANDBOX_APP_LIST = exports.TXT_SANDBOX_WAITING_START = exports.TXT_SANDBOX_WAITING_STOP = exports.TXT_SANDBOX_WAITING_APPS = exports.TXT_SANDBOX_WAITING_SETUP = exports.TXT_SANDBOX_WAITING_RUNNING = exports.TXT_SANDBOX_STOPPED = exports.TXT_SANDBOX_STARTED = exports.TXT_SANDBOX_DESTROYED = exports.TXT_SANDBOX_DESTROY_CONFIRM = exports.TXT_SANDBOX_UPDATED = exports.TXT_SANDBOX_CREATED = exports.TXT_SANDBOX_CREATING = exports.TXT_SANDBOX_APP_STARTED = exports.TXT_SANDBOX_APP_STOPPED = exports.OPTION_SANDBOX_WAIT = exports.OPTION_SANDBOX_WAIT_APPS = exports.OPTION_SANDBOX_WAIT_CONFIGURED = exports.OPTION_SANDBOX_WAIT_RUNNING = exports.ERR_SANDBOX_STOP_FAILED = exports.ERR_SANDBOX_SSH_MISSING = exports.ERR_SANDBOX_SSH_NO_ACCESS = exports.ERR_SANDBOX_NOT_RUNNING = exports.ERR_SANDBOX_NO_COMMANDS = exports.ERR_SANDBOX_RUNNING_FAILED = exports.ERR_SANDBOX_STOP_TIMEOUT = exports.ERR_SANDBOX_SNAPSHOT_TIMEOUT = exports.ERR_SANDBOX_RUNNING_TIMEOUT = exports.ERR_SANDBOX_APPS_TIMEOUT = exports.ERR_SANDBOX_SETUP_TIMEOUT = exports.ERR_SANDBOX_APP_FAILED = exports.ERR_SANDBOX_SETUP_FAILED = exports.ERR_SANDBOX_INVALID_RESOURCES = exports.ERR_SANDBOX_APP_NOT_FOUND = exports.ERR_SANDBOX_NOT_FOUND = exports.OPTION_SANDBOX_SSH_PRINT = exports.OPTION_SANDBOX_SSH_IDENTITY = exports.OPTION_SANDBOX_SSH_ARGS = exports.OPTION_SANDBOX_RUNTIME = exports.OPTION_SANDBOX_TIMEOUT = exports.OPTION_SANDBOX_FETCH = exports.OPTION_SANDBOX_APP_DIR = exports.OPTION_SANDBOX_APP_COMMAND = exports.OPTION_SANDBOX_YAML = exports.OPTION_SANDBOX_TAGS = exports.OPTION_SANDBOX_INSTALL_SCRIPT = void 0;
|
|
15
|
+
exports.OPTION_SANDBOX_CP_IGNORE = exports.OPTION_SANDBOX_CP_USER = exports.OPTION_SANDBOX_CP_DOWNLOAD_REPLACE = exports.OPTION_SANDBOX_CP_DOWNLOAD_MERGE = exports.OPTION_SANDBOX_CP_DEST = exports.OPTION_SANDBOX_CP_SOURCE = exports.DESC_COMMAND_SANDBOX_CP = exports.ERR_SANDBOX_ENDPOINTS_NOT_FOUND = exports.ERR_SANDBOX_ENDPOINT_NOT_FOUND = exports.ERR_SANDBOX_ENDPOINT_EXISTS = exports.TXT_SANDBOX_ENDPOINT_DELETED = exports.TXT_SANDBOX_ENDPOINT_DELETE_CONFIRM = exports.TXT_SANDBOX_ENDPOINT_ADDED = exports.TXT_SANDBOX_APP_REMOVED = exports.TXT_SANDBOX_APP_ADDED = exports.OPTION_SANDBOX_ENDPOINT_TYPE = exports.OPTION_SANDBOX_ENDPOINT_PORT = exports.OPTION_SANDBOX_ENDPOINT_NAME_ARG = exports.OPTION_SANDBOX_ENDPOINT_NAME = exports.DESC_COMMAND_SANDBOX_ENDPOINT_DELETE = exports.DESC_COMMAND_SANDBOX_ENDPOINT_ADD = exports.DESC_COMMAND_SANDBOX_ENDPOINT_GET = exports.DESC_COMMAND_SANDBOX_ENDPOINT_LIST = exports.DESC_COMMAND_SANDBOX_ENDPOINT = exports.ERR_SANDBOX_SNAPSHOTS_NOT_FOUND = exports.ERR_SANDBOX_SNAPSHOT_NOT_FOUND = exports.ERR_SANDBOX_SNAPSHOT_FAILED = exports.TXT_SANDBOX_SNAPSHOT_WAITING = exports.TXT_SANDBOX_SNAPSHOT_DELETE_CONFIRM = exports.TXT_SANDBOX_SNAPSHOT_DELETED = exports.TXT_SANDBOX_SNAPSHOT_CREATED = exports.OPTION_SANDBOX_FROM_SNAPSHOT = exports.OPTION_SANDBOX_SNAPSHOT_NAME_ARG = exports.OPTION_SANDBOX_SNAPSHOT_NAME = exports.DESC_COMMAND_SANDBOX_SNAPSHOT_DELETE = exports.DESC_COMMAND_SANDBOX_SNAPSHOT_GET = exports.DESC_COMMAND_SANDBOX_SNAPSHOT_CREATE = exports.DESC_COMMAND_SANDBOX_SNAPSHOT_LIST = exports.DESC_COMMAND_SANDBOX_SNAPSHOT = exports.TXT_SANDBOX_COMMAND_KILLED = exports.OPTION_SANDBOX_COMMAND_KILL_CONFIRM = exports.OPTION_SANDBOX_LOGS_LIMIT = exports.OPTION_SANDBOX_APP_ID = exports.OPTION_SANDBOX_COMMAND_ID = exports.DESC_COMMAND_SANDBOX_EXEC_KILL = exports.DESC_COMMAND_SANDBOX_EXEC_LOGS = exports.DESC_COMMAND_SANDBOX_APP_START = exports.DESC_COMMAND_SANDBOX_APP_STOP = exports.DESC_COMMAND_SANDBOX_APP_STATUS = exports.DESC_COMMAND_SANDBOX_APP_LOGS = void 0;
|
|
16
|
+
exports.OPT_COMMAND_API_INFO_URL = exports.OPT_COMMAND_API_INFO_SCHEMA = exports.OPT_COMMAND_API_INFO_METHOD = exports.OPT_COMMAND_API_LIST_SEARCH = exports.OPT_COMMAND_API_LIST_METHOD = exports.ERR_API_REQUEST_BODY_VALUE = exports.ERR_API_REQUEST_QUERY_VALUE = exports.ERR_API_REQUEST_INVALID_JSON = exports.ERR_API_REQUEST_FILE_ERROR = exports.ERR_API_REQUEST_OUTPUT_EXISTS = exports.DESC_COMMAND_API_INFO = exports.DESC_COMMAND_API_FORM = exports.DESC_COMMAND_API_JSON = exports.DESC_COMMAND_API_DATA = exports.DESC_COMMAND_API_OUTPUT = exports.DESC_COMMAND_API_REQUEST_QUERY = exports.DESC_COMMAND_API_PROJECT = exports.DESC_COMMAND_API_WORKSPACE = exports.DESC_COMMAND_API_REQUEST_URL = exports.DESC_COMMAND_API_GET = exports.DESC_COMMAND_API_PATCH = exports.DESC_COMMAND_API_DELETE = exports.DESC_COMMAND_API_PUT = exports.DESC_COMMAND_API_POST = exports.DESC_COMMAND_API_LIST = exports.DESC_COMMAND_API = exports.ERR_WHOAMI_LOGOUT = exports.TXT_WHOAMI_NO_WORKSPACE = exports.DESC_COMMAND_WHOAMI = exports.TXT_SANDBOX_EXEC_FAILED = exports.TXT_SANDBOX_EXEC_INPROGRESS = exports.TXT_SANDBOX_EXEC_SUCCESS = exports.TXT_SANDBOX_EXEC_BACKGROUND = exports.TXT_SANDBOX_EXEC_ID = exports.ERR_SANDBOX_CP_INVALID_SOURCE = exports.ERR_SANDBOX_CP_INVALID_DEST = exports.ERR_SANDBOX_CP_REPLACE = exports.ERR_SANDBOX_CP_MKDIR = exports.ERR_SANDBOX_CP_PATH_EXISTS = exports.ERR_SANDBOX_CP_NOT_EMPTY_DIR = exports.ERR_SANDBOX_CP_READDIR = exports.ERR_SANDBOX_CP_DEST_NOT_FOLDER = exports.ERR_SANDBOX_CP_SOURCE_NOT_FOUND = exports.TXT_SANDBOX_CP_DONE = exports.TXT_SANDBOX_CP_PROGRESS = exports.TXT_SANDBOX_UNZIPPING_COUNT = exports.TXT_SANDBOX_UNZIP_DONE = exports.TXT_SANDBOX_UNZIP = exports.TXT_SANDBOX_CP_DOWNLOAD_DONE = exports.TXT_SANDBOX_CP_DOWNLOAD = void 0;
|
|
17
|
+
exports.ERR_LOGIN_INVALID_BASE_URL = exports.ERR_LOGIN_NO_WORKSPACE_FOUND = exports.ERR_LOGIN_NO_WORKSPACES = exports.ERR_REGISTER_HTTP_CANCEL = exports.ERR_LOGIN_HTTP_CANCEL = exports.ERR_LOGIN_HTTP_FAILED = exports.ERR_LOGIN_HTTP_SERVER_PORT_TAKEN = exports.TXT_REGISTER_SUCCESS = exports.TXT_LOGIN_SUCCESS = exports.TXT_LOGIN_SELECT_WORKSPACE = exports.TXT_LOGIN_ENTER_BASE_URL = exports.TXT_LOGIN_PROVIDE_CODE = exports.TXT_REGISTER_OPEN_URL = exports.TXT_LOGIN_OPEN_URL = exports.TXT_REGISTER_OPENING_STAR = exports.TXT_LOGIN_OPENING_STAR = exports.TXT_REGISTER_OPENING = exports.TXT_LOGIN_OPENING = exports.TXT_LOGIN_SELECT_REGION = exports.TXT_WORKSPACE_NONE = exports.TXT_WORKSPACE_SET_SUCCESS = exports.ARG_COMMAND_WORKSPACE = exports.DESC_COMMAND_WORKSPACE_GET = exports.DESC_COMMAND_WORKSPACE_SET = exports.DESC_COMMAND_WORKSPACE_LIST = exports.DESC_COMMAND_WORKSPACE = exports.TXT_COMMAND_REGISTER_PROVIDE_NAME = exports.TXT_COMMAND_REGISTER_PROVIDE_EMAIL = exports.ERR_COMMAND_REGISTER_INVALID_NAME = exports.ERR_COMMAND_REGISTER_INVALID_EMAIL = exports.OPT_COMMAND_REGISTER_NAME = exports.OPT_COMMAND_REGISTER_EMAIL = exports.DESC_COMMAND_REGISTER = exports.TXT_LOGOUT_SUCCESS = exports.DESC_COMMAND_LOGOUT = exports.DESC_COMMAND_LOGIN = exports.HELP_COMMAND_MCP = exports.ERR_MCP_TOOL_FILTERED = exports.ERR_MCP_TOOLS_CATEGORY = exports.OPT_COMMAND_MCP_TOOLS = exports.ERR_MCP_REFRESH_FAILED = exports.ERR_MCP_URL_INVALID = exports.ERR_MCP_ENDPOINT = exports.DESC_COMMAND_MCP = exports.ERR_API_MEDIA_TYPE_NOT_IMPLEMENTED = exports.ERR_API_PARAMETER_NOT_REPLACED = exports.TXT_API_ENDPOINT_REQUIRED_SCOPES = exports.ERR_API_ENDPOINT_NOT_FOUND = exports.ERR_API_WRONG_METHOD = exports.ERR_SCHEMA_FETCH_FAILED = void 0;
|
|
18
|
+
exports.ERR_WRONG_ROUTE_TARGET = exports.ERR_COMMAND_ROUTE_NO_TARGET = exports.ERR_COMMAND_ROUTE_TYPE = exports.TXT_COMMAND_ROUTES_NOT_FOUND = exports.TXT_COMMAND_DISTROS_NOT_FOUND = exports.TXT_COMMAND_ROUTE_DELETED = exports.TXT_COMMAND_DISTRO_DELETED = exports.TXT_COMMAND_ROUTE_DELETE_CONFIRM = exports.TXT_COMMAND_DISTRO_DELETE_CONFIRM = exports.ERR_COMMAND_DISTRO_ENABLE_DISABLE = exports.ERR_COMMAND_DISTRO_NO_UPDATE = exports.ERR_COMMAND_ROUTE_NO_UPDATE = exports.ERR_COMMAND_DISTRO_NOT_FOUND = exports.ERR_COMMAND_SCOPE = exports.TXT_COMMAND_DISTRO_UPDATED = exports.TXT_COMMAND_ROUTE_UPDATED = exports.TXT_ROUTE_SERVE = exports.TXT_COMMAND_ROUTE_CREATED = exports.TXT_COMMAND_DISTRO_CREATED = exports.ERR_COMMAND_SCOPE_NO_PROJECT = exports.OPT_COMMAND_DISTRO_DISABLE = exports.OPT_COMMAND_DISTRO_ENABLE = exports.OPT_COMMAND_DISTRO_AGENT_NOTE = exports.OPT_COMMAND_DISTRO_NOTE = exports.OPT_COMMAND_DISTRO_NAME = exports.OPT_COMMAND_ROUTE_TARGET = exports.OPT_COMMAND_ROUTE_AGENT_NOTE = exports.OPT_COMMAND_ROUTE_NOTE = exports.OPT_COMMAND_ROUTE_PATH = exports.OPT_COMMAND_ROUTE_DOMAIN = exports.OPT_COMMAND_ROUTE_SUBDOMAIN = exports.OPT_COMMAND_ROUTE_TYPE = exports.OPT_COMMAND_ROUTE_ID = exports.OPT_COMMAND_DISTRO_IDENTIFIER = exports.OPT_COMMAND_SCOPE = exports.OPT_COMMAND_AGENT_NOTE = exports.OPT_COMMAND_NOTE = exports.DESC_COMMAND_ROUTE = exports.DESC_COMMAND_ROUTE_UPDATE = exports.DESC_COMMAND_ROUTE_DELETE = exports.DESC_COMMAND_ROUTE_GET = exports.DESC_COMMAND_DISTRO_UPDATE = exports.DESC_COMMAND_DISTRO_GET = exports.DESC_COMMAND_ROUTE_LIST = exports.DESC_COMMAND_DISTRO_LIST = exports.DESC_COMMAND_DISTRO_DELETE = exports.DESC_COMMAND_ROUTE_CREATE = exports.DESC_COMMAND_DISTRO_CREATE = exports.DESC_COMMAND_DISTRO = exports.ERR_API_MESSAGE_REPLACER = void 0;
|
|
19
|
+
exports.OPT_COMMAND_PROJECT_LINK_GIT = exports.OPT_COMMAND_PROJECT_LINK_RELINK = exports.DESC_COMMAND_PROJECT_LINK = exports.DESC_COMMAND_PROJECT_LIST = exports.DESC_COMMAND_PROJECT_GIT = exports.DESC_COMMAND_PROJECT_GIT_CREDENTIAL = exports.DESC_COMMAND_PROJECT = exports.TXT_ARTIFACT_VERSION_DOWNLOAD = exports.TXT_ARTIFACT_PUBLISH = exports.TXT_ARTIFACT_CREATED = exports.TXT_ARTIFACT_VERSION_DELETED = exports.TXT_ARTIFACT_DELETED = exports.ERR_COMMAND_ARTIFACT_TYPE = exports.OPT_COMMAND_ARTIFACT_VERSION = exports.OPT_COMMAND_ARTIFACT_IDENTIFIER = exports.OPT_COMMAND_ARTIFACT_CREATE_IDENTIFIER = exports.OPT_COMMAND_ARTIFACT_NAME = exports.OPT_COMMAND_ARTIFACT_TYPE = exports.DESC_COMMAND_ARTIFACT_CREATE = exports.DESC_COMMAND_ARTIFACT_GET = exports.TXT_ARTIFACT_DOCKER_LOGIN_FAILED = exports.TXT_ARTIFACT_DOCKER_LOGIN_SUCCESS = exports.TXT_ARTIFACT_VERSION_DELETE_CONFIRM = exports.TXT_ARTIFACT_DELETE_CONFIRM = exports.DESC_COMMAND_ARTIFACT_DELETE = exports.ERR_COMMAND_ARTIFACT_NO_PROJECTS = exports.DESC_COMMAND_ARTIFACT_VERSION_GET = exports.DESC_COMMAND_ARTIFACT_VERSION_LIST = exports.DESC_COMMAND_ARTIFACT_VERSION_DELETE = exports.DESC_COMMAND_ARTIFACT_DOCKER_LOGIN = exports.DESC_COMMAND_ARTIFACT_LIST = exports.DESC_COMMAND_ARTIFACT_VERSION = exports.ERR_COMMAND_DOMAIN_UNAVAILABLE = exports.OPTION_COMMAND_DOMAIN_IDENTIFIER = exports.ERR_COMMAND_DOMAIN_NO_DOMAINS = exports.TXT_COMMAND_DOMAIN_PROMPT_REQUIRED = exports.TXT_COMMAND_DOMAIN_BUY_SELECT_DOMAIN = exports.TXT_COMMAND_DOMAIN_PROVIDE_PROMPT = exports.ERR_COMMAND_DOMAIN_NOT_FOUND = exports.OPT_COMMAND_DOMAIN_ONLY_AVAILABLE = exports.OPT_COMMAND_DOMAIN_SORT = exports.OPT_COMMAND_DOMAIN_PHRASE = exports.OPT_COMMAND_DOMAIN_BUY_OWNER = exports.OPT_COMMAND_DOMAIN_BUY_TLD = exports.DESC_COMMAND_DOMAIN_GET = exports.DESC_COMMAND_DOMAIN_LIST = exports.DESC_COMMAND_DOMAIN_SEARCH = exports.DESC_COMMAND_DOMAIN_BUY = exports.DESC_COMMAND_DOMAIN = exports.ERR_ROUTE_NO_DEFAULT = void 0;
|
|
20
|
+
exports.EXAMPLE_SANDBOX_APP_REMOVE = exports.EXAMPLE_SANDBOX_APP_ADD = exports.EXAMPLE_SANDBOX_APP_START = exports.EXAMPLE_SANDBOX_APP_LOGS = exports.EXAMPLE_SANDBOX_EXEC_LIST = exports.EXAMPLE_SANDBOX_APP_LIST = exports.EXAMPLE_SANDBOX_EXEC_KILL = exports.EXAMPLE_SANDBOX_SSH = exports.EXAMPLE_SANDBOX_EXEC_COMMAND = exports.EXAMPLE_TUNNEL_START = exports.EXAMPLE_TUNNEL_TCP = exports.EXAMPLE_TUNNEL_TLS = exports.EXAMPLE_AGENT_TUNNEL_START = exports.EXAMPLE_AGENT_TUNNEL_STATUS = exports.EXAMPLE_AGENT_TUNNEL_REMOVE = exports.EXAMPLE_AGENT_TUNNEL_LIST = exports.EXAMPLE_TUNNEL_HTTP = exports.EXAMPLE_SANDBOX_CREATE = exports.EXAMPLE_DISTRO_CREATE = exports.EXAMPLE_ROUTE_CREATE = exports.EXAMPLE_ROUTE_LIST = exports.EXAMPLE_ROUTE_UPDATE = exports.EXAMPLE_ROUTE_DELETE = exports.EXAMPLE_DISTRO_DELETE = exports.EXAMPLE_ROUTE_GET = exports.EXAMPLE_DISTRO_UPDATE = exports.EXAMPLE_DISTRO_GET = exports.EXAMPLE_DISTRO_LIST = exports.EXAMPLE_SANDBOX_CP = exports.ERR_PROJECT_NO_PROJECTS = exports.TXT_LOGIN_SELECT_PROJECT = exports.TXT_COMMAND_PROJECT_CREATED = exports.TXT_COMMAND_PROJECT_LINK_NOT_FOUND = exports.TXT_COMMAND_PROJECT_LINK_NAME = exports.TXT_COMMAND_PROJECT_LINK_SELECT_PROJECT = exports.TXT_COMMAND_PROJECT_LINK_TO = exports.TXT_COMMAND_PROJECT_LINK_EXISTING_DESC = exports.TXT_COMMAND_PROJECT_LINK_EXISTING = exports.TXT_COMMAND_PROJECT_LINK_CREATE_NEW_DESC = exports.TXT_COMMAND_PROJECT_LINK_CREATE_NEW = exports.ERR_COMMAND_PROJECT_LINK_DIR_NOT_DIR = exports.TXT_COMMAND_PROJECT_LINK_GIT_REPO_INITIALIZED = exports.TXT_COMMAND_PROJECT_LINK_GIT_REPO = exports.TXT_COMMAND_PROJECT_LINK_DIR_CONFIRM = exports.TXT_COMMAND_PROJECT_LINK_DIR_LINKED = exports.ERR_COMMAND_PROJECT_LINK_DIR_CREATE = exports.OPT_COMMAND_PROJECT_LINK_TRY_NOW = exports.OPT_COMMAND_PROJECT_LINK_SET_GIT_REMOTE = exports.OPT_COMMAND_PROJECT_LINK_HAS_REMOTE = exports.OPT_COMMAND_PROJECT_LINK_DIRECTORY = void 0;
|
|
21
|
+
exports.EXAMPLE_CRAWL_LINK = exports.EXAMPLE_CRAWL_RUN = exports.EXAMPLE_TESTS_CAPTURE = exports.EXAMPLE_TESTS_VISUAL_SESSION_CLOSE = exports.EXAMPLE_TESTS_VISUAL_SESSION_CREATE = exports.EXAMPLE_TESTS_VISUAL_LINK = exports.EXAMPLE_TESTS_VISUAL_UPLOAD = exports.EXAMPLE_TESTS_VISUAL_SETUP = exports.EXAMPLE_TESTS_UNIT_LINK = exports.EXAMPLE_TESTS_UNIT_UPLOAD = exports.EXAMPLE_ARTIFACT_VERSION_DELETE = exports.EXAMPLE_ARTIFACT_VERSION_GET = exports.EXAMPLE_ARTIFACT_VERSION_LIST = exports.EXAMPLE_ARTIFACT_CREATE = exports.EXAMPLE_ARTIFACT_DELETE = exports.EXAMPLE_ARTIFACT_DOWNLOAD = exports.EXAMPLE_ARTIFACT_PUBLISH = exports.EXAMPLE_ARTIFACT_VERSION_CREATE = exports.EXAMPLE_PIPELINE_RUN_RETRY = exports.EXAMPLE_PIPELINE_RUN_LIST = exports.EXAMPLE_PIPELINE_LIST = exports.EXAMPLE_PIPELINE_YML = exports.EXAMPLE_PIPELINE_GET = exports.EXAMPLE_PIPELINE_UPDATE = exports.EXAMPLE_PIPELINE_DELETE = exports.EXAMPLE_PIPELINE_CREATE = exports.EXAMPLE_PIPELINE_RUN_CANCEL = exports.EXAMPLE_PIPELINE_RUN_APPLY = exports.EXAMPLE_PIPELINE_RUN_LOGS = exports.EXAMPLE_PIPELINE_RUN_JSONL = exports.EXAMPLE_PIPELINE_RUN_STATUS = exports.EXAMPLE_PIPELINE_RUN_START = exports.EXAMPLE_SANDBOX_ENDPOINT_LIST = exports.EXAMPLE_SANDBOX_ENDPOINT_GET = exports.EXAMPLE_SANDBOX_ENDPOINT_DELETE = exports.EXAMPLE_SANDBOX_ENDPOINT_CREATE = exports.EXAMPLE_SANDBOX_SNAPSHOT_LIST = exports.EXAMPLE_SANDBOX_SNAPSHOT_GET = exports.EXAMPLE_SANDBOX_SNAPSHOT_DELETE = exports.EXAMPLE_SANDBOX_SNAPSHOT_CREATE = exports.EXAMPLE_SANDBOX_EXEC_STATUS = exports.EXAMPLE_SANDBOX_EXEC_LOGS = exports.EXAMPLE_SANDBOX_APP_STATUS = exports.EXAMPLE_SANDBOX_APP_STOP = void 0;
|
|
22
22
|
const utils_1 = require("./utils");
|
|
23
23
|
exports.ERR_CANCELLED = 'Cancelled';
|
|
24
24
|
exports.ERR_REST_API_GENERAL_ERROR = 'Something went wrong';
|
|
@@ -559,6 +559,13 @@ const LOG_HTTP2_CONNECTION = (ip) => `HTTP/2 server: New tunnel connection from
|
|
|
559
559
|
exports.LOG_HTTP2_CONNECTION = LOG_HTTP2_CONNECTION;
|
|
560
560
|
const LOG_HTTP2_REQUEST = (method, url) => `HTTP/2 server: New request ${method} ${url}`;
|
|
561
561
|
exports.LOG_HTTP2_REQUEST = LOG_HTTP2_REQUEST;
|
|
562
|
+
const LOG_HTTP2_SESSION_SHED = (ip, suppressed) => `HTTP/2 server: session limit reached, refusing connection from ${ip}` +
|
|
563
|
+
(suppressed ? ` (+${suppressed} more since the last report)` : '');
|
|
564
|
+
exports.LOG_HTTP2_SESSION_SHED = LOG_HTTP2_SESSION_SHED;
|
|
565
|
+
const LOG_HTTP2_SESSION_SHED_TAIL = (suppressed) => `HTTP/2 server: session limit reached, refused +${suppressed} more connections ` +
|
|
566
|
+
`since the last report, then it stopped`;
|
|
567
|
+
exports.LOG_HTTP2_SESSION_SHED_TAIL = LOG_HTTP2_SESSION_SHED_TAIL;
|
|
568
|
+
exports.LOG_HTTP2_SESSION_TIMEOUT = 'HTTP/2 server: closing idle session';
|
|
562
569
|
const LOG_DETECTED_STREAM = (type) => `Detected stream '${type}'`;
|
|
563
570
|
exports.LOG_DETECTED_STREAM = LOG_DETECTED_STREAM;
|
|
564
571
|
exports.LOG_WRONG_STREAM = 'Wrong stream type';
|
|
@@ -9,6 +9,7 @@ const logger_1 = __importDefault(require("../../logger"));
|
|
|
9
9
|
const texts_1 = require("../../texts");
|
|
10
10
|
const tunnel_1 = require("../../types/tunnel");
|
|
11
11
|
const jwks_1 = __importDefault(require("./jwks"));
|
|
12
|
+
const ip_1 = require("./ip");
|
|
12
13
|
const COOKIE_NAME = 'jwt_token';
|
|
13
14
|
const AUTH_ME_PATH = '/.buddy/auth/me';
|
|
14
15
|
const AUTH_USER_CACHE_TTL = 60 * 1000;
|
|
@@ -122,13 +123,7 @@ class TunnelHttpAuth {
|
|
|
122
123
|
if (!user || !user.name || !user.pass)
|
|
123
124
|
return false;
|
|
124
125
|
const client = this._getClient();
|
|
125
|
-
|
|
126
|
-
if (req.httpVersion === '2.0') {
|
|
127
|
-
ipAddress = req.socket.stream ? req.socket.stream.remoteAddress : '::1';
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
ipAddress = req.socket.remoteAddress;
|
|
131
|
-
}
|
|
126
|
+
const ipAddress = (0, ip_1.requestIp)(req);
|
|
132
127
|
try {
|
|
133
128
|
const { statusCode, body } = await client.request({
|
|
134
129
|
path: `/tunnel/auth/pat`,
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.requestIp = void 0;
|
|
4
|
+
const utils_1 = require("../../utils");
|
|
5
|
+
// The client address behind a request, from whichever place this channel carries it.
|
|
6
|
+
//
|
|
7
|
+
// Historically the address belonged to the CHANNEL: the worker put it in the 50-byte handshake and
|
|
8
|
+
// the agent set it as the channel's remoteAddress, which was exact because a channel served one
|
|
9
|
+
// client. Shared h2 channels break that - one channel now carries requests from many clients - so
|
|
10
|
+
// on those the worker sends the address per request instead.
|
|
11
|
+
//
|
|
12
|
+
// Which source to trust is decided by the channel's handshake type (`sharedIp`), never by the
|
|
13
|
+
// header being present. A worker old enough to open a non-shared channel is also old enough not to
|
|
14
|
+
// strip a client-supplied copy of the header, so trusting presence alone would let any client on
|
|
15
|
+
// such a tunnel dictate the address seen by the target app, the rate limiter, the request log and
|
|
16
|
+
// the PAT audit trail. Tie it to the channel and that whole class of confusion cannot arise.
|
|
17
|
+
const channelOf = (req) => req.httpVersion === '2.0' ? req.socket.stream : req.socket;
|
|
18
|
+
const requestIp = (req) => {
|
|
19
|
+
const channel = channelOf(req);
|
|
20
|
+
if (channel && channel.sharedIp) {
|
|
21
|
+
const claimed = req.headers ? req.headers[utils_1.TUNNEL_CLIENT_IP_HEADER] : null;
|
|
22
|
+
// A shared channel with no header means a worker bug, not a client one. '::1' matches what the
|
|
23
|
+
// legacy path already reports when it cannot resolve an address, so callers need no new case.
|
|
24
|
+
return (Array.isArray(claimed) ? claimed[0] : claimed) || '::1';
|
|
25
|
+
}
|
|
26
|
+
if (req.httpVersion === '2.0') {
|
|
27
|
+
return channel ? channel.remoteAddress : '::1';
|
|
28
|
+
}
|
|
29
|
+
return req.socket.remoteAddress;
|
|
30
|
+
};
|
|
31
|
+
exports.requestIp = requestIp;
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.TunnelHttpLogRequest = void 0;
|
|
7
7
|
const events_1 = __importDefault(require("events"));
|
|
8
8
|
const stream_1 = __importDefault(require("./stream"));
|
|
9
|
+
const ip_1 = require("./ip");
|
|
9
10
|
const utils_1 = require("../../utils");
|
|
10
11
|
const tunnel_1 = require("../../types/tunnel");
|
|
11
12
|
class TunnelHttpLogRequest extends events_1.default {
|
|
@@ -153,14 +154,7 @@ class TunnelHttpLog extends events_1.default {
|
|
|
153
154
|
}
|
|
154
155
|
}
|
|
155
156
|
getIp(req) {
|
|
156
|
-
|
|
157
|
-
if (req.httpVersion === '2.0') {
|
|
158
|
-
ip = req.socket.stream ? req.socket.stream.remoteAddress : '::1';
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
ip = req.socket.remoteAddress;
|
|
162
|
-
}
|
|
163
|
-
return ip;
|
|
157
|
+
return (0, ip_1.requestIp)(req);
|
|
164
158
|
}
|
|
165
159
|
increaseRateLimit(req) {
|
|
166
160
|
const ip = this.getIp(req);
|
|
@@ -13,6 +13,7 @@ const node_stream_1 = require("node:stream");
|
|
|
13
13
|
const texts_1 = require("../texts");
|
|
14
14
|
const logger_1 = __importDefault(require("../logger"));
|
|
15
15
|
const serve_1 = __importDefault(require("./http/serve"));
|
|
16
|
+
const ip_1 = require("./http/ip");
|
|
16
17
|
const https_1 = __importDefault(require("https"));
|
|
17
18
|
const compression_1 = __importDefault(require("./compression"));
|
|
18
19
|
const html_1 = __importDefault(require("./html"));
|
|
@@ -151,15 +152,7 @@ class TunnelHttp extends events_1.default {
|
|
|
151
152
|
}
|
|
152
153
|
getRequestHeaders(http2) {
|
|
153
154
|
const h = {};
|
|
154
|
-
|
|
155
|
-
if (this.req.httpVersion === '2.0') {
|
|
156
|
-
ip = this.req.socket.stream
|
|
157
|
-
? this.req.socket.stream.remoteAddress
|
|
158
|
-
: '::1';
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
ip = this.req.socket.remoteAddress;
|
|
162
|
-
}
|
|
155
|
+
const ip = (0, ip_1.requestIp)(this.req);
|
|
163
156
|
if (http2) {
|
|
164
157
|
h[':scheme'] = this.proto || '';
|
|
165
158
|
h[':authority'] = this.getHostHeader();
|
|
@@ -192,6 +185,9 @@ class TunnelHttp extends events_1.default {
|
|
|
192
185
|
'transfer-encoding',
|
|
193
186
|
'strict-transport-security',
|
|
194
187
|
'te',
|
|
188
|
+
// Ours, not the client's: it carried the address here (requestIp) and x-forwarded-for is
|
|
189
|
+
// where the target is supposed to read it. Same treatment the worker gives x-forwarded-auth.
|
|
190
|
+
utils_1.TUNNEL_CLIENT_IP_HEADER,
|
|
195
191
|
];
|
|
196
192
|
if (!(allowUpgrade && headers.connection === 'Upgrade')) {
|
|
197
193
|
hop.push('upgrade');
|
|
@@ -32,11 +32,64 @@ class ServerHttp1 extends events_1.default {
|
|
|
32
32
|
}
|
|
33
33
|
this.server = null;
|
|
34
34
|
}
|
|
35
|
+
// node's keep-alive reaping (server.keepAliveTimeout, 5s default) is driven through
|
|
36
|
+
// socket.setTimeout(), which net.Socket has but an ssh2 channel - a plain Duplex - does not.
|
|
37
|
+
// node guards those calls with a typeof check, so on channels the reaping silently never
|
|
38
|
+
// happens and an idle keep-alive channel lives until the worker tears it down. This shim
|
|
39
|
+
// supplies the missing method with net.Socket semantics: an activity-reset timer that only
|
|
40
|
+
// emits 'timeout' and leaves the destroy decision to node's own handler - which is also what
|
|
41
|
+
// keeps upgraded (websocket) connections exempt, exactly as on a real socket, because node
|
|
42
|
+
// disarms the timer for them instead of ever arming keepAliveTimeout.
|
|
43
|
+
armChannelTimeout(stream) {
|
|
44
|
+
if (typeof stream.setTimeout === 'function')
|
|
45
|
+
return;
|
|
46
|
+
let ms = 0;
|
|
47
|
+
let timer = null;
|
|
48
|
+
const rearm = () => {
|
|
49
|
+
if (timer)
|
|
50
|
+
clearTimeout(timer);
|
|
51
|
+
timer = null;
|
|
52
|
+
if (ms > 0)
|
|
53
|
+
timer = setTimeout(() => stream.emit('timeout'), ms);
|
|
54
|
+
};
|
|
55
|
+
stream.setTimeout = (msecs, callback) => {
|
|
56
|
+
ms = msecs || 0;
|
|
57
|
+
if (callback)
|
|
58
|
+
stream.once('timeout', callback);
|
|
59
|
+
rearm();
|
|
60
|
+
return stream;
|
|
61
|
+
};
|
|
62
|
+
stream.on('data', rearm);
|
|
63
|
+
const write = stream.write.bind(stream);
|
|
64
|
+
stream.write = (...args) => {
|
|
65
|
+
rearm();
|
|
66
|
+
return write(...args);
|
|
67
|
+
};
|
|
68
|
+
stream.once('close', () => {
|
|
69
|
+
ms = 0;
|
|
70
|
+
if (timer)
|
|
71
|
+
clearTimeout(timer);
|
|
72
|
+
timer = null;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
35
75
|
handleSshTunnel(stream, _, ip) {
|
|
36
76
|
logger_1.default.debug((0, texts_1.LOG_HTTP1_CONNECTION)(ip));
|
|
77
|
+
// No server left (stop() ran): destroy, never arm. The shim below attaches a 'data' listener,
|
|
78
|
+
// which resumes the channel - arming without a consumer would silently drain the request.
|
|
79
|
+
if (!this.server) {
|
|
80
|
+
stream.destroy();
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
37
83
|
stream.remoteAddress = ip;
|
|
38
|
-
|
|
39
|
-
|
|
84
|
+
// Arm AFTER handing the channel over, the same order routing uses in its ServerHttp2.handleSocket.
|
|
85
|
+
// Before the emit our 'data' listener would be the only consumer, so anything arriving in that
|
|
86
|
+
// window would be dropped; afterwards node is already reading. Adding the listener late is safe:
|
|
87
|
+
// node wraps socket.on to unconsume a parser bound to a real socket handle, and unconsume() is
|
|
88
|
+
// a no-op without socket._handle (_http_server.js), which a channel never has. Nothing arms a
|
|
89
|
+
// timeout during the emit either - server.timeout stays 0 here and node only arms
|
|
90
|
+
// keepAliveTimeout once a response has finished.
|
|
91
|
+
this.server.emit('connection', stream);
|
|
92
|
+
this.armChannelTimeout(stream);
|
|
40
93
|
}
|
|
41
94
|
retryRequest(logRequest) {
|
|
42
95
|
const address = this.server?.address();
|
|
@@ -8,24 +8,77 @@ const http2_1 = __importDefault(require("http2"));
|
|
|
8
8
|
const logger_js_1 = __importDefault(require("../../logger.js"));
|
|
9
9
|
const uuid_1 = require("uuid");
|
|
10
10
|
const texts_1 = require("../../texts");
|
|
11
|
+
const utils_1 = require("../../utils");
|
|
12
|
+
const logThrottle_1 = __importDefault(require("../../logThrottle"));
|
|
11
13
|
const tunnel_1 = require("../../types/tunnel");
|
|
14
|
+
// The only throttled kind on this server, so the map LogThrottle keeps holds one entry. Named
|
|
15
|
+
// rather than inlined because the string IS the key: the same one has to reach hit() and read
|
|
16
|
+
// sensibly in the tail line the sweep emits.
|
|
17
|
+
const SHED_KIND = 'session cap';
|
|
12
18
|
class ServerHttp2 extends events_1.default {
|
|
13
19
|
server;
|
|
14
20
|
host;
|
|
21
|
+
sessions = 0;
|
|
22
|
+
shedLog;
|
|
15
23
|
constructor(host) {
|
|
16
24
|
super();
|
|
17
25
|
this.host = host;
|
|
26
|
+
// The onFlush half reports the tail of a flood: what the throttle swallowed after its last line
|
|
27
|
+
// out, once the shedding has stopped. Floods END, and hit() only ever hands its count to the
|
|
28
|
+
// NEXT shed - so without this, 50k channels refused in the half-minute after a report would be
|
|
29
|
+
// represented by one line saying nothing, which reads as "the cap was brushed once". The
|
|
30
|
+
// throttle owns the sweep timer and unrefs it, and stop() below shuts it down so a tunnel
|
|
31
|
+
// restart leaves nothing behind.
|
|
32
|
+
this.shedLog = new logThrottle_1.default(utils_1.TUNNEL_HTTP2_SHED_LOG_INTERVAL, (_kind, suppressed) => logger_js_1.default.info((0, texts_1.LOG_HTTP2_SESSION_SHED_TAIL)(suppressed)));
|
|
18
33
|
this.server = http2_1.default.createServer((req, res) => this.processRequest(req, res));
|
|
19
34
|
this.server.on('session', (session) => {
|
|
20
35
|
session.id = (0, uuid_1.v4)();
|
|
36
|
+
this.sessions += 1;
|
|
37
|
+
// Streams in flight on THIS session. Http2Session runs its own frame-activity timer, which
|
|
38
|
+
// works even though the underlying "socket" is an ssh2 channel with no setTimeout of its own -
|
|
39
|
+
// but frame activity is not the same as being busy. A SILENT in-flight stream (SSE with long
|
|
40
|
+
// gaps, long-poll, an origin that has not sent headers yet) produces no frames, and nothing
|
|
41
|
+
// else refreshes that clock either: a PING does not, in either direction. So "idle" has to
|
|
42
|
+
// mean this counter, not the timer.
|
|
43
|
+
let active = 0;
|
|
44
|
+
session.on('stream', (stream) => {
|
|
45
|
+
active += 1;
|
|
46
|
+
stream.once('close', () => {
|
|
47
|
+
active -= 1;
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
// Idle reaping. on('timeout') plus a callback-less setTimeout, NOT setTimeout(ms, callback):
|
|
51
|
+
// node registers that callback with once(), so the first firing consumes it and the re-arm
|
|
52
|
+
// below would be silent from then on.
|
|
53
|
+
session.setTimeout(utils_1.TUNNEL_HTTP2_SESSION_IDLE_TIMEOUT);
|
|
54
|
+
session.on('timeout', () => {
|
|
55
|
+
// Busy: re-arm and leave it alone. close() would send GOAWAY, and a worker old enough to
|
|
56
|
+
// predate the graceful-GOAWAY branch in its pipe.js destroys the whole session on one -
|
|
57
|
+
// taking the live request with it. Re-arming is not optional, because node does not re-arm a
|
|
58
|
+
// session timer after it fires, only on the next frame; a session that finishes its request
|
|
59
|
+
// in silence would otherwise never be reaped.
|
|
60
|
+
if (active > 0) {
|
|
61
|
+
session.setTimeout(utils_1.TUNNEL_HTTP2_SESSION_IDLE_TIMEOUT);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
logger_js_1.default.debug(texts_1.LOG_HTTP2_SESSION_TIMEOUT);
|
|
65
|
+
try {
|
|
66
|
+
session.close();
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
// do nothing
|
|
70
|
+
}
|
|
71
|
+
});
|
|
21
72
|
this.emit(tunnel_1.TUNNEL_EVENT.HTTP_SESSION_OPEN, session);
|
|
22
73
|
session.once('close', () => {
|
|
74
|
+
this.sessions -= 1;
|
|
23
75
|
this.emit(tunnel_1.TUNNEL_EVENT.HTTP_SESSION_CLOSED, session);
|
|
24
76
|
});
|
|
25
77
|
});
|
|
26
78
|
this.server.listen();
|
|
27
79
|
}
|
|
28
80
|
stop() {
|
|
81
|
+
this.shedLog.stop();
|
|
29
82
|
if (this.server) {
|
|
30
83
|
this.server.close();
|
|
31
84
|
this.server.removeAllListeners();
|
|
@@ -33,10 +86,44 @@ class ServerHttp2 extends events_1.default {
|
|
|
33
86
|
this.server = null;
|
|
34
87
|
}
|
|
35
88
|
handleSshTunnel(stream, info, ip) {
|
|
89
|
+
// No server left (stop() ran): destroy. Nothing downstream will ever read this channel, so
|
|
90
|
+
// leaving it open holds an SSH channel on the worker until the worker itself notices - the gap
|
|
91
|
+
// ServerHttp1.handleSshTunnel closes the same way. Ahead of the cap check on purpose: that
|
|
92
|
+
// branch's debug line would otherwise report a session limit for a channel that is simply late.
|
|
93
|
+
if (!this.server) {
|
|
94
|
+
try {
|
|
95
|
+
stream.destroy();
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// do nothing
|
|
99
|
+
}
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
// Session cap, checked before an Http2Session even exists - destroying the channel here is
|
|
103
|
+
// the cheapest possible shed. inFlight (tunnel.ts) cannot protect against this: it counts
|
|
104
|
+
// requests, while a spread-out flood parks thousands of near-idle sessions (~2-3 requests
|
|
105
|
+
// each) whose per-session state is what actually exhausts the agent.
|
|
106
|
+
if (this.sessions >= utils_1.TUNNEL_HTTP2_MAX_SESSIONS) {
|
|
107
|
+
// info, not debug: this shed answers the client with nothing at all - the channel is simply
|
|
108
|
+
// destroyed - so unlike httpShed's 503 there is no trace of it anywhere else, and a flood is
|
|
109
|
+
// over long before anyone can re-run with DEBUG=1. Throttled because the cap engages per
|
|
110
|
+
// channel: a line each would run the 5MB log rotation and discard the very evidence it is
|
|
111
|
+
// there to leave. The line that does get out carries its own multiplier, which is what
|
|
112
|
+
// separates one client tripping the cap from the cap being pinned for an hour.
|
|
113
|
+
const suppressed = this.shedLog.hit(SHED_KIND);
|
|
114
|
+
if (suppressed >= 0)
|
|
115
|
+
logger_js_1.default.info((0, texts_1.LOG_HTTP2_SESSION_SHED)(ip, suppressed));
|
|
116
|
+
try {
|
|
117
|
+
stream.destroy();
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// do nothing
|
|
121
|
+
}
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
36
124
|
logger_js_1.default.debug((0, texts_1.LOG_HTTP2_CONNECTION)(ip));
|
|
37
125
|
stream.remoteAddress = ip;
|
|
38
|
-
|
|
39
|
-
this.server.emit('connection', stream);
|
|
126
|
+
this.server.emit('connection', stream);
|
|
40
127
|
}
|
|
41
128
|
retryRequest(logRequest) {
|
|
42
129
|
const address = this.server?.address();
|
|
@@ -52,6 +52,9 @@ class SshClient extends events_1.default {
|
|
|
52
52
|
kex: ['ecdh-sha2-nistp256'],
|
|
53
53
|
},
|
|
54
54
|
keepaliveInterval: 10000,
|
|
55
|
+
// Capability advertisement, read by the worker off info.header at connection time. An
|
|
56
|
+
// old worker simply ignores what a client calls itself, so this is safe to send always.
|
|
57
|
+
ident: (0, utils_1.getSshIdent)(),
|
|
55
58
|
host: this.ip,
|
|
56
59
|
port: this.port,
|
|
57
60
|
username: this.username,
|
|
@@ -164,6 +167,17 @@ class SshClient extends events_1.default {
|
|
|
164
167
|
triggerStream(tunnel_1.TUNNEL_SSH_EVENT.STREAM_HTTP2, ip);
|
|
165
168
|
return;
|
|
166
169
|
}
|
|
170
|
+
if (type === tunnel_1.TUNNEL_SOCKET_TYPE.HTTP2_SHARED) {
|
|
171
|
+
logger_1.default.debug((0, texts_1.LOG_DETECTED_STREAM)('HTTP2_SHARED'));
|
|
172
|
+
// Same h2 path as above - only where the client address comes from differs, and that is
|
|
173
|
+
// decided by this flag rather than by the header being present. A worker too old to strip a
|
|
174
|
+
// client-sent TUNNEL_CLIENT_IP_HEADER never opens this type, so its traffic can never reach
|
|
175
|
+
// the branch that trusts the header. The handshake IP is a placeholder here; requestIp()
|
|
176
|
+
// reads the per-request header instead.
|
|
177
|
+
stream.sharedIp = true;
|
|
178
|
+
triggerStream(tunnel_1.TUNNEL_SSH_EVENT.STREAM_HTTP2, ip);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
167
181
|
if (type === tunnel_1.TUNNEL_SOCKET_TYPE.TCP) {
|
|
168
182
|
logger_1.default.debug((0, texts_1.LOG_DETECTED_STREAM)('TCP'));
|
|
169
183
|
triggerStream(tunnel_1.TUNNEL_SSH_EVENT.STREAM_TCP, ip);
|
|
@@ -113,6 +113,12 @@ var TUNNEL_SOCKET_TYPE;
|
|
|
113
113
|
TUNNEL_SOCKET_TYPE[TUNNEL_SOCKET_TYPE["HTTP1"] = 2] = "HTTP1";
|
|
114
114
|
TUNNEL_SOCKET_TYPE[TUNNEL_SOCKET_TYPE["HTTP2"] = 3] = "HTTP2";
|
|
115
115
|
TUNNEL_SOCKET_TYPE[TUNNEL_SOCKET_TYPE["SSH"] = 4] = "SSH";
|
|
116
|
+
// Same channel as HTTP2, except the handshake's IP field is a placeholder and the real client
|
|
117
|
+
// address arrives per request in TUNNEL_CLIENT_IP_HEADER. That is what lets one channel serve
|
|
118
|
+
// many client IPs, so the worker no longer needs a session per source address. Sent only to an
|
|
119
|
+
// agent that advertised the capability in its SSH ident - types 0-4 keep working forever, since
|
|
120
|
+
// old workers will be opening them for a long time.
|
|
121
|
+
TUNNEL_SOCKET_TYPE[TUNNEL_SOCKET_TYPE["HTTP2_SHARED"] = 5] = "HTTP2_SHARED";
|
|
116
122
|
})(TUNNEL_SOCKET_TYPE || (exports.TUNNEL_SOCKET_TYPE = TUNNEL_SOCKET_TYPE = {}));
|
|
117
123
|
var TUNNEL_REGION;
|
|
118
124
|
(function (TUNNEL_REGION) {
|
package/distTs/src/utils.js
CHANGED
|
@@ -36,8 +36,8 @@ 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.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.sleep = exports.getLatestVersion = exports.getVersionEnv = exports.getCurrentVersionWithoutEnv = exports.getVersionWithoutEnv = 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 = void 0;
|
|
39
|
+
exports.isStringRegExp = exports.getWorkingDir = exports.getRootDir = exports.TARGET_ONLY_PORT_REGEX = 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.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_H2 = exports.TUNNEL_CLIENT_IP_HEADER = exports.TUNNEL_HTTP2_SHED_LOG_INTERVAL = exports.TUNNEL_HTTP2_MAX_SESSIONS = 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.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.sleep = exports.getLatestVersion = exports.getVersionEnv = exports.getCurrentVersionWithoutEnv = exports.getVersionWithoutEnv = 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.newCommand = exports.formatBytes = exports.formatHelp = exports.getPlatform = exports.getHostname = void 0;
|
|
41
41
|
exports.apiErrorCodeToClass = apiErrorCodeToClass;
|
|
42
42
|
exports.isFile = isFile;
|
|
43
43
|
exports.getAppWorkspaceUrl = getAppWorkspaceUrl;
|
|
@@ -78,6 +78,35 @@ exports.TUNNEL_HTTP_CB_WINDOW = 10000;
|
|
|
78
78
|
exports.TUNNEL_HTTP_CB_MIN_REQUESTS = 20;
|
|
79
79
|
exports.TUNNEL_HTTP_MAX_INFLIGHT = 2000;
|
|
80
80
|
exports.TUNNEL_HTTP_RETRY_AFTER = 30;
|
|
81
|
+
// Flood hardening for the agent-side h2 server. The worker bounds its side of the session pool
|
|
82
|
+
// too (worker/src/pipe.js, PIPE_HTTP2_SESSION_IDLE_TIMEOUT / PIPE_HTTP2_MAX_SESSIONS_*); these
|
|
83
|
+
// are the agent's own backstop for workers that don't - an old worker keeps idle sessions for
|
|
84
|
+
// 10 minutes, and a spread-out flood then parks tens of thousands of sessions on the agent.
|
|
85
|
+
// Idle timeout sits above the worker's 60s so a healthy worker closes its side first and this
|
|
86
|
+
// timer only fires against a worker that never reaps.
|
|
87
|
+
exports.TUNNEL_HTTP2_SESSION_IDLE_TIMEOUT = 75000;
|
|
88
|
+
// Above the worker's global cap (2000): the worker sheds first, this only catches what slips
|
|
89
|
+
// through (multiple workers, old workers, caps overshoot under a burst).
|
|
90
|
+
exports.TUNNEL_HTTP2_MAX_SESSIONS = 4000;
|
|
91
|
+
// How often the shed above may report. The cap engages once per channel under a flood, which is
|
|
92
|
+
// exactly when the agent cannot afford a line per channel: the log rotates at 5MB
|
|
93
|
+
// (logger.checkLogSize), so an unthrottled stream would discard the evidence of the flood it is
|
|
94
|
+
// recording. Mirrors PIPE_HTTP2_ADMISSION_LOG_INTERVAL on the worker side.
|
|
95
|
+
exports.TUNNEL_HTTP2_SHED_LOG_INTERVAL = 60000;
|
|
96
|
+
// Per-request client IP on a shared h2 channel (handshake type HTTP2_SHARED). Trusted ONLY on a
|
|
97
|
+
// channel the worker opened as shared: on any other channel the address still comes from the
|
|
98
|
+
// handshake, so an old worker - which does not strip a client-sent copy of this header - cannot be
|
|
99
|
+
// talked into reporting an attacker-chosen address. Always removed before the request reaches the
|
|
100
|
+
// user's target (getClearedHeaders).
|
|
101
|
+
exports.TUNNEL_CLIENT_IP_HEADER = 'x-bdy-client-ip';
|
|
102
|
+
// SSH identification suffix announcing that this agent understands the shared-h2 handshake. The
|
|
103
|
+
// worker reads it off the client ident at connection time (out-of-band on purpose: an agent that
|
|
104
|
+
// does not know a handshake type destroys the channel, so the worker has to know BEFORE it opens
|
|
105
|
+
// one). Per SSH connection, so an updated agent gets the new mode on its next reconnect rather
|
|
106
|
+
// than when its tunnel record is recreated. RFC 4253: printable ASCII, no spaces, no minus.
|
|
107
|
+
exports.TUNNEL_SSH_IDENT_SHARED_H2 = 'hip1';
|
|
108
|
+
const getSshIdent = () => `bdy_${(0, exports.getVersionWithoutEnv)((0, exports.getVersion)())}_${exports.TUNNEL_SSH_IDENT_SHARED_H2}`;
|
|
109
|
+
exports.getSshIdent = getSshIdent;
|
|
81
110
|
exports.DEFAULT_TIMEOUT = 30;
|
|
82
111
|
exports.SSH_HANDSHAKE_TIMEOUT = 10000;
|
|
83
112
|
exports.AGENT_FETCH_RETRY_MIN = 3000;
|