Compare commits
15 Commits
typescript
...
e6a6327b08
| Author | SHA1 | Date | |
|---|---|---|---|
| e6a6327b08 | |||
| 5f0fce2c33 | |||
| 97cb5078e2 | |||
| f2e56c99aa | |||
| 9741568f12 | |||
| fa04b7e9da | |||
| 470f510701 | |||
| da83e18aa2 | |||
| 09d26efa0d | |||
| c2f3454a38 | |||
| ed9002f436 | |||
| 7d8a85f01e | |||
| 31d7cab487 | |||
| b691020074 | |||
| b8a11e779c |
200
package-lock.json
generated
200
package-lock.json
generated
@@ -1,22 +1,36 @@
|
||||
{
|
||||
"name": "tryton-rpc-client",
|
||||
"name": "tryton-rpc-client-js",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "tryton-rpc-client",
|
||||
"name": "tryton-rpc-client-js",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.0.0",
|
||||
"@types/node": "^20.19.21",
|
||||
"rimraf": "^5.0.0",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@cspotcode/source-map-support": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
||||
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/trace-mapping": "0.3.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui": {
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
||||
@@ -35,6 +49,34 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/resolve-uri": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
||||
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
||||
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
||||
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.0.3",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@pkgjs/parseargs": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
||||
@@ -46,16 +88,70 @@
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@tsconfig/node10": {
|
||||
"version": "1.0.12",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz",
|
||||
"integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tsconfig/node12": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
|
||||
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tsconfig/node14": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
||||
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@tsconfig/node16": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
|
||||
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.19.20",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.20.tgz",
|
||||
"integrity": "sha512-2Q7WS25j4pS1cS8yw3d6buNCVJukOTeQ39bAnwR6sOJbaxvyCGebzTMypDFN82CxBLnl+lSWVdCCWbRY6y9yZQ==",
|
||||
"version": "20.19.21",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.21.tgz",
|
||||
"integrity": "sha512-CsGG2P3I5y48RPMfprQGfy4JPRZ6csfC3ltBZSRItG3ngggmNY/qs2uZKp4p9VbrpqNNSMzUZNFZKzgOGnd/VA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.16.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
|
||||
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/acorn-walk": {
|
||||
"version": "8.3.5",
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz",
|
||||
"integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"acorn": "^8.11.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
|
||||
@@ -82,6 +178,13 @@
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/arg": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
@@ -119,6 +222,13 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/create-require": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
@@ -134,6 +244,16 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/diff": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz",
|
||||
"integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/eastasianwidth": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
|
||||
@@ -226,6 +346,13 @@
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/make-error": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||
@@ -442,6 +569,50 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-node": {
|
||||
"version": "10.9.2",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
|
||||
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@cspotcode/source-map-support": "^0.8.0",
|
||||
"@tsconfig/node10": "^1.0.7",
|
||||
"@tsconfig/node12": "^1.0.7",
|
||||
"@tsconfig/node14": "^1.0.0",
|
||||
"@tsconfig/node16": "^1.0.2",
|
||||
"acorn": "^8.4.1",
|
||||
"acorn-walk": "^8.1.1",
|
||||
"arg": "^4.1.0",
|
||||
"create-require": "^1.1.0",
|
||||
"diff": "^4.0.1",
|
||||
"make-error": "^1.1.1",
|
||||
"v8-compile-cache-lib": "^3.0.1",
|
||||
"yn": "3.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"ts-node": "dist/bin.js",
|
||||
"ts-node-cwd": "dist/bin-cwd.js",
|
||||
"ts-node-esm": "dist/bin-esm.js",
|
||||
"ts-node-script": "dist/bin-script.js",
|
||||
"ts-node-transpile-only": "dist/bin-transpile.js",
|
||||
"ts-script": "dist/bin-script-deprecated.js"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@swc/core": ">=1.2.50",
|
||||
"@swc/wasm": ">=1.2.50",
|
||||
"@types/node": "*",
|
||||
"typescript": ">=2.7"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@swc/core": {
|
||||
"optional": true
|
||||
},
|
||||
"@swc/wasm": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||
@@ -463,6 +634,13 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/v8-compile-cache-lib": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
@@ -576,6 +754,16 @@
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/yn": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,11 +34,11 @@
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.0.0",
|
||||
"typescript": "^5.0.0",
|
||||
"rimraf": "^5.0.0"
|
||||
"@types/node": "^20.19.21",
|
||||
"rimraf": "^5.0.0",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.0.0"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
|
||||
@@ -181,7 +181,6 @@ export class TrytonCache {
|
||||
throw new Error("Key expired");
|
||||
}
|
||||
|
||||
console.log(`(cached) ${prefix} ${key}`);
|
||||
return this._deepCopy(entry.value);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,9 @@ export class TrytonClient {
|
||||
|
||||
/**
|
||||
* Create a new Tryton client
|
||||
* @param config Configuration object
|
||||
* @param config.hostname - Hostname or IP address. Can include port (e.g., "46.62.242.210:8090")
|
||||
* @param config.port - Port number (ignored if hostname includes port)
|
||||
*/
|
||||
constructor(config: TrytonClientConfig) {
|
||||
const {
|
||||
@@ -69,10 +72,20 @@ export class TrytonClient {
|
||||
this.useHttps = port === 443 || port === 8443;
|
||||
}
|
||||
|
||||
// Handle IP:Port format (e.g., "46.62.242.210:8090")
|
||||
if (this.hostname.includes(":") && !this.hostname.startsWith("http")) {
|
||||
const [ip, hostPort] = this.hostname.split(":");
|
||||
this.hostname = ip;
|
||||
this.port = parseInt(hostPort, 10);
|
||||
// Determine https based on extracted port
|
||||
this.useHttps = this.port === 443 || this.port === 8443;
|
||||
} else {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
this.database = database;
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.port = port;
|
||||
this.password = password || ""; // Empty string if not provided
|
||||
this.language = language;
|
||||
this.options = options;
|
||||
this.connection = null;
|
||||
@@ -81,6 +94,7 @@ export class TrytonClient {
|
||||
|
||||
/**
|
||||
* Alternative constructor for backward compatibility
|
||||
* Note: If hostname includes port (IP:Port), the port parameter will be ignored
|
||||
*/
|
||||
static create(
|
||||
hostname: string,
|
||||
@@ -158,6 +172,28 @@ export class TrytonClient {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup connection pool without authentication
|
||||
* Used when restoring an existing session
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async setupConnection(): Promise<void> {
|
||||
this.connection = new ServerPool(
|
||||
this.hostname,
|
||||
this.port,
|
||||
this.database,
|
||||
{
|
||||
session: undefined, // Session will be set by restoreSession()
|
||||
cache: this.options.cache !== false ? [] : null,
|
||||
verbose: this.options.verbose || false,
|
||||
connectTimeout: this.options.connectTimeout || CONNECT_TIMEOUT,
|
||||
timeout: this.options.timeout || DEFAULT_TIMEOUT,
|
||||
keepMax: this.options.keepMax || 4,
|
||||
useHttps: this.useHttps,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call RPC method on server
|
||||
* @param {string} methodName - RPC method name (e.g., 'model.party.party.read')
|
||||
@@ -521,21 +557,30 @@ export class TrytonClient {
|
||||
// Establecer la sesión sin hacer login
|
||||
this.session = sessionToken;
|
||||
|
||||
// Verificar que la sesión sigue siendo válida
|
||||
const proxy = this.connection?.getConnection();
|
||||
if (!proxy) {
|
||||
throw new Error("No connection available");
|
||||
// Actualizar la sesión en el connection pool ANTES de obtener proxy
|
||||
if (this.connection) {
|
||||
this.connection.setSession(sessionToken);
|
||||
} else {
|
||||
throw new Error("No connection pool available");
|
||||
}
|
||||
|
||||
// Obtener proxy (ahora con la sesión ya actualizada)
|
||||
const proxy = this.connection.getConnection();
|
||||
|
||||
// Test de validación de sesión
|
||||
try {
|
||||
await proxy.request("common.version", []);
|
||||
console.log("✅ Sesión restaurada exitosamente");
|
||||
// Usar un método que requiere autenticación para validar la sesión
|
||||
await proxy.request("model.res.user.get_preferences", [
|
||||
true,
|
||||
{},
|
||||
]);
|
||||
this.connection.putConnection(proxy); // Devolver conexión al pool
|
||||
return true;
|
||||
} catch (error) {
|
||||
// Sesión inválida o expirada
|
||||
console.error("❌ Error en validación:", error);
|
||||
this.session = null;
|
||||
console.log("❌ Sesión inválida o expirada");
|
||||
this.connection.putConnection(proxy); // Devolver conexión al pool
|
||||
return false;
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
107
src/jsonrpc.ts
107
src/jsonrpc.ts
@@ -169,13 +169,15 @@ export class TrytonJSONEncoder {
|
||||
case "datetime": {
|
||||
const dt = specialValue as TrytonDateTime;
|
||||
return new Date(
|
||||
dt.year,
|
||||
dt.month - 1,
|
||||
dt.day,
|
||||
dt.hour || 0,
|
||||
dt.minute || 0,
|
||||
dt.second || 0,
|
||||
Math.floor((dt.microsecond || 0) / 1000)
|
||||
Date.UTC(
|
||||
dt.year,
|
||||
dt.month - 1,
|
||||
dt.day,
|
||||
dt.hour || 0,
|
||||
dt.minute || 0,
|
||||
dt.second || 0,
|
||||
Math.floor((dt.microsecond || 0) / 1000)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -239,6 +241,7 @@ interface TransportOptions {
|
||||
connectTimeout?: number | undefined;
|
||||
timeout?: number | undefined;
|
||||
useHttps?: boolean;
|
||||
followRedirects?: boolean;
|
||||
}
|
||||
|
||||
interface JsonRpcRequest {
|
||||
@@ -265,6 +268,8 @@ export class Transport {
|
||||
private connectTimeout: number;
|
||||
private timeout: number;
|
||||
private useHttps: boolean;
|
||||
private followRedirects: boolean;
|
||||
private redirectCount: number;
|
||||
|
||||
constructor(options: TransportOptions = {}) {
|
||||
this.fingerprints = options.fingerprints || null;
|
||||
@@ -274,6 +279,8 @@ export class Transport {
|
||||
this.connectTimeout = options.connectTimeout || CONNECT_TIMEOUT;
|
||||
this.timeout = options.timeout || DEFAULT_TIMEOUT;
|
||||
this.useHttps = options.useHttps || false;
|
||||
this.followRedirects = options.followRedirects ?? true;
|
||||
this.redirectCount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -289,6 +296,21 @@ export class Transport {
|
||||
handler: string,
|
||||
requestData: string,
|
||||
verbose: boolean = false
|
||||
): Promise<JsonRpcResponse> {
|
||||
// Reset redirect count for each new request
|
||||
this.redirectCount = 0;
|
||||
return this.doRequest(host, handler, requestData, verbose);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to make HTTP request with redirect support
|
||||
*/
|
||||
private async doRequest(
|
||||
host: string,
|
||||
handler: string,
|
||||
requestData: string,
|
||||
verbose: boolean = false,
|
||||
forceHttps?: boolean
|
||||
): Promise<JsonRpcResponse> {
|
||||
// Detect protocol based on port or explicit protocol
|
||||
const hostParts = host.split(":");
|
||||
@@ -297,6 +319,7 @@ export class Transport {
|
||||
|
||||
// Use HTTPS if explicitly configured, or for standard HTTPS ports
|
||||
const shouldUseHttps =
|
||||
forceHttps === true ||
|
||||
this.useHttps ||
|
||||
port === 443 ||
|
||||
port === 8443 ||
|
||||
@@ -362,6 +385,49 @@ export class Transport {
|
||||
|
||||
res.on("end", () => {
|
||||
try {
|
||||
// Handle redirects BEFORE parsing response body
|
||||
const statusCode = res.statusCode;
|
||||
if (
|
||||
this.followRedirects &&
|
||||
statusCode &&
|
||||
this.redirectCount < 3 &&
|
||||
[301, 302, 307, 308].includes(statusCode)
|
||||
) {
|
||||
const location = res.headers["location"];
|
||||
if (location) {
|
||||
this.redirectCount++;
|
||||
if (verbose) {
|
||||
console.log(
|
||||
`🔄 Redirect (${statusCode}): ${host}${handler} → ${location}`
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const redirectUrl = new URL(
|
||||
location,
|
||||
`http://${host}`
|
||||
);
|
||||
const newHost = redirectUrl.host;
|
||||
const newUseHttps =
|
||||
redirectUrl.protocol === "https:";
|
||||
|
||||
this.doRequest(
|
||||
newHost,
|
||||
handler,
|
||||
requestData,
|
||||
verbose,
|
||||
newUseHttps
|
||||
)
|
||||
.then(resolve)
|
||||
.catch(reject);
|
||||
return;
|
||||
} catch (redirectError) {
|
||||
reject(redirectError);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle compression
|
||||
const encoding = res.headers["content-encoding"];
|
||||
let responseText: string;
|
||||
@@ -378,9 +444,9 @@ export class Transport {
|
||||
responseText = data.toString("utf-8");
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
console.log("Response:", responseText);
|
||||
}
|
||||
// if (verbose) {
|
||||
// console.log("Response:", responseText);
|
||||
// }
|
||||
|
||||
const response = TrytonJSONEncoder.deserialize(
|
||||
responseText
|
||||
@@ -646,6 +712,27 @@ export class ServerPool {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update session for all connections
|
||||
* @param {string} session - New session string
|
||||
*/
|
||||
setSession(session: string): void {
|
||||
this.session = session;
|
||||
this.options.session = session;
|
||||
|
||||
// Update session for all existing connections and their transports
|
||||
for (const conn of this.pool) {
|
||||
if ((conn as any).transport) {
|
||||
(conn as any).transport.session = session;
|
||||
}
|
||||
}
|
||||
for (const conn of this.used) {
|
||||
if ((conn as any).transport) {
|
||||
(conn as any).transport.session = session;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get connection from pool or create new one
|
||||
* @returns {ServerProxy} - Server proxy instance
|
||||
|
||||
Reference in New Issue
Block a user