Skip to content

Commit 4764a26

Browse files
committed
Add support for _bg, remove legacy :bg support
1 parent fa6823d commit 4764a26

File tree

3 files changed

+79
-95
lines changed

3 files changed

+79
-95
lines changed

lib/gateway.js

Lines changed: 62 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -158,27 +158,23 @@ class Gateway extends EventEmitter {
158158
return headers;
159159
}
160160

161-
__background__ (req, res, definition, params) {
161+
__beginBackgroundExecution__ (req, res, definition, params, headers) {
162162
let bgResponse = this.supportedBgModes[definition.bg && definition.bg.mode] ||
163163
this.supportedBgModes[this.defaultBgMode];
164164
let value = bgResponse(definition, params);
165-
let initialHeaders = {
166-
'x-execution-uuid': req._uuid
167-
};
168-
let headers = this.__createHeaders__(req, initialHeaders);
165+
headers = headers || {};
166+
headers = this.__createHeaders__(req, headers);
169167
headers['content-type'] = headers['content-type'] ||
170168
(value instanceof Buffer ? 'application/octet-stream' : 'application/json');
171169
value = value instanceof Buffer ? value : JSON.stringify(value);
172170
res.headersSent || res.writeHead(202, this.__formatHeaders__(headers));
173171
res.finished || res.end(value);
174172
}
175173

176-
__beginServerSentEvent__ (req, res, definition, params) {
177-
let initialHeaders = {
178-
'content-type': 'text/event-stream',
179-
'x-execution-uuid': req._uuid
180-
};
181-
let headers = this.__createHeaders__(req, initialHeaders);
174+
__beginServerSentEvent__ (req, res, definition, params, headers) {
175+
headers = headers || {};
176+
headers = this.__createHeaders__(req, headers);
177+
headers['content-type'] = 'text/event-stream';
182178
res.headersSent || res.writeHead(200, this.__formatHeaders__(headers));
183179
// Create SSE Instance
184180
let sseInstance = {
@@ -928,13 +924,16 @@ class Gateway extends EventEmitter {
928924
let errors = {};
929925

930926
// Handle special parameters
931-
if (params._stream) {
932-
try {
933-
params._stream = types.parse('object', null, params._stream, convert);
934-
} catch (e) {
935-
params._stream = params._stream;
927+
let specialParams = ['_bg', '_stream', '_debug'];
928+
specialParams.forEach(key => {
929+
if (params[key]) {
930+
try {
931+
params[key] = types.parse('object', null, params[key], convert);
932+
} catch (e) {
933+
params[key] = params[key];
934+
}
936935
}
937-
}
936+
});
938937

939938
let paramsList = definition.params.map(param => {
940939
// Catch where there is a mismatch
@@ -1089,37 +1088,17 @@ class Gateway extends EventEmitter {
10891088
this._requestCount += 1;
10901089

10911090
let urlinfo = url.parse(req.url);
1092-
let pathinfo = urlinfo.pathname.split(':');
1093-
let pathname = pathinfo[0];
1091+
let pathname = urlinfo.pathname;
10941092
req.url = [pathname, urlinfo.search].join('');
10951093

1096-
// Legacy, will deprecate
1097-
let pathquery;
1098-
try {
1099-
pathquery = this.__parseParamsFromEncodedURL__(pathinfo[1] || '');
1100-
} catch (e) {
1101-
return this.__parameterParseError__(req, res, e.message, 400);
1102-
}
1103-
if ('bg' in pathquery) {
1104-
req._background = true;
1105-
this.log(req, `Background Function Initiated`);
1106-
}
1107-
11081094
if (
11091095
this.trailingSlashRedirectMethods[req.method] &&
11101096
req.headers['user-agent'] &&
11111097
!pathname.endsWith('/') &&
11121098
pathname.split('/').pop().indexOf('.') === -1
11131099
) {
11141100
this.log(req, `Redirect`);
1115-
if (pathinfo.length === 2) {
1116-
pathinfo[0] = pathname + '/';
1117-
pathinfo[1] = pathinfo[1].endsWith('/') ?
1118-
pathinfo[1].substr(0, pathinfo[1].length - 1) :
1119-
pathinfo[1];
1120-
return this.__redirect__(req, res, pathinfo.join(':') + (urlinfo.search || ''));
1121-
}
1122-
return this.__redirect__(req, res, [pathinfo.join(':'), urlinfo.search].join('/'));
1101+
return this.__redirect__(req, res, [pathname, urlinfo.search].join('/'));
11231102
} else if (!(req.method in this.supportedMethods)) {
11241103
this.log(req, `Not Implemented`, 'error');
11251104
return this.__clientError__(req, res, `Not Implemented`, 501);
@@ -1150,6 +1129,12 @@ class Gateway extends EventEmitter {
11501129
this.log(req, `Request Received (Size ${buffer.length})`);
11511130
this.resolve(req, res, buffer, (err, definition, data, buffer, proxyParameters) => {
11521131

1132+
let headers = {};
1133+
headers['x-execution-uuid'] = req._uuid;
1134+
if (definition && definition.allowOrigin) {
1135+
headers['access-control-allow-origin'] = definition.allowOrigin;
1136+
}
1137+
11531138
if (err) {
11541139
if (err.accessSourceError) {
11551140
return this.__accessSourceError__(req, res, err.message);
@@ -1209,22 +1194,28 @@ class Gateway extends EventEmitter {
12091194
return this.__parameterError__(req, res, validated.errors);
12101195
}
12111196

1212-
if (req._background) {
1213-
this.log(req, `Background Function Responded to Client`);
1214-
this.__background__(req, res, definition, validated.params);
1215-
}
1216-
12171197
if (
1218-
validated.params._stream === '' ||
1219-
validated.params._stream
1198+
definition.bg && (
1199+
validated.params._bg === '' ||
1200+
validated.params._bg
1201+
)
1202+
) {
1203+
this.log(req, `Background Function Responded to Client`);
1204+
this.__beginBackgroundExecution__(req, res, definition, validated.params, headers);
1205+
} else if (
1206+
definition.streams &&
1207+
definition.streams.length > 0 && (
1208+
validated.params._stream === '' ||
1209+
validated.params._stream
1210+
)
12201211
) {
12211212
let streamValidated = this.__validateStreams__(validated.params._stream, definition.streams);
12221213
if (streamValidated.errors) {
12231214
this.log(req, `Stream Listener Error`, 'error');
12241215
return this.__streamListenerError__(req, res, streamValidated.errors);
12251216
}
12261217
this.log(req, `Begin Server-Sent Event`);
1227-
this.__beginServerSentEvent__(req, res, definition, validated.params);
1218+
this.__beginServerSentEvent__(req, res, definition, validated.params, headers);
12281219
}
12291220

12301221
let context = this.createContext(req, definition, validated.params, data, buffer);
@@ -1241,7 +1232,8 @@ class Gateway extends EventEmitter {
12411232
res,
12421233
definition,
12431234
data,
1244-
functionArgs
1235+
functionArgs,
1236+
headers
12451237
);
12461238
});
12471239

@@ -1317,7 +1309,7 @@ class Gateway extends EventEmitter {
13171309
!this._requestCount && this.emit('empty');
13181310
}
13191311

1320-
__requestHandler__ (req, res, definition, data, functionArgs, context) {
1312+
__requestHandler__ (req, res, definition, data, functionArgs, headers) {
13211313
let nullable = (definition.returns || {}).defaultValue === null;
13221314
this.log(req, `Execution Start`);
13231315
let t = new Date().valueOf();
@@ -1326,9 +1318,7 @@ class Gateway extends EventEmitter {
13261318
definition.format.language &&
13271319
definition.format.language === 'static'
13281320
);
1329-
this.execute(definition, functionArgs, data, (err, value, headers, executionUuid) => {
1330-
headers = headers || {};
1331-
headers['x-execution-uuid'] = executionUuid;
1321+
this.execute(definition, functionArgs, data, headers, (err, value, headers, executionUuid) => {
13321322
let dt = new Date().valueOf() - t;
13331323
err = err === undefined ? null : err;
13341324
// Catch where there is a mismatch
@@ -1713,7 +1703,8 @@ class Gateway extends EventEmitter {
17131703
}
17141704
}
17151705

1716-
execute (definition, functionArgs, data, callback) {
1706+
execute (definition, functionArgs, data, headers, callback) {
1707+
headers = headers || {};
17171708
let fn;
17181709
let complete = false;
17191710
let callbackWrapper = (err, result, headers, executionUuid) => {
@@ -1735,7 +1726,7 @@ class Gateway extends EventEmitter {
17351726
let error = new Error(`Timeout of ${this.defaultTimeout}ms exceeded.`);
17361727
error.timeoutError = true;
17371728
error.fatal = true;
1738-
return callbackWrapper(error, null, null, executionUuid);
1729+
return callbackWrapper(error, null, headers, executionUuid);
17391730
}, this.defaultTimeout);
17401731
let executionUuid = data.context.uuid || uuid.v4();
17411732
if (definition.format.language === 'static') {
@@ -1744,7 +1735,6 @@ class Gateway extends EventEmitter {
17441735
this.preloadFiles[definition.pathname] ||
17451736
fs.readFileSync(path.join(process.cwd(), this.root, definition.pathname))
17461737
);
1747-
let headers = {};
17481738
let statusCode = definition.name.endsWith(':notfound')
17491739
? 404
17501740
: 200;
@@ -1786,7 +1776,7 @@ class Gateway extends EventEmitter {
17861776
return callbackWrapper(
17871777
null,
17881778
{statusCode: statusCode, headers: headers, body: buffer},
1789-
null,
1779+
headers,
17901780
executionUuid
17911781
);
17921782
} else if (definition.format.language === 'nodejs') {
@@ -1804,7 +1794,7 @@ class Gateway extends EventEmitter {
18041794
this._inlineCache[definition.pathname] = fn;
18051795
} catch (e) {
18061796
e.fatal = true;
1807-
return callbackWrapper(e, null, null, executionUuid);
1797+
return callbackWrapper(e, null, headers, executionUuid);
18081798
}
18091799
}
18101800
} else {
@@ -1854,28 +1844,31 @@ class Gateway extends EventEmitter {
18541844
e.value = value;
18551845
}
18561846
e.fatal = true;
1857-
return callbackWrapper(e, null, null, executionUuid);
1847+
return callbackWrapper(e, null, headers, executionUuid);
18581848
}
18591849
}
18601850
// Catch unhandled promise rejections once, starting now.
18611851
// This applies to local testing only.
18621852
process.removeAllListeners('unhandledRejection');
1863-
process.once('unhandledRejection', (err, p) => callbackWrapper(err, null, null, executionUuid));
1853+
process.once('unhandledRejection', (err, p) => callbackWrapper(err, null, headers, executionUuid));
18641854
if (definition.format.async) {
18651855
fn.apply(null, functionArgs)
1866-
.then(result => callbackWrapper(null, result, null, executionUuid))
1856+
.then(result => callbackWrapper(null, result, headers, executionUuid))
18671857
.catch(e => {
18681858
if (!(e instanceof Error)) {
18691859
let value = e;
18701860
e = new Error(e || '');
18711861
e.value = value;
18721862
}
18731863
e.thrown = true;
1874-
callbackWrapper(e, null, null, executionUuid);
1864+
callbackWrapper(e, null, headers, executionUuid);
18751865
});
18761866
} else {
18771867
try {
1878-
fn.apply(null, functionArgs.concat((err, result, headers) => {
1868+
fn.apply(null, functionArgs.concat((err, result, responseHeaders) => {
1869+
Object.keys(responseHeaders || {}).forEach(key => {
1870+
headers[key.toLowerCase()] = responseHeaders[key];
1871+
});
18791872
return callbackWrapper(err, result, headers, executionUuid);
18801873
}));
18811874
} catch (e) {
@@ -1885,11 +1878,16 @@ class Gateway extends EventEmitter {
18851878
e.value = value;
18861879
}
18871880
e.thrown = true;
1888-
return callbackWrapper(e, null, null, executionUuid);
1881+
return callbackWrapper(e, null, headers, executionUuid);
18891882
}
18901883
}
18911884
} else {
1892-
return callbackWrapper(new Error(`Gateway does not support language "${definition.format.language}"`))
1885+
return callbackWrapper(
1886+
new Error(`Gateway does not support language "${definition.format.language}"`),
1887+
null,
1888+
headers,
1889+
executionUuid
1890+
);
18931891
}
18941892
}
18951893

lib/parser/nodejs/validate_parameter_name.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ const babelParser = require('@babel/parser');
22

33
const RESERVED_NAMES = [
44
'_stream',
5+
'_debug',
56
'_bg',
67
'context'
78
];

0 commit comments

Comments
 (0)