serverless-offline 8.2.0 → 8.5.0
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/README.md +157 -116
- package/dist/ServerlessOffline.js +98 -26
- package/dist/config/commandOptions.js +4 -0
- package/dist/config/constants.js +1 -1
- package/dist/config/defaultOptions.js +1 -0
- package/dist/events/http/Endpoint.js +27 -9
- package/dist/events/http/Http.js +3 -3
- package/dist/events/http/HttpServer.js +355 -82
- package/dist/events/http/authFunctionNameExtractor.js +14 -8
- package/dist/events/http/authJWTSettingsExtractor.js +14 -7
- package/dist/events/http/createAuthScheme.js +44 -9
- package/dist/events/http/createJWTAuthScheme.js +52 -13
- package/dist/events/http/lambda-events/LambdaIntegrationEvent.js +7 -6
- package/dist/events/http/lambda-events/LambdaProxyIntegrationEvent.js +38 -7
- package/dist/events/http/lambda-events/LambdaProxyIntegrationEventV2.js +37 -6
- package/dist/events/http/lambda-events/VelocityContext.js +4 -4
- package/dist/events/http/lambda-events/index.js +4 -4
- package/dist/events/http/lambda-events/renderVelocityTemplateObject.js +19 -7
- package/dist/events/schedule/Schedule.js +45 -10
- package/dist/events/websocket/HttpServer.js +24 -7
- package/dist/events/websocket/WebSocket.js +14 -6
- package/dist/events/websocket/WebSocketClients.js +127 -38
- package/dist/events/websocket/WebSocketServer.js +79 -11
- package/dist/events/websocket/http-routes/_catchAll/catchAllRoute.js +9 -2
- package/dist/events/websocket/http-routes/connections/ConnectionsController.js +1 -1
- package/dist/events/websocket/http-routes/connections/connectionsRoutes.js +28 -5
- package/dist/events/websocket/lambda-events/WebSocketConnectEvent.js +5 -5
- package/dist/events/websocket/lambda-events/WebSocketDisconnectEvent.js +1 -1
- package/dist/events/websocket/lambda-events/WebSocketEvent.js +3 -3
- package/dist/events/websocket/lambda-events/WebSocketRequestContext.js +4 -4
- package/dist/lambda/HttpServer.js +34 -10
- package/dist/lambda/Lambda.js +15 -7
- package/dist/lambda/LambdaContext.js +1 -1
- package/dist/lambda/LambdaFunction.js +40 -23
- package/dist/lambda/LambdaFunctionPool.js +9 -8
- package/dist/lambda/handler-runner/HandlerRunner.js +51 -16
- package/dist/lambda/handler-runner/child-process-runner/ChildProcessRunner.js +21 -8
- package/dist/lambda/handler-runner/child-process-runner/childProcessHelper.js +1 -10
- package/dist/lambda/handler-runner/docker-runner/DockerContainer.js +168 -69
- package/dist/lambda/handler-runner/docker-runner/DockerImage.js +21 -5
- package/dist/lambda/handler-runner/docker-runner/DockerRunner.js +4 -4
- package/dist/lambda/handler-runner/go-runner/GoRunner.js +211 -0
- package/dist/lambda/handler-runner/go-runner/index.js +15 -0
- package/dist/lambda/handler-runner/in-process-runner/InProcessRunner.js +16 -22
- package/dist/lambda/handler-runner/java-runner/JavaRunner.js +26 -14
- package/dist/lambda/handler-runner/python-runner/PythonRunner.js +20 -7
- package/dist/lambda/handler-runner/ruby-runner/RubyRunner.js +22 -24
- package/dist/lambda/handler-runner/worker-thread-runner/WorkerThreadRunner.js +2 -2
- package/dist/lambda/handler-runner/worker-thread-runner/workerThreadHelper.js +1 -11
- package/dist/lambda/routes/invocations/InvocationsController.js +30 -11
- package/dist/lambda/routes/invocations/invocationsRoute.js +4 -3
- package/dist/lambda/routes/invoke-async/InvokeAsyncController.js +2 -6
- package/dist/serverlessLog.js +1 -1
- package/dist/utils/checkGoVersion.js +27 -0
- package/dist/utils/getHttpApiCorsConfig.js +18 -5
- package/dist/utils/index.js +24 -16
- package/package.json +86 -37
|
@@ -24,12 +24,12 @@ const {
|
|
|
24
24
|
stringify
|
|
25
25
|
} = JSON;
|
|
26
26
|
|
|
27
|
-
var _lambda = _classPrivateFieldLooseKey("lambda");
|
|
27
|
+
var _lambda = /*#__PURE__*/_classPrivateFieldLooseKey("lambda");
|
|
28
28
|
|
|
29
|
-
var _region = _classPrivateFieldLooseKey("region");
|
|
29
|
+
var _region = /*#__PURE__*/_classPrivateFieldLooseKey("region");
|
|
30
30
|
|
|
31
31
|
class Schedule {
|
|
32
|
-
constructor(lambda, region) {
|
|
32
|
+
constructor(lambda, region, v3Utils) {
|
|
33
33
|
Object.defineProperty(this, _lambda, {
|
|
34
34
|
writable: true,
|
|
35
35
|
value: null
|
|
@@ -40,6 +40,13 @@ class Schedule {
|
|
|
40
40
|
});
|
|
41
41
|
_classPrivateFieldLooseBase(this, _lambda)[_lambda] = lambda;
|
|
42
42
|
_classPrivateFieldLooseBase(this, _region)[_region] = region;
|
|
43
|
+
|
|
44
|
+
if (v3Utils) {
|
|
45
|
+
this.log = v3Utils.log;
|
|
46
|
+
this.progress = v3Utils.progress;
|
|
47
|
+
this.writeText = v3Utils.writeText;
|
|
48
|
+
this.v3Utils = v3Utils;
|
|
49
|
+
}
|
|
43
50
|
}
|
|
44
51
|
|
|
45
52
|
_scheduleEvent(functionKey, scheduleEvent) {
|
|
@@ -50,7 +57,12 @@ class Schedule {
|
|
|
50
57
|
} = scheduleEvent;
|
|
51
58
|
|
|
52
59
|
if (!enabled) {
|
|
53
|
-
|
|
60
|
+
if (this.log) {
|
|
61
|
+
this.log.notice(`Scheduling [${functionKey}] cron: disabled`);
|
|
62
|
+
} else {
|
|
63
|
+
console.log(`Scheduling [${functionKey}] cron: disabled`);
|
|
64
|
+
}
|
|
65
|
+
|
|
54
66
|
return;
|
|
55
67
|
} // Convert string rate to array to support Serverless v2.57.0 and lower.
|
|
56
68
|
|
|
@@ -64,7 +76,11 @@ class Schedule {
|
|
|
64
76
|
rates.forEach(entry => {
|
|
65
77
|
const cron = this._convertExpressionToCron(entry);
|
|
66
78
|
|
|
67
|
-
|
|
79
|
+
if (this.log) {
|
|
80
|
+
this.log.notice(`Scheduling [${functionKey}] cron: [${cron}] input: ${stringify(input)}`);
|
|
81
|
+
} else {
|
|
82
|
+
console.log(`Scheduling [${functionKey}] cron: [${cron}] input: ${stringify(input)}`);
|
|
83
|
+
}
|
|
68
84
|
|
|
69
85
|
_nodeSchedule.default.scheduleJob(cron, async () => {
|
|
70
86
|
try {
|
|
@@ -75,9 +91,18 @@ class Schedule {
|
|
|
75
91
|
/* const result = */
|
|
76
92
|
|
|
77
93
|
await lambdaFunction.runHandler();
|
|
78
|
-
|
|
94
|
+
|
|
95
|
+
if (this.log) {
|
|
96
|
+
this.log.notice(`Successfully invoked scheduled function: [${functionKey}]`);
|
|
97
|
+
} else {
|
|
98
|
+
console.log(`Successfully invoked scheduled function: [${functionKey}]`);
|
|
99
|
+
}
|
|
79
100
|
} catch (err) {
|
|
80
|
-
|
|
101
|
+
if (this.log) {
|
|
102
|
+
this.log.error(`Failed to execute scheduled function: [${functionKey}] Error: ${err}`);
|
|
103
|
+
} else {
|
|
104
|
+
console.log(`Failed to execute scheduled function: [${functionKey}] Error: ${err}`);
|
|
105
|
+
}
|
|
81
106
|
}
|
|
82
107
|
});
|
|
83
108
|
});
|
|
@@ -107,7 +132,12 @@ class Schedule {
|
|
|
107
132
|
return `0 0 */${number} * *`;
|
|
108
133
|
|
|
109
134
|
default:
|
|
110
|
-
|
|
135
|
+
if (this.log) {
|
|
136
|
+
this.log.error(`scheduler: Invalid rate syntax '${rate}', will not schedule`);
|
|
137
|
+
} else {
|
|
138
|
+
console.log(`scheduler: Invalid rate syntax '${rate}', will not schedule`);
|
|
139
|
+
}
|
|
140
|
+
|
|
111
141
|
return null;
|
|
112
142
|
}
|
|
113
143
|
}
|
|
@@ -116,14 +146,19 @@ class Schedule {
|
|
|
116
146
|
const params = scheduleEvent.replace('rate(', '').replace('cron(', '').replace(')', '');
|
|
117
147
|
|
|
118
148
|
if (scheduleEvent.startsWith('cron(')) {
|
|
119
|
-
console.log('schedule rate "cron" not yet supported!'); // return this._convertCronSyntax(params)
|
|
149
|
+
if (!this.log) console.log('schedule rate "cron" not yet supported!'); // return this._convertCronSyntax(params)
|
|
120
150
|
}
|
|
121
151
|
|
|
122
152
|
if (scheduleEvent.startsWith('rate(')) {
|
|
123
153
|
return this._convertRateToCron(params);
|
|
124
154
|
}
|
|
125
155
|
|
|
126
|
-
|
|
156
|
+
if (this.log) {
|
|
157
|
+
this.log.error('scheduler: invalid, schedule syntax');
|
|
158
|
+
} else {
|
|
159
|
+
console.log('scheduler: invalid, schedule syntax');
|
|
160
|
+
}
|
|
161
|
+
|
|
127
162
|
return undefined;
|
|
128
163
|
}
|
|
129
164
|
|
|
@@ -19,14 +19,14 @@ var id = 0;
|
|
|
19
19
|
|
|
20
20
|
function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
|
|
21
21
|
|
|
22
|
-
var _options = _classPrivateFieldLooseKey("options");
|
|
22
|
+
var _options = /*#__PURE__*/_classPrivateFieldLooseKey("options");
|
|
23
23
|
|
|
24
|
-
var _server = _classPrivateFieldLooseKey("server");
|
|
24
|
+
var _server = /*#__PURE__*/_classPrivateFieldLooseKey("server");
|
|
25
25
|
|
|
26
|
-
var _webSocketClients = _classPrivateFieldLooseKey("webSocketClients");
|
|
26
|
+
var _webSocketClients = /*#__PURE__*/_classPrivateFieldLooseKey("webSocketClients");
|
|
27
27
|
|
|
28
28
|
class HttpServer {
|
|
29
|
-
constructor(options, webSocketClients) {
|
|
29
|
+
constructor(options, webSocketClients, v3Utils) {
|
|
30
30
|
Object.defineProperty(this, _options, {
|
|
31
31
|
writable: true,
|
|
32
32
|
value: null
|
|
@@ -41,6 +41,14 @@ class HttpServer {
|
|
|
41
41
|
});
|
|
42
42
|
_classPrivateFieldLooseBase(this, _options)[_options] = options;
|
|
43
43
|
_classPrivateFieldLooseBase(this, _webSocketClients)[_webSocketClients] = webSocketClients;
|
|
44
|
+
|
|
45
|
+
if (v3Utils) {
|
|
46
|
+
this.log = v3Utils.log;
|
|
47
|
+
this.progress = v3Utils.progress;
|
|
48
|
+
this.writeText = v3Utils.writeText;
|
|
49
|
+
this.v3Utils = v3Utils;
|
|
50
|
+
}
|
|
51
|
+
|
|
44
52
|
const {
|
|
45
53
|
host,
|
|
46
54
|
websocketPort
|
|
@@ -59,7 +67,7 @@ class HttpServer {
|
|
|
59
67
|
|
|
60
68
|
async start() {
|
|
61
69
|
// add routes
|
|
62
|
-
const routes = [...(0, _index.connectionsRoutes)(_classPrivateFieldLooseBase(this, _webSocketClients)[_webSocketClients]), (0, _index.catchAllRoute)()];
|
|
70
|
+
const routes = [...(0, _index.connectionsRoutes)(_classPrivateFieldLooseBase(this, _webSocketClients)[_webSocketClients], this.v3Utils), (0, _index.catchAllRoute)(this.v3Utils)];
|
|
63
71
|
|
|
64
72
|
_classPrivateFieldLooseBase(this, _server)[_server].route(routes);
|
|
65
73
|
|
|
@@ -72,11 +80,20 @@ class HttpServer {
|
|
|
72
80
|
try {
|
|
73
81
|
await _classPrivateFieldLooseBase(this, _server)[_server].start();
|
|
74
82
|
} catch (err) {
|
|
75
|
-
|
|
83
|
+
if (this.log) {
|
|
84
|
+
this.log.error(`Unexpected error while starting serverless-offline websocket server on port ${websocketPort}:`, err);
|
|
85
|
+
} else {
|
|
86
|
+
console.error(`Unexpected error while starting serverless-offline websocket server on port ${websocketPort}:`, err);
|
|
87
|
+
}
|
|
88
|
+
|
|
76
89
|
process.exit(1);
|
|
77
90
|
}
|
|
78
91
|
|
|
79
|
-
(
|
|
92
|
+
if (this.log) {
|
|
93
|
+
this.log.notice(`Offline [http for websocket] listening on http${httpsProtocol ? 's' : ''}://${host}:${websocketPort}`);
|
|
94
|
+
} else {
|
|
95
|
+
(0, _serverlessLog.default)(`Offline [http for websocket] listening on http${httpsProtocol ? 's' : ''}://${host}:${websocketPort}`);
|
|
96
|
+
}
|
|
80
97
|
} // stops the server
|
|
81
98
|
|
|
82
99
|
|
|
@@ -21,12 +21,12 @@ var id = 0;
|
|
|
21
21
|
|
|
22
22
|
function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
|
|
23
23
|
|
|
24
|
-
var _httpServer = _classPrivateFieldLooseKey("httpServer");
|
|
24
|
+
var _httpServer = /*#__PURE__*/_classPrivateFieldLooseKey("httpServer");
|
|
25
25
|
|
|
26
|
-
var _webSocketServer = _classPrivateFieldLooseKey("webSocketServer");
|
|
26
|
+
var _webSocketServer = /*#__PURE__*/_classPrivateFieldLooseKey("webSocketServer");
|
|
27
27
|
|
|
28
28
|
class WebSocket {
|
|
29
|
-
constructor(serverless, options, lambda) {
|
|
29
|
+
constructor(serverless, options, lambda, v3Utils) {
|
|
30
30
|
Object.defineProperty(this, _httpServer, {
|
|
31
31
|
writable: true,
|
|
32
32
|
value: null
|
|
@@ -35,10 +35,18 @@ class WebSocket {
|
|
|
35
35
|
writable: true,
|
|
36
36
|
value: null
|
|
37
37
|
});
|
|
38
|
-
const webSocketClients = new _WebSocketClients.default(serverless, options, lambda);
|
|
39
|
-
_classPrivateFieldLooseBase(this, _httpServer)[_httpServer] = new _HttpServer.default(options, webSocketClients); // share server
|
|
38
|
+
const webSocketClients = new _WebSocketClients.default(serverless, options, lambda, v3Utils);
|
|
40
39
|
|
|
41
|
-
|
|
40
|
+
if (v3Utils) {
|
|
41
|
+
this.log = v3Utils.log;
|
|
42
|
+
this.progress = v3Utils.progress;
|
|
43
|
+
this.writeText = v3Utils.writeText;
|
|
44
|
+
this.v3Utils = v3Utils;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
_classPrivateFieldLooseBase(this, _httpServer)[_httpServer] = new _HttpServer.default(options, webSocketClients, this.v3Utils); // share server
|
|
48
|
+
|
|
49
|
+
_classPrivateFieldLooseBase(this, _webSocketServer)[_webSocketServer] = new _WebSocketServer.default(options, webSocketClients, _classPrivateFieldLooseBase(this, _httpServer)[_httpServer].server, v3Utils);
|
|
42
50
|
}
|
|
43
51
|
|
|
44
52
|
start() {
|
|
@@ -30,22 +30,22 @@ const {
|
|
|
30
30
|
stringify
|
|
31
31
|
} = JSON;
|
|
32
32
|
|
|
33
|
-
var _clients = _classPrivateFieldLooseKey("clients");
|
|
33
|
+
var _clients = /*#__PURE__*/_classPrivateFieldLooseKey("clients");
|
|
34
34
|
|
|
35
|
-
var _lambda = _classPrivateFieldLooseKey("lambda");
|
|
35
|
+
var _lambda = /*#__PURE__*/_classPrivateFieldLooseKey("lambda");
|
|
36
36
|
|
|
37
|
-
var _options = _classPrivateFieldLooseKey("options");
|
|
37
|
+
var _options = /*#__PURE__*/_classPrivateFieldLooseKey("options");
|
|
38
38
|
|
|
39
|
-
var _webSocketRoutes = _classPrivateFieldLooseKey("webSocketRoutes");
|
|
39
|
+
var _webSocketRoutes = /*#__PURE__*/_classPrivateFieldLooseKey("webSocketRoutes");
|
|
40
40
|
|
|
41
|
-
var _websocketsApiRouteSelectionExpression = _classPrivateFieldLooseKey("websocketsApiRouteSelectionExpression");
|
|
41
|
+
var _websocketsApiRouteSelectionExpression = /*#__PURE__*/_classPrivateFieldLooseKey("websocketsApiRouteSelectionExpression");
|
|
42
42
|
|
|
43
|
-
var _idleTimeouts = _classPrivateFieldLooseKey("idleTimeouts");
|
|
43
|
+
var _idleTimeouts = /*#__PURE__*/_classPrivateFieldLooseKey("idleTimeouts");
|
|
44
44
|
|
|
45
|
-
var _hardTimeouts = _classPrivateFieldLooseKey("hardTimeouts");
|
|
45
|
+
var _hardTimeouts = /*#__PURE__*/_classPrivateFieldLooseKey("hardTimeouts");
|
|
46
46
|
|
|
47
47
|
class WebSocketClients {
|
|
48
|
-
constructor(serverless, options, lambda) {
|
|
48
|
+
constructor(serverless, options, lambda, v3Utils) {
|
|
49
49
|
Object.defineProperty(this, _clients, {
|
|
50
50
|
writable: true,
|
|
51
51
|
value: new Map()
|
|
@@ -77,6 +77,13 @@ class WebSocketClients {
|
|
|
77
77
|
_classPrivateFieldLooseBase(this, _lambda)[_lambda] = lambda;
|
|
78
78
|
_classPrivateFieldLooseBase(this, _options)[_options] = options;
|
|
79
79
|
_classPrivateFieldLooseBase(this, _websocketsApiRouteSelectionExpression)[_websocketsApiRouteSelectionExpression] = serverless.service.provider.websocketsApiRouteSelectionExpression || _index2.DEFAULT_WEBSOCKETS_API_ROUTE_SELECTION_EXPRESSION;
|
|
80
|
+
|
|
81
|
+
if (v3Utils) {
|
|
82
|
+
this.log = v3Utils.log;
|
|
83
|
+
this.progress = v3Utils.progress;
|
|
84
|
+
this.writeText = v3Utils.writeText;
|
|
85
|
+
this.v3Utils = v3Utils;
|
|
86
|
+
}
|
|
80
87
|
}
|
|
81
88
|
|
|
82
89
|
_addWebSocketClient(client, connectionId) {
|
|
@@ -105,7 +112,12 @@ class WebSocketClients {
|
|
|
105
112
|
|
|
106
113
|
_addHardTimeout(client, connectionId) {
|
|
107
114
|
const timeoutId = setTimeout(() => {
|
|
108
|
-
(
|
|
115
|
+
if (this.log) {
|
|
116
|
+
this.log.debug(`timeout:hard:${connectionId}`);
|
|
117
|
+
} else {
|
|
118
|
+
(0, _debugLog.default)(`timeout:hard:${connectionId}`);
|
|
119
|
+
}
|
|
120
|
+
|
|
109
121
|
client.close(1001, 'Going away');
|
|
110
122
|
}, _classPrivateFieldLooseBase(this, _options)[_options].webSocketHardTimeout * 1000);
|
|
111
123
|
|
|
@@ -123,9 +135,19 @@ class WebSocketClients {
|
|
|
123
135
|
|
|
124
136
|
this._clearIdleTimeout(client);
|
|
125
137
|
|
|
126
|
-
(
|
|
138
|
+
if (this.log) {
|
|
139
|
+
this.log.debug(`timeout:idle:${connectionId}:reset`);
|
|
140
|
+
} else {
|
|
141
|
+
(0, _debugLog.default)(`timeout:idle:${connectionId}:reset`);
|
|
142
|
+
}
|
|
143
|
+
|
|
127
144
|
const timeoutId = setTimeout(() => {
|
|
128
|
-
(
|
|
145
|
+
if (this.log) {
|
|
146
|
+
this.log.debug(`timeout:idle:${connectionId}:trigger`);
|
|
147
|
+
} else {
|
|
148
|
+
(0, _debugLog.default)(`timeout:idle:${connectionId}:trigger`);
|
|
149
|
+
}
|
|
150
|
+
|
|
129
151
|
client.close(1001, 'Going away');
|
|
130
152
|
}, _classPrivateFieldLooseBase(this, _options)[_options].webSocketIdleTimeout * 1000);
|
|
131
153
|
|
|
@@ -138,14 +160,53 @@ class WebSocketClients {
|
|
|
138
160
|
clearTimeout(timeoutId);
|
|
139
161
|
}
|
|
140
162
|
|
|
141
|
-
async
|
|
142
|
-
|
|
163
|
+
async verifyClient(connectionId, request) {
|
|
164
|
+
const route = _classPrivateFieldLooseBase(this, _webSocketRoutes)[_webSocketRoutes].get('$connect');
|
|
143
165
|
|
|
144
|
-
if (!
|
|
145
|
-
|
|
166
|
+
if (!route) {
|
|
167
|
+
return {
|
|
168
|
+
verified: false,
|
|
169
|
+
statusCode: 502
|
|
170
|
+
};
|
|
146
171
|
}
|
|
147
172
|
|
|
148
|
-
|
|
173
|
+
const connectEvent = new _index.WebSocketConnectEvent(connectionId, request, _classPrivateFieldLooseBase(this, _options)[_options]).create();
|
|
174
|
+
|
|
175
|
+
const lambdaFunction = _classPrivateFieldLooseBase(this, _lambda)[_lambda].get(route.functionKey);
|
|
176
|
+
|
|
177
|
+
lambdaFunction.setEvent(connectEvent);
|
|
178
|
+
|
|
179
|
+
try {
|
|
180
|
+
const {
|
|
181
|
+
statusCode
|
|
182
|
+
} = await lambdaFunction.runHandler();
|
|
183
|
+
const verified = statusCode >= 200 && statusCode < 300;
|
|
184
|
+
return {
|
|
185
|
+
verified,
|
|
186
|
+
statusCode
|
|
187
|
+
};
|
|
188
|
+
} catch (err) {
|
|
189
|
+
if (this.log) {
|
|
190
|
+
this.log.debug(`Error in route handler '${route.functionKey}'`, err);
|
|
191
|
+
} else {
|
|
192
|
+
(0, _debugLog.default)(`Error in route handler '${route.functionKey}'`, err);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
verified: false,
|
|
197
|
+
statusCode: 502
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
async _processEvent(websocketClient, connectionId, routeKey, event) {
|
|
203
|
+
let route = _classPrivateFieldLooseBase(this, _webSocketRoutes)[_webSocketRoutes].get(routeKey);
|
|
204
|
+
|
|
205
|
+
if (!route && routeKey !== '$disconnect') {
|
|
206
|
+
route = _classPrivateFieldLooseBase(this, _webSocketRoutes)[_webSocketRoutes].get('$default');
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (!route) {
|
|
149
210
|
return;
|
|
150
211
|
}
|
|
151
212
|
|
|
@@ -156,25 +217,37 @@ class WebSocketClients {
|
|
|
156
217
|
message: 'Internal server error',
|
|
157
218
|
requestId: '1234567890'
|
|
158
219
|
}));
|
|
159
|
-
} // mimic AWS behaviour (close connection) when the $connect route handler throws
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
if (route === '$connect') {
|
|
163
|
-
websocketClient.close();
|
|
164
220
|
}
|
|
165
221
|
|
|
166
|
-
(
|
|
222
|
+
if (this.log) {
|
|
223
|
+
this.log.debug(`Error in route handler '${route.functionKey}'`, err);
|
|
224
|
+
} else {
|
|
225
|
+
(0, _debugLog.default)(`Error in route handler '${route.functionKey}'`, err);
|
|
226
|
+
}
|
|
167
227
|
};
|
|
168
228
|
|
|
169
|
-
const lambdaFunction = _classPrivateFieldLooseBase(this, _lambda)[_lambda].get(functionKey);
|
|
229
|
+
const lambdaFunction = _classPrivateFieldLooseBase(this, _lambda)[_lambda].get(route.functionKey);
|
|
170
230
|
|
|
171
|
-
lambdaFunction.setEvent(event);
|
|
231
|
+
lambdaFunction.setEvent(event);
|
|
172
232
|
|
|
173
233
|
try {
|
|
174
|
-
|
|
175
|
-
|
|
234
|
+
const {
|
|
235
|
+
body
|
|
236
|
+
} = await lambdaFunction.runHandler();
|
|
237
|
+
|
|
238
|
+
if (body && routeKey !== '$disconnect' && route.definition.routeResponseSelectionExpression === '$default') {
|
|
239
|
+
// https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api-selection-expressions.html#apigateway-websocket-api-route-response-selection-expressions
|
|
240
|
+
// TODO: Once API gateway supports RouteResponses, this will need to change to support that functionality
|
|
241
|
+
// For now, send body back to the client
|
|
242
|
+
this.send(connectionId, body);
|
|
243
|
+
}
|
|
176
244
|
} catch (err) {
|
|
177
|
-
|
|
245
|
+
if (this.log) {
|
|
246
|
+
this.log.error(err);
|
|
247
|
+
} else {
|
|
248
|
+
console.log(err);
|
|
249
|
+
}
|
|
250
|
+
|
|
178
251
|
sendError(err);
|
|
179
252
|
}
|
|
180
253
|
}
|
|
@@ -199,15 +272,15 @@ class WebSocketClients {
|
|
|
199
272
|
return route || _index2.DEFAULT_WEBSOCKETS_ROUTE;
|
|
200
273
|
}
|
|
201
274
|
|
|
202
|
-
addClient(webSocketClient,
|
|
275
|
+
addClient(webSocketClient, connectionId) {
|
|
203
276
|
this._addWebSocketClient(webSocketClient, connectionId);
|
|
204
277
|
|
|
205
|
-
const connectEvent = new _index.WebSocketConnectEvent(connectionId, request, _classPrivateFieldLooseBase(this, _options)[_options]).create();
|
|
206
|
-
|
|
207
|
-
this._processEvent(webSocketClient, connectionId, '$connect', connectEvent);
|
|
208
|
-
|
|
209
278
|
webSocketClient.on('close', () => {
|
|
210
|
-
(
|
|
279
|
+
if (this.log) {
|
|
280
|
+
this.log.debug(`disconnect:${connectionId}`);
|
|
281
|
+
} else {
|
|
282
|
+
(0, _debugLog.default)(`disconnect:${connectionId}`);
|
|
283
|
+
}
|
|
211
284
|
|
|
212
285
|
this._removeWebSocketClient(webSocketClient);
|
|
213
286
|
|
|
@@ -220,11 +293,20 @@ class WebSocketClients {
|
|
|
220
293
|
this._processEvent(webSocketClient, connectionId, '$disconnect', disconnectEvent);
|
|
221
294
|
});
|
|
222
295
|
webSocketClient.on('message', message => {
|
|
223
|
-
(
|
|
296
|
+
if (this.log) {
|
|
297
|
+
this.log.debug(`message:${message}`);
|
|
298
|
+
} else {
|
|
299
|
+
(0, _debugLog.default)(`message:${message}`);
|
|
300
|
+
}
|
|
224
301
|
|
|
225
302
|
const route = this._getRoute(message);
|
|
226
303
|
|
|
227
|
-
(
|
|
304
|
+
if (this.log) {
|
|
305
|
+
this.log.debug(`route:${route} on connection=${connectionId}`);
|
|
306
|
+
} else {
|
|
307
|
+
(0, _debugLog.default)(`route:${route} on connection=${connectionId}`);
|
|
308
|
+
}
|
|
309
|
+
|
|
228
310
|
const event = new _index.WebSocketEvent(connectionId, route, message).create();
|
|
229
311
|
|
|
230
312
|
this._onWebSocketUsed(connectionId);
|
|
@@ -233,11 +315,18 @@ class WebSocketClients {
|
|
|
233
315
|
});
|
|
234
316
|
}
|
|
235
317
|
|
|
236
|
-
addRoute(functionKey,
|
|
318
|
+
addRoute(functionKey, definition) {
|
|
237
319
|
// set the route name
|
|
238
|
-
_classPrivateFieldLooseBase(this, _webSocketRoutes)[_webSocketRoutes].set(route,
|
|
320
|
+
_classPrivateFieldLooseBase(this, _webSocketRoutes)[_webSocketRoutes].set(definition.route, {
|
|
321
|
+
functionKey,
|
|
322
|
+
definition
|
|
323
|
+
});
|
|
239
324
|
|
|
240
|
-
(
|
|
325
|
+
if (this.log) {
|
|
326
|
+
this.log.notice(`route '${definition}'`);
|
|
327
|
+
} else {
|
|
328
|
+
(0, _serverlessLog.default)(`route '${definition}'`);
|
|
329
|
+
}
|
|
241
330
|
}
|
|
242
331
|
|
|
243
332
|
close(connectionId) {
|
|
@@ -21,12 +21,14 @@ var id = 0;
|
|
|
21
21
|
|
|
22
22
|
function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
|
|
23
23
|
|
|
24
|
-
var _options = _classPrivateFieldLooseKey("options");
|
|
24
|
+
var _options = /*#__PURE__*/_classPrivateFieldLooseKey("options");
|
|
25
25
|
|
|
26
|
-
var _webSocketClients = _classPrivateFieldLooseKey("webSocketClients");
|
|
26
|
+
var _webSocketClients = /*#__PURE__*/_classPrivateFieldLooseKey("webSocketClients");
|
|
27
|
+
|
|
28
|
+
var _connectionIds = /*#__PURE__*/_classPrivateFieldLooseKey("connectionIds");
|
|
27
29
|
|
|
28
30
|
class WebSocketServer {
|
|
29
|
-
constructor(options, webSocketClients, sharedServer) {
|
|
31
|
+
constructor(options, webSocketClients, sharedServer, v3Utils) {
|
|
30
32
|
Object.defineProperty(this, _options, {
|
|
31
33
|
writable: true,
|
|
32
34
|
value: null
|
|
@@ -35,17 +37,79 @@ class WebSocketServer {
|
|
|
35
37
|
writable: true,
|
|
36
38
|
value: null
|
|
37
39
|
});
|
|
40
|
+
Object.defineProperty(this, _connectionIds, {
|
|
41
|
+
writable: true,
|
|
42
|
+
value: new Map()
|
|
43
|
+
});
|
|
38
44
|
_classPrivateFieldLooseBase(this, _options)[_options] = options;
|
|
39
45
|
_classPrivateFieldLooseBase(this, _webSocketClients)[_webSocketClients] = webSocketClients;
|
|
46
|
+
|
|
47
|
+
if (v3Utils) {
|
|
48
|
+
this.log = v3Utils.log;
|
|
49
|
+
this.progress = v3Utils.progress;
|
|
50
|
+
this.writeText = v3Utils.writeText;
|
|
51
|
+
this.v3Utils = v3Utils;
|
|
52
|
+
}
|
|
53
|
+
|
|
40
54
|
const server = new _ws.Server({
|
|
41
|
-
server: sharedServer
|
|
55
|
+
server: sharedServer,
|
|
56
|
+
verifyClient: ({
|
|
57
|
+
req
|
|
58
|
+
}, cb) => {
|
|
59
|
+
const connectionId = (0, _index.createUniqueId)();
|
|
60
|
+
const {
|
|
61
|
+
headers
|
|
62
|
+
} = req;
|
|
63
|
+
const key = headers['sec-websocket-key'];
|
|
64
|
+
|
|
65
|
+
if (this.log) {
|
|
66
|
+
this.log.debug(`verifyClient:${key} ${connectionId}`);
|
|
67
|
+
} else {
|
|
68
|
+
(0, _debugLog.default)(`verifyClient:${key} ${connectionId}`);
|
|
69
|
+
} // Use the websocket key to coorelate connection IDs
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
_classPrivateFieldLooseBase(this, _connectionIds)[_connectionIds][key] = connectionId;
|
|
73
|
+
|
|
74
|
+
_classPrivateFieldLooseBase(this, _webSocketClients)[_webSocketClients].verifyClient(connectionId, req).then(({
|
|
75
|
+
verified,
|
|
76
|
+
statusCode
|
|
77
|
+
}) => {
|
|
78
|
+
try {
|
|
79
|
+
if (!verified) {
|
|
80
|
+
cb(false, statusCode);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
cb(true);
|
|
85
|
+
} catch (e) {
|
|
86
|
+
(0, _debugLog.default)(`Error verifying`, e);
|
|
87
|
+
cb(false);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
}
|
|
42
91
|
});
|
|
43
92
|
server.on('connection', (webSocketClient, request) => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
93
|
+
if (this.log) {
|
|
94
|
+
this.log.notice('received connection');
|
|
95
|
+
} else {
|
|
96
|
+
console.log('received connection');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const {
|
|
100
|
+
headers
|
|
101
|
+
} = request;
|
|
102
|
+
const key = headers['sec-websocket-key'];
|
|
103
|
+
|
|
104
|
+
const connectionId = _classPrivateFieldLooseBase(this, _connectionIds)[_connectionIds][key];
|
|
105
|
+
|
|
106
|
+
if (this.log) {
|
|
107
|
+
this.log.debug(`connect:${connectionId}`);
|
|
108
|
+
} else {
|
|
109
|
+
(0, _debugLog.default)(`connect:${connectionId}`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
_classPrivateFieldLooseBase(this, _webSocketClients)[_webSocketClients].addClient(webSocketClient, connectionId);
|
|
49
113
|
});
|
|
50
114
|
}
|
|
51
115
|
|
|
@@ -56,14 +120,18 @@ class WebSocketServer {
|
|
|
56
120
|
websocketPort
|
|
57
121
|
} = _classPrivateFieldLooseBase(this, _options)[_options];
|
|
58
122
|
|
|
59
|
-
(
|
|
123
|
+
if (this.log) {
|
|
124
|
+
this.log.notice(`Offline [websocket] listening on ws${httpsProtocol ? 's' : ''}://${host}:${websocketPort}`);
|
|
125
|
+
} else {
|
|
126
|
+
(0, _serverlessLog.default)(`Offline [websocket] listening on ws${httpsProtocol ? 's' : ''}://${host}:${websocketPort}`);
|
|
127
|
+
}
|
|
60
128
|
} // no-op, we're re-using the http server
|
|
61
129
|
|
|
62
130
|
|
|
63
131
|
stop() {}
|
|
64
132
|
|
|
65
133
|
addRoute(functionKey, webSocketEvent) {
|
|
66
|
-
_classPrivateFieldLooseBase(this, _webSocketClients)[_webSocketClients].addRoute(functionKey, webSocketEvent
|
|
134
|
+
_classPrivateFieldLooseBase(this, _webSocketClients)[_webSocketClients].addRoute(functionKey, webSocketEvent); // serverlessLog(`route '${route}'`)
|
|
67
135
|
|
|
68
136
|
}
|
|
69
137
|
|
|
@@ -9,7 +9,8 @@ var _debugLog = _interopRequireDefault(require("../../../../debugLog.js"));
|
|
|
9
9
|
|
|
10
10
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
11
|
|
|
12
|
-
function catchAllRoute() {
|
|
12
|
+
function catchAllRoute(v3Utils) {
|
|
13
|
+
const log = v3Utils && v3Utils.log;
|
|
13
14
|
return {
|
|
14
15
|
method: 'GET',
|
|
15
16
|
path: '/{path*}',
|
|
@@ -18,7 +19,13 @@ function catchAllRoute() {
|
|
|
18
19
|
const {
|
|
19
20
|
url
|
|
20
21
|
} = request;
|
|
21
|
-
|
|
22
|
+
|
|
23
|
+
if (log) {
|
|
24
|
+
log.debug(`got GET to ${url}`);
|
|
25
|
+
} else {
|
|
26
|
+
(0, _debugLog.default)(`got GET to ${url}`);
|
|
27
|
+
}
|
|
28
|
+
|
|
22
29
|
return h.response(null).code(426);
|
|
23
30
|
}
|
|
24
31
|
|
|
@@ -11,7 +11,7 @@ var id = 0;
|
|
|
11
11
|
|
|
12
12
|
function _classPrivateFieldLooseKey(name) { return "__private_" + id++ + "_" + name; }
|
|
13
13
|
|
|
14
|
-
var _webSocketClients = _classPrivateFieldLooseKey("webSocketClients");
|
|
14
|
+
var _webSocketClients = /*#__PURE__*/_classPrivateFieldLooseKey("webSocketClients");
|
|
15
15
|
|
|
16
16
|
class ConnectionsController {
|
|
17
17
|
constructor(webSocketClients) {
|