@litert/televoke 0.4.5 → 0.4.6
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/CHANGES.md +7 -0
- package/lib/Client/Common.d.ts +1 -1
- package/lib/Client/Common.d.ts.map +1 -1
- package/lib/Client/HttpClient.d.ts.map +1 -1
- package/lib/Client/HttpClient.js +17 -9
- package/lib/Client/HttpClient.js.map +1 -1
- package/lib/Client/HttpsClient.d.ts.map +1 -1
- package/lib/Client/HttpsClient.js +17 -9
- package/lib/Client/HttpsClient.js.map +1 -1
- package/lib/Client/TCPClient.d.ts +5 -0
- package/lib/Client/TCPClient.d.ts.map +1 -1
- package/lib/Client/TCPClient.js +8 -4
- package/lib/Client/TCPClient.js.map +1 -1
- package/lib/Client/TLSClient.d.ts.map +1 -1
- package/lib/Client/TLSClient.js +3 -4
- package/lib/Client/TLSClient.js.map +1 -1
- package/lib/Client/index.js +5 -1
- package/lib/Client/index.js.map +1 -1
- package/lib/Common/API.d.ts +1 -1
- package/lib/Common/API.d.ts.map +1 -1
- package/lib/Common/Request.d.ts +1 -1
- package/lib/Common/Request.d.ts.map +1 -1
- package/lib/Common/Response.js +1 -1
- package/lib/Common/Response.js.map +1 -1
- package/lib/Common/index.js +5 -1
- package/lib/Common/index.js.map +1 -1
- package/lib/Encoder/Decoder.d.ts.map +1 -1
- package/lib/Encoder/Decoder.js +23 -13
- package/lib/Encoder/Decoder.js.map +1 -1
- package/lib/Encoder/Encoder.d.ts.map +1 -1
- package/lib/Encoder/Encoder.js +4 -4
- package/lib/Encoder/Encoder.js.map +1 -1
- package/lib/Server/Common/Gateway.d.ts +3 -1
- package/lib/Server/Common/Gateway.d.ts.map +1 -1
- package/lib/Server/Common/Request.d.ts +1 -1
- package/lib/Server/Common/Request.d.ts.map +1 -1
- package/lib/Server/Common/Router.d.ts +2 -2
- package/lib/Server/Common/Router.d.ts.map +1 -1
- package/lib/Server/Common/Server.d.ts +6 -0
- package/lib/Server/Common/Server.d.ts.map +1 -1
- package/lib/Server/Common/index.js +5 -1
- package/lib/Server/Common/index.js.map +1 -1
- package/lib/Server/Errors.d.ts +1 -0
- package/lib/Server/Errors.d.ts.map +1 -1
- package/lib/Server/Errors.js +7 -1
- package/lib/Server/Errors.js.map +1 -1
- package/lib/Server/Gateways/Http.d.ts.map +1 -1
- package/lib/Server/Gateways/Http.js +26 -11
- package/lib/Server/Gateways/Http.js.map +1 -1
- package/lib/Server/Gateways/TCP.d.ts +5 -0
- package/lib/Server/Gateways/TCP.d.ts.map +1 -1
- package/lib/Server/Gateways/TCP.js +15 -7
- package/lib/Server/Gateways/TCP.js.map +1 -1
- package/lib/Server/Server.d.ts.map +1 -1
- package/lib/Server/Server.js +30 -16
- package/lib/Server/Server.js.map +1 -1
- package/lib/Server/index.js +5 -1
- package/lib/Server/index.js.map +1 -1
- package/lib/index.js +5 -1
- package/lib/index.js.map +1 -1
- package/package.json +7 -9
- package/src/lib/Client/Common.ts +2 -1
- package/src/lib/Client/HttpClient.ts +19 -16
- package/src/lib/Client/HttpsClient.ts +19 -16
- package/src/lib/Client/TCPClient.ts +16 -12
- package/src/lib/Client/TLSClient.ts +12 -13
- package/src/lib/Common/Request.ts +1 -1
- package/src/lib/Encoder/Decoder.ts +28 -13
- package/src/lib/Encoder/Encoder.ts +4 -5
- package/src/lib/Server/Common/Gateway.ts +4 -0
- package/src/lib/Server/Common/Request.ts +1 -1
- package/src/lib/Server/Common/Router.ts +7 -2
- package/src/lib/Server/Common/Server.ts +7 -0
- package/src/lib/Server/Errors.ts +7 -0
- package/src/lib/Server/Gateways/Http.ts +34 -12
- package/src/lib/Server/Gateways/TCP.ts +16 -7
- package/src/lib/Server/Server.ts +38 -16
- package/src/lib/Server/SimpleRouter.ts +1 -1
|
@@ -23,17 +23,17 @@ import { Events } from '@litert/observable';
|
|
|
23
23
|
|
|
24
24
|
class HttpClient extends Events.EventEmitter<Events.ICallbackDefinitions> implements C.IClient {
|
|
25
25
|
|
|
26
|
-
private _agent: $Http.Agent;
|
|
26
|
+
private readonly _agent: $Http.Agent;
|
|
27
27
|
|
|
28
28
|
public onError!: any;
|
|
29
29
|
|
|
30
30
|
public constructor(
|
|
31
|
-
private _host: string,
|
|
32
|
-
private _port: number,
|
|
33
|
-
private _ridGenerator: C.IRIDGenerator,
|
|
34
|
-
private _path: string = '/',
|
|
35
|
-
private _timeout: number = 30000,
|
|
36
|
-
private _apiNameWrapper?: (name: string) => string
|
|
31
|
+
private readonly _host: string,
|
|
32
|
+
private readonly _port: number,
|
|
33
|
+
private readonly _ridGenerator: C.IRIDGenerator,
|
|
34
|
+
private readonly _path: string = '/',
|
|
35
|
+
private readonly _timeout: number = 30000,
|
|
36
|
+
private readonly _apiNameWrapper?: (name: string) => string
|
|
37
37
|
) {
|
|
38
38
|
|
|
39
39
|
super();
|
|
@@ -75,7 +75,7 @@ class HttpClient extends Events.EventEmitter<Events.ICallbackDefinitions> implem
|
|
|
75
75
|
|
|
76
76
|
if (length > G.MAX_PACKET_SIZE) {
|
|
77
77
|
|
|
78
|
-
|
|
78
|
+
reject(new GE.E_PACKET_TOO_LARGE()); return;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
const req = $Http.request({
|
|
@@ -85,21 +85,22 @@ class HttpClient extends Events.EventEmitter<Events.ICallbackDefinitions> implem
|
|
|
85
85
|
agent: this._agent,
|
|
86
86
|
method: 'POST',
|
|
87
87
|
headers: {
|
|
88
|
-
'content-length': Buffer.byteLength(content)
|
|
88
|
+
'content-length': Buffer.byteLength(content),
|
|
89
|
+
'x-tv-ver': 1
|
|
89
90
|
},
|
|
90
91
|
timeout: this._timeout
|
|
91
92
|
}, (resp) => {
|
|
92
93
|
|
|
93
94
|
if (!resp.headers['content-length']) {
|
|
94
95
|
|
|
95
|
-
|
|
96
|
+
reject(new E.E_INVALID_RESPONSE()); return;
|
|
96
97
|
}
|
|
97
98
|
|
|
98
99
|
const length = parseInt(resp.headers['content-length']);
|
|
99
100
|
|
|
100
101
|
if (!Number.isSafeInteger(length) || length > G.MAX_PACKET_SIZE) { // Maximum request packet is 64MB
|
|
101
102
|
|
|
102
|
-
|
|
103
|
+
reject(new GE.E_PACKET_TOO_LARGE()); return;
|
|
103
104
|
}
|
|
104
105
|
|
|
105
106
|
const buf = Buffer.allocUnsafe(length);
|
|
@@ -118,7 +119,7 @@ class HttpClient extends Events.EventEmitter<Events.ICallbackDefinitions> implem
|
|
|
118
119
|
resp.removeAllListeners('data');
|
|
119
120
|
resp.destroy();
|
|
120
121
|
|
|
121
|
-
|
|
122
|
+
reject(new GE.E_INVALID_PACKET()); return;
|
|
122
123
|
}
|
|
123
124
|
|
|
124
125
|
chunk.copy(buf, index);
|
|
@@ -133,7 +134,7 @@ class HttpClient extends Events.EventEmitter<Events.ICallbackDefinitions> implem
|
|
|
133
134
|
}
|
|
134
135
|
catch {
|
|
135
136
|
|
|
136
|
-
|
|
137
|
+
reject(new GE.E_INVALID_PACKET()); return;
|
|
137
138
|
}
|
|
138
139
|
|
|
139
140
|
const data = rawData as C.IResponse<any>;
|
|
@@ -168,9 +169,11 @@ class HttpClient extends Events.EventEmitter<Events.ICallbackDefinitions> implem
|
|
|
168
169
|
});
|
|
169
170
|
});
|
|
170
171
|
|
|
171
|
-
req.once('timeout', () =>
|
|
172
|
-
|
|
173
|
-
|
|
172
|
+
req.once('timeout', () => {
|
|
173
|
+
reject(new E.E_REQUEST_TIMEOUT({
|
|
174
|
+
metadata: { api, requestId: rid, time: Date.now(), details: null }
|
|
175
|
+
}));
|
|
176
|
+
});
|
|
174
177
|
|
|
175
178
|
req.once('error', reject);
|
|
176
179
|
|
|
@@ -23,17 +23,17 @@ import { Events } from '@litert/observable';
|
|
|
23
23
|
|
|
24
24
|
class HttpsClient extends Events.EventEmitter<Events.ICallbackDefinitions> implements C.IClient {
|
|
25
25
|
|
|
26
|
-
private _agent: $Https.Agent;
|
|
26
|
+
private readonly _agent: $Https.Agent;
|
|
27
27
|
|
|
28
28
|
public onError!: any;
|
|
29
29
|
|
|
30
30
|
public constructor(
|
|
31
|
-
private _host: string,
|
|
32
|
-
private _port: number,
|
|
33
|
-
private _ridGenerator: C.IRIDGenerator,
|
|
34
|
-
private _path: string = '',
|
|
35
|
-
private _timeout: number = 30000,
|
|
36
|
-
private _apiNameWrapper?: (name: string) => string,
|
|
31
|
+
private readonly _host: string,
|
|
32
|
+
private readonly _port: number,
|
|
33
|
+
private readonly _ridGenerator: C.IRIDGenerator,
|
|
34
|
+
private readonly _path: string = '',
|
|
35
|
+
private readonly _timeout: number = 30000,
|
|
36
|
+
private readonly _apiNameWrapper?: (name: string) => string,
|
|
37
37
|
tlsAgentOptions?: $Https.AgentOptions
|
|
38
38
|
) {
|
|
39
39
|
|
|
@@ -78,7 +78,7 @@ class HttpsClient extends Events.EventEmitter<Events.ICallbackDefinitions> imple
|
|
|
78
78
|
|
|
79
79
|
if (length > G.MAX_PACKET_SIZE) {
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
reject(new GE.E_PACKET_TOO_LARGE()); return;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
const req = $Https.request({
|
|
@@ -88,21 +88,22 @@ class HttpsClient extends Events.EventEmitter<Events.ICallbackDefinitions> imple
|
|
|
88
88
|
agent: this._agent,
|
|
89
89
|
method: 'POST',
|
|
90
90
|
headers: {
|
|
91
|
-
'content-length': Buffer.byteLength(content)
|
|
91
|
+
'content-length': Buffer.byteLength(content),
|
|
92
|
+
'x-tv-ver': 1
|
|
92
93
|
},
|
|
93
94
|
timeout: this._timeout
|
|
94
95
|
}, (resp) => {
|
|
95
96
|
|
|
96
97
|
if (!resp.headers['content-length']) {
|
|
97
98
|
|
|
98
|
-
|
|
99
|
+
reject(new E.E_INVALID_RESPONSE()); return;
|
|
99
100
|
}
|
|
100
101
|
|
|
101
102
|
const length = parseInt(resp.headers['content-length']);
|
|
102
103
|
|
|
103
104
|
if (!Number.isSafeInteger(length) || length > G.MAX_PACKET_SIZE) { // Maximum request packet is 64MB
|
|
104
105
|
|
|
105
|
-
|
|
106
|
+
reject(new GE.E_PACKET_TOO_LARGE()); return;
|
|
106
107
|
}
|
|
107
108
|
|
|
108
109
|
const buf = Buffer.allocUnsafe(length);
|
|
@@ -121,7 +122,7 @@ class HttpsClient extends Events.EventEmitter<Events.ICallbackDefinitions> imple
|
|
|
121
122
|
resp.removeAllListeners('data');
|
|
122
123
|
resp.destroy();
|
|
123
124
|
|
|
124
|
-
|
|
125
|
+
reject(new GE.E_INVALID_PACKET()); return;
|
|
125
126
|
}
|
|
126
127
|
|
|
127
128
|
chunk.copy(buf, index);
|
|
@@ -136,7 +137,7 @@ class HttpsClient extends Events.EventEmitter<Events.ICallbackDefinitions> imple
|
|
|
136
137
|
}
|
|
137
138
|
catch {
|
|
138
139
|
|
|
139
|
-
|
|
140
|
+
reject(new GE.E_INVALID_PACKET()); return;
|
|
140
141
|
}
|
|
141
142
|
|
|
142
143
|
const data = rawData as C.IResponse<any>;
|
|
@@ -171,9 +172,11 @@ class HttpsClient extends Events.EventEmitter<Events.ICallbackDefinitions> imple
|
|
|
171
172
|
});
|
|
172
173
|
});
|
|
173
174
|
|
|
174
|
-
req.once('timeout', () =>
|
|
175
|
-
|
|
176
|
-
|
|
175
|
+
req.once('timeout', () => {
|
|
176
|
+
reject(new E.E_REQUEST_TIMEOUT({
|
|
177
|
+
metadata: { api, requestId: rid, time: Date.now(), details: null }
|
|
178
|
+
}));
|
|
179
|
+
});
|
|
177
180
|
|
|
178
181
|
req.once('error', reject);
|
|
179
182
|
|
|
@@ -17,11 +17,10 @@
|
|
|
17
17
|
import * as $Net from 'net';
|
|
18
18
|
import * as C from './Common';
|
|
19
19
|
import * as G from '../Common';
|
|
20
|
-
import { Promises } from '@litert/observable';
|
|
20
|
+
import { Promises, Events } from '@litert/observable';
|
|
21
21
|
import * as E from './Errors';
|
|
22
22
|
import { createDecoder } from '../Encoder/Decoder';
|
|
23
23
|
import { createEncoder } from '../Encoder/Encoder';
|
|
24
|
-
import { Events } from '@litert/observable';
|
|
25
24
|
|
|
26
25
|
enum EStatus {
|
|
27
26
|
|
|
@@ -48,7 +47,7 @@ interface IRequest {
|
|
|
48
47
|
|
|
49
48
|
class TCPClient extends Events.EventEmitter<Events.ICallbackDefinitions> implements C.IClient {
|
|
50
49
|
|
|
51
|
-
private static _$promises = Promises.getGlobalFactory();
|
|
50
|
+
private static readonly _$promises = Promises.getGlobalFactory();
|
|
52
51
|
|
|
53
52
|
private static _$clientCounter = 0;
|
|
54
53
|
|
|
@@ -56,11 +55,11 @@ class TCPClient extends Events.EventEmitter<Events.ICallbackDefinitions> impleme
|
|
|
56
55
|
|
|
57
56
|
private _status: EStatus = EStatus.IDLE;
|
|
58
57
|
|
|
59
|
-
private _clientId: number = TCPClient._$clientCounter++;
|
|
58
|
+
private readonly _clientId: number = TCPClient._$clientCounter++;
|
|
60
59
|
|
|
61
|
-
private _connPrId: string;
|
|
60
|
+
private readonly _connPrId: string;
|
|
62
61
|
|
|
63
|
-
private _closePrId: string;
|
|
62
|
+
private readonly _closePrId: string;
|
|
64
63
|
|
|
65
64
|
private _sent: Record<string, IRequest> = {};
|
|
66
65
|
|
|
@@ -70,14 +69,14 @@ class TCPClient extends Events.EventEmitter<Events.ICallbackDefinitions> impleme
|
|
|
70
69
|
|
|
71
70
|
private _sendingQty: number = 0;
|
|
72
71
|
|
|
73
|
-
private _encoder = createEncoder();
|
|
72
|
+
private readonly _encoder = createEncoder();
|
|
74
73
|
|
|
75
74
|
public constructor(
|
|
76
|
-
private _host: string,
|
|
77
|
-
private _port: number,
|
|
78
|
-
private _ridGenerator: C.IRIDGenerator,
|
|
79
|
-
private _timeout: number = 30000,
|
|
80
|
-
private _apiNameWrapper?: (name: string) => string
|
|
75
|
+
private readonly _host: string,
|
|
76
|
+
private readonly _port: number,
|
|
77
|
+
private readonly _ridGenerator: C.IRIDGenerator,
|
|
78
|
+
private readonly _timeout: number = 30000,
|
|
79
|
+
private readonly _apiNameWrapper?: (name: string) => string
|
|
81
80
|
) {
|
|
82
81
|
|
|
83
82
|
super();
|
|
@@ -404,6 +403,11 @@ export interface ITCPClientOptions {
|
|
|
404
403
|
apiNameWrapper?: (name: string) => string;
|
|
405
404
|
}
|
|
406
405
|
|
|
406
|
+
/**
|
|
407
|
+
* Create a client of TCP-base televoke/1 protocol.
|
|
408
|
+
*
|
|
409
|
+
* @deprecated This legacy TCP-based televoke/1 protocol is no longer maintained, and will be removed in v2.0.0
|
|
410
|
+
*/
|
|
407
411
|
export function createTCPClient<TAPIs extends G.IServiceAPIs>(opts: ITCPClientOptions): C.IClient<TAPIs> {
|
|
408
412
|
|
|
409
413
|
return new TCPClient(
|
|
@@ -17,11 +17,10 @@
|
|
|
17
17
|
import * as $TLS from 'tls';
|
|
18
18
|
import * as C from './Common';
|
|
19
19
|
import * as G from '../Common';
|
|
20
|
-
import { Promises } from '@litert/observable';
|
|
20
|
+
import { Promises, Events } from '@litert/observable';
|
|
21
21
|
import * as E from './Errors';
|
|
22
22
|
import { createDecoder } from '../Encoder/Decoder';
|
|
23
23
|
import { createEncoder } from '../Encoder/Encoder';
|
|
24
|
-
import { Events } from '@litert/observable';
|
|
25
24
|
|
|
26
25
|
enum EStatus {
|
|
27
26
|
|
|
@@ -48,7 +47,7 @@ interface IRequest {
|
|
|
48
47
|
|
|
49
48
|
class TLSClient extends Events.EventEmitter<Events.ICallbackDefinitions> implements C.IClient {
|
|
50
49
|
|
|
51
|
-
private static _$promises = Promises.getGlobalFactory();
|
|
50
|
+
private static readonly _$promises = Promises.getGlobalFactory();
|
|
52
51
|
|
|
53
52
|
private static _$clientCounter = 0;
|
|
54
53
|
|
|
@@ -56,11 +55,11 @@ class TLSClient extends Events.EventEmitter<Events.ICallbackDefinitions> impleme
|
|
|
56
55
|
|
|
57
56
|
private _status: EStatus = EStatus.IDLE;
|
|
58
57
|
|
|
59
|
-
private _clientId: number = TLSClient._$clientCounter++;
|
|
58
|
+
private readonly _clientId: number = TLSClient._$clientCounter++;
|
|
60
59
|
|
|
61
|
-
private _connPrId: string;
|
|
60
|
+
private readonly _connPrId: string;
|
|
62
61
|
|
|
63
|
-
private _closePrId: string;
|
|
62
|
+
private readonly _closePrId: string;
|
|
64
63
|
|
|
65
64
|
private _sent: Record<string, IRequest> = {};
|
|
66
65
|
|
|
@@ -70,15 +69,15 @@ class TLSClient extends Events.EventEmitter<Events.ICallbackDefinitions> impleme
|
|
|
70
69
|
|
|
71
70
|
private _sendingQty: number = 0;
|
|
72
71
|
|
|
73
|
-
private _encoder = createEncoder();
|
|
72
|
+
private readonly _encoder = createEncoder();
|
|
74
73
|
|
|
75
74
|
public constructor(
|
|
76
|
-
private _host: string,
|
|
77
|
-
private _port: number,
|
|
78
|
-
private _ridGenerator: C.IRIDGenerator,
|
|
79
|
-
private _timeout: number = 30000,
|
|
80
|
-
private _apiNameWrapper?: (name: string) => string,
|
|
81
|
-
private _tlsOptions?: $TLS.ConnectionOptions
|
|
75
|
+
private readonly _host: string,
|
|
76
|
+
private readonly _port: number,
|
|
77
|
+
private readonly _ridGenerator: C.IRIDGenerator,
|
|
78
|
+
private readonly _timeout: number = 30000,
|
|
79
|
+
private readonly _apiNameWrapper?: (name: string) => string,
|
|
80
|
+
private readonly _tlsOptions?: $TLS.ConnectionOptions
|
|
82
81
|
) {
|
|
83
82
|
|
|
84
83
|
super();
|
|
@@ -37,7 +37,7 @@ class Decoder implements C.IDecoder<any> {
|
|
|
37
37
|
|
|
38
38
|
private _packetLength!: number;
|
|
39
39
|
|
|
40
|
-
private _plBuf: Buffer = Buffer.allocUnsafe(
|
|
40
|
+
private readonly _plBuf: Buffer = Buffer.allocUnsafe(8);
|
|
41
41
|
|
|
42
42
|
private _plBufLength: number = 0;
|
|
43
43
|
|
|
@@ -72,7 +72,7 @@ class Decoder implements C.IDecoder<any> {
|
|
|
72
72
|
|
|
73
73
|
try {
|
|
74
74
|
|
|
75
|
-
data = JSON.parse(chunk.
|
|
75
|
+
data = JSON.parse(chunk.subarray(0, this._packetLength).toString());
|
|
76
76
|
}
|
|
77
77
|
catch (e) {
|
|
78
78
|
|
|
@@ -81,7 +81,7 @@ class Decoder implements C.IDecoder<any> {
|
|
|
81
81
|
return;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
chunk = chunk.
|
|
84
|
+
chunk = chunk.subarray(this._packetLength);
|
|
85
85
|
this.reset();
|
|
86
86
|
|
|
87
87
|
try {
|
|
@@ -98,15 +98,15 @@ class Decoder implements C.IDecoder<any> {
|
|
|
98
98
|
|
|
99
99
|
if (chunk.length + this._bufLength >= this._packetLength) {
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
const restLength = this._packetLength - this._bufLength;
|
|
102
102
|
chunk.copy(this._buf, this._bufLength, 0, this._packetLength - this._bufLength);
|
|
103
|
-
chunk = chunk.
|
|
103
|
+
chunk = chunk.subarray(restLength);
|
|
104
104
|
|
|
105
105
|
let data: any;
|
|
106
106
|
|
|
107
107
|
try {
|
|
108
108
|
|
|
109
|
-
data = JSON.parse(this._buf.
|
|
109
|
+
data = JSON.parse(this._buf.subarray(0, this._packetLength).toString());
|
|
110
110
|
}
|
|
111
111
|
catch (e) {
|
|
112
112
|
|
|
@@ -137,13 +137,21 @@ class Decoder implements C.IDecoder<any> {
|
|
|
137
137
|
|
|
138
138
|
if (this._plBufLength) {
|
|
139
139
|
|
|
140
|
-
if (this._plBufLength + chunk.byteLength >=
|
|
140
|
+
if (this._plBufLength + chunk.byteLength >= 8) {
|
|
141
141
|
|
|
142
|
-
chunk.copy(this._plBuf, this._plBufLength, 0,
|
|
142
|
+
chunk.copy(this._plBuf, this._plBufLength, 0, 8 - this._plBufLength);
|
|
143
|
+
|
|
144
|
+
chunk = chunk.subarray(8 - this._plBufLength);
|
|
145
|
+
|
|
146
|
+
if (this._plBuf.readUInt32LE(0) !== 1) {
|
|
147
|
+
|
|
148
|
+
this.onProtocolError(new GE.E_INVALID_PACKET());
|
|
149
|
+
this.reset();
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
143
152
|
|
|
144
|
-
chunk = chunk.slice(4 - this._plBufLength);
|
|
145
153
|
this._plBufLength = 0;
|
|
146
|
-
this._packetLength = this._plBuf.readUInt32LE(
|
|
154
|
+
this._packetLength = this._plBuf.readUInt32LE(4);
|
|
147
155
|
}
|
|
148
156
|
else {
|
|
149
157
|
|
|
@@ -155,10 +163,17 @@ class Decoder implements C.IDecoder<any> {
|
|
|
155
163
|
}
|
|
156
164
|
else {
|
|
157
165
|
|
|
158
|
-
if (chunk.length >=
|
|
166
|
+
if (chunk.length >= 8) {
|
|
167
|
+
|
|
168
|
+
if (chunk.readUInt32LE(0) !== 1) {
|
|
169
|
+
|
|
170
|
+
this.onProtocolError(new GE.E_INVALID_PACKET());
|
|
171
|
+
this.reset();
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
159
174
|
|
|
160
|
-
this._packetLength = chunk.readUInt32LE(
|
|
161
|
-
chunk = chunk.
|
|
175
|
+
this._packetLength = chunk.readUInt32LE(4);
|
|
176
|
+
chunk = chunk.subarray(8);
|
|
162
177
|
this._plBufLength = 0;
|
|
163
178
|
}
|
|
164
179
|
else {
|
|
@@ -22,16 +22,15 @@ class Encoder implements C.IEncoder {
|
|
|
22
22
|
|
|
23
23
|
content = JSON.stringify(content);
|
|
24
24
|
|
|
25
|
-
const
|
|
25
|
+
const ret = Buffer.allocUnsafe(8);
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
ret.writeUInt32LE(contentLength, 0);
|
|
30
|
-
ret.write(content, 4);
|
|
27
|
+
ret.writeUInt32LE(1, 0);
|
|
28
|
+
ret.writeUInt32LE(Buffer.byteLength(content), 4);
|
|
31
29
|
|
|
32
30
|
if (socket.writable) {
|
|
33
31
|
|
|
34
32
|
socket.write(ret);
|
|
33
|
+
socket.write(content);
|
|
35
34
|
}
|
|
36
35
|
}
|
|
37
36
|
}
|
|
@@ -16,9 +16,14 @@
|
|
|
16
16
|
|
|
17
17
|
import { IRequest } from './Request';
|
|
18
18
|
|
|
19
|
-
export type IHandler<
|
|
19
|
+
export type IHandler<TApi extends (...args: any[]) => any> = (
|
|
20
|
+
...args: Parameters<TApi>
|
|
21
|
+
) => ReturnType<TApi> | Promise<ReturnType<TApi>>;
|
|
20
22
|
|
|
21
|
-
export type IHandlerEx<
|
|
23
|
+
export type IHandlerEx<TApi extends (...args: any[]) => any> = (
|
|
24
|
+
req: IRequest<Parameters<TApi>>,
|
|
25
|
+
...args: Parameters<TApi>
|
|
26
|
+
) => ReturnType<TApi> | Promise<ReturnType<TApi>>;
|
|
22
27
|
|
|
23
28
|
export interface IRouter {
|
|
24
29
|
|
|
@@ -35,6 +35,13 @@ export interface IServer extends Events.IObservable<IServerEvents> {
|
|
|
35
35
|
*/
|
|
36
36
|
addGateway(name: string, gateway: IGateway): this;
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Get a mounted gateway by name.
|
|
40
|
+
*
|
|
41
|
+
* @param name The name of the gateway.
|
|
42
|
+
*/
|
|
43
|
+
getGateway(name: string): IGateway;
|
|
44
|
+
|
|
38
45
|
/**
|
|
39
46
|
* Unmount a gateway.
|
|
40
47
|
*
|
package/src/lib/Server/Errors.ts
CHANGED
|
@@ -71,3 +71,10 @@ export const E_GATEWAY_BUSY = errorRegistry.register({
|
|
|
71
71
|
metadata: {},
|
|
72
72
|
type: 'public'
|
|
73
73
|
});
|
|
74
|
+
|
|
75
|
+
export const E_GATEWAY_NOT_FOUND = errorRegistry.register({
|
|
76
|
+
name: 'gateway_not_found',
|
|
77
|
+
message: 'No such a gateway.',
|
|
78
|
+
metadata: {},
|
|
79
|
+
type: 'public'
|
|
80
|
+
});
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
+
import * as $Net from 'net';
|
|
17
18
|
import * as C from '../Common';
|
|
18
19
|
import * as G from '../../Common';
|
|
19
20
|
import * as E from '../Errors';
|
|
@@ -27,9 +28,28 @@ enum EStatus {
|
|
|
27
28
|
CLOSING,
|
|
28
29
|
}
|
|
29
30
|
|
|
31
|
+
const INVALID_REQUEST_RESPONSE = Buffer.from('{"rid":"null","body":INVALID REQUEST,"sst":1698886839989,"srt":0,"code":4}');
|
|
32
|
+
|
|
33
|
+
function refuseBadRequest(resp: $Http.ServerResponse): void {
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
|
|
37
|
+
resp.writeHead(400, {
|
|
38
|
+
'content-length': INVALID_REQUEST_RESPONSE.byteLength,
|
|
39
|
+
});
|
|
40
|
+
const socket = resp.socket!;
|
|
41
|
+
resp.end(INVALID_REQUEST_RESPONSE);
|
|
42
|
+
socket.destroy();
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
|
|
46
|
+
// do nothing.
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
30
50
|
class HttpGateway implements C.IGateway {
|
|
31
51
|
|
|
32
|
-
private _server: $Http.Server = $Http.createServer(this._onRequest.bind(this));
|
|
52
|
+
private readonly _server: $Http.Server = $Http.createServer(this._onRequest.bind(this));
|
|
33
53
|
|
|
34
54
|
private _status: EStatus = EStatus.IDLE;
|
|
35
55
|
|
|
@@ -41,17 +61,16 @@ class HttpGateway implements C.IGateway {
|
|
|
41
61
|
) => void;
|
|
42
62
|
|
|
43
63
|
public constructor(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
private _backlog?: number,
|
|
64
|
+
public host: string,
|
|
65
|
+
public port: number,
|
|
66
|
+
private readonly _backlog?: number,
|
|
47
67
|
) { }
|
|
48
68
|
|
|
49
69
|
private _onRequest(req: $Http.IncomingMessage, resp: $Http.ServerResponse): void {
|
|
50
70
|
|
|
51
71
|
if (req.method !== 'POST' || !req.headers['content-length']) {
|
|
52
72
|
|
|
53
|
-
|
|
54
|
-
resp.socket!.destroy();
|
|
73
|
+
refuseBadRequest(resp);
|
|
55
74
|
return;
|
|
56
75
|
}
|
|
57
76
|
|
|
@@ -59,8 +78,7 @@ class HttpGateway implements C.IGateway {
|
|
|
59
78
|
|
|
60
79
|
if (!Number.isSafeInteger(length) || length > G.MAX_PACKET_SIZE) { // Maximum request packet is 64MB
|
|
61
80
|
|
|
62
|
-
|
|
63
|
-
resp.socket!.destroy();
|
|
81
|
+
refuseBadRequest(resp);
|
|
64
82
|
return;
|
|
65
83
|
}
|
|
66
84
|
|
|
@@ -80,7 +98,7 @@ class HttpGateway implements C.IGateway {
|
|
|
80
98
|
|
|
81
99
|
req.removeAllListeners('end');
|
|
82
100
|
req.removeAllListeners('data');
|
|
83
|
-
|
|
101
|
+
refuseBadRequest(resp);
|
|
84
102
|
return;
|
|
85
103
|
}
|
|
86
104
|
|
|
@@ -96,8 +114,8 @@ class HttpGateway implements C.IGateway {
|
|
|
96
114
|
}
|
|
97
115
|
catch (e) {
|
|
98
116
|
|
|
117
|
+
refuseBadRequest(resp);
|
|
99
118
|
this.onError(e);
|
|
100
|
-
req.destroy();
|
|
101
119
|
return;
|
|
102
120
|
}
|
|
103
121
|
|
|
@@ -132,11 +150,15 @@ class HttpGateway implements C.IGateway {
|
|
|
132
150
|
|
|
133
151
|
return new Promise((resolve, reject) => {
|
|
134
152
|
|
|
135
|
-
this._server.listen(this.
|
|
153
|
+
this._server.listen(this.port, this.host, this._backlog)
|
|
136
154
|
.once('listening', () => {
|
|
137
155
|
|
|
138
156
|
this._server.removeAllListeners('error');
|
|
139
157
|
this._status = EStatus.WORKING;
|
|
158
|
+
if (this.port === 0) {
|
|
159
|
+
|
|
160
|
+
this.port = (this._server.address() as $Net.AddressInfo).port;
|
|
161
|
+
}
|
|
140
162
|
resolve();
|
|
141
163
|
})
|
|
142
164
|
.once('error', (e) => {
|
|
@@ -169,7 +191,7 @@ class HttpGateway implements C.IGateway {
|
|
|
169
191
|
case EStatus.WORKING:
|
|
170
192
|
return new Promise((resolve) => {
|
|
171
193
|
|
|
172
|
-
this._server.close(() => resolve());
|
|
194
|
+
this._server.close(() => { resolve(); });
|
|
173
195
|
});
|
|
174
196
|
}
|
|
175
197
|
}
|
|
@@ -48,7 +48,7 @@ interface IClient {
|
|
|
48
48
|
|
|
49
49
|
class TCPGateway implements C.IGateway {
|
|
50
50
|
|
|
51
|
-
private _socket: $Net.Server = $Net.createServer(this._onConnect.bind(this));
|
|
51
|
+
private readonly _socket: $Net.Server = $Net.createServer(this._onConnect.bind(this));
|
|
52
52
|
|
|
53
53
|
private _status: EStatus = EStatus.IDLE;
|
|
54
54
|
|
|
@@ -64,10 +64,10 @@ class TCPGateway implements C.IGateway {
|
|
|
64
64
|
) => void;
|
|
65
65
|
|
|
66
66
|
public constructor(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
private _backlog?: number,
|
|
70
|
-
) {
|
|
67
|
+
public host: string,
|
|
68
|
+
public port: number,
|
|
69
|
+
private readonly _backlog?: number,
|
|
70
|
+
) {}
|
|
71
71
|
|
|
72
72
|
private _onConnect(socket: $Net.Socket): void {
|
|
73
73
|
|
|
@@ -143,11 +143,15 @@ class TCPGateway implements C.IGateway {
|
|
|
143
143
|
|
|
144
144
|
return new Promise((resolve, reject) => {
|
|
145
145
|
|
|
146
|
-
this._socket.listen(this.
|
|
146
|
+
this._socket.listen(this.port, this.host, this._backlog)
|
|
147
147
|
.once('listening', () => {
|
|
148
148
|
|
|
149
149
|
this._socket.removeAllListeners('error');
|
|
150
150
|
this._status = EStatus.WORKING;
|
|
151
|
+
if (this.port === 0) {
|
|
152
|
+
|
|
153
|
+
this.port = (this._socket.address() as $Net.AddressInfo).port;
|
|
154
|
+
}
|
|
151
155
|
resolve();
|
|
152
156
|
})
|
|
153
157
|
.once('error', (e) => {
|
|
@@ -180,7 +184,7 @@ class TCPGateway implements C.IGateway {
|
|
|
180
184
|
case EStatus.WORKING:
|
|
181
185
|
return new Promise((resolve) => {
|
|
182
186
|
|
|
183
|
-
this._socket.close(() => resolve());
|
|
187
|
+
this._socket.close(() => { resolve(); });
|
|
184
188
|
|
|
185
189
|
for (const clientId in this._clients) {
|
|
186
190
|
|
|
@@ -206,6 +210,11 @@ class TCPGateway implements C.IGateway {
|
|
|
206
210
|
}
|
|
207
211
|
}
|
|
208
212
|
|
|
213
|
+
/**
|
|
214
|
+
* Create a gateway of TCP-base televoke/1 protocol.
|
|
215
|
+
*
|
|
216
|
+
* @deprecated This legacy TCP-based televoke/1 protocol is no longer maintained, and will be removed in v2.0.0
|
|
217
|
+
*/
|
|
209
218
|
export function createTCPGateway(host: string, port: number, backlog?: number): C.IGateway {
|
|
210
219
|
|
|
211
220
|
return new TCPGateway(host, port, backlog);
|