Skip to content

Commit 5b6429d

Browse files
authored
Merge pull request dougmoscrop#1 from eelayoubi/feature/create-lambda-edge-type-for-aws
feat: add lambda edge origin request to AWS
2 parents 11cd9ef + 53491ad commit 5b6429d

18 files changed

+327
-17
lines changed
File renamed without changes.

lib/provider/aws/create-request.js renamed to lib/provider/aws/api-gw/create-request.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
const URL = require('url');
44

5-
const Request = require('../../request');
5+
const Request = require('../../../request');
66

77
function requestMethod(event) {
88
if (event.version === '2.0') {

lib/provider/aws/format-response.js renamed to lib/provider/aws/api-gw/format-response.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22

33
const isBinary = require('./is-binary');
4-
const Response = require('../../response');
4+
const Response = require('../../../response');
55
const sanitizeHeaders = require('./sanitize-headers');
66

77
module.exports = (event, response, options) => {

lib/provider/aws/api-gw/index.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const cleanUpEvent = require('./clean-up-event');
2+
3+
const createRequest = require('./create-request');
4+
const formatResponse = require('./format-response');
5+
6+
module.exports = options => {
7+
return getResponse => async (event_, context = {}) => {
8+
const event = cleanUpEvent(event_, options);
9+
10+
const request = createRequest(event, options);
11+
const response = await getResponse(request, event, context);
12+
13+
return formatResponse(event, response, options);
14+
};
15+
};
File renamed without changes.
File renamed without changes.

lib/provider/aws/index.js

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
1-
const cleanUpEvent = require('./clean-up-event');
2-
3-
const createRequest = require('./create-request');
4-
const formatResponse = require('./format-response');
1+
const apiGw = require('./api-gw');
2+
const lambdaEdgeOriginRequest = require('./lambda-edge-origin-request');
53

64
module.exports = options => {
7-
return getResponse => async (event_, context = {}) => {
8-
const event = cleanUpEvent(event_, options);
9-
10-
const request = createRequest(event, options);
11-
const response = await getResponse(request, event, context);
12-
13-
return formatResponse(event, response, options);
14-
};
5+
if (options.type === 'lambda-edge-origin-request') {
6+
return lambdaEdgeOriginRequest(options)
7+
} else {
8+
return apiGw(options)
9+
}
1510
};
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
'use strict';
2+
3+
function getPath({ uri }) {
4+
return typeof uri === 'string' ? uri : '/';
5+
}
6+
7+
module.exports = function cleanupEvent(evt, options) {
8+
const event = (evt &&
9+
evt.Records &&
10+
evt.Records.length > 0 &&
11+
evt.Records[0].cf) ||
12+
{};
13+
14+
event.config = event.config || {};
15+
16+
event.request = event.request || {};
17+
event.request.body = event.request.body || '';
18+
event.request.headers = event.request.headers || {};
19+
event.request.method = event.request.method || 'GET';
20+
event.request.uri = getPath(event.request);
21+
22+
if (options.basePath) {
23+
const basePathIndex = event.path.indexOf(options.basePath);
24+
25+
if (basePathIndex > -1) {
26+
event.path = event.path.substr(basePathIndex + options.basePath.length);
27+
}
28+
}
29+
30+
return event;
31+
};
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
'use strict';
2+
3+
const crypto = require('crypto');
4+
const Request = require('../../../request');
5+
6+
function requestHeaders(event) {
7+
let headers = Object.keys(event.request.headers).reduce((headers, key) => {
8+
headers[event.request.headers[key][0].key.toLowerCase()] = event.request.headers[key][0].value;
9+
return headers;
10+
}, {});
11+
12+
headers['x-request-id'] = crypto.randomBytes(30).toString('base64')
13+
14+
return headers;
15+
}
16+
17+
function requestBody(event) {
18+
const type = typeof event.request.body;
19+
const body = event && event.request && event.request.body;
20+
21+
if (!body) return '';
22+
23+
if (Buffer.isBuffer(event.request.body.data)) {
24+
return event.request.body.data;
25+
} else if (type === 'string') {
26+
return Buffer.from(event.request.body.data, event.request.body.encoding === 'base64' ? 'base64' : 'utf8');
27+
} else if (type === 'object') {
28+
return Buffer.from(JSON.stringify(event.request.body.data));
29+
}
30+
31+
throw new Error(`Unexpected event.body type: ${typeof event.request.body.data}`);
32+
}
33+
34+
function getUrl(path, queryString) {
35+
if (queryString) {
36+
return `${path}?${queryString}`
37+
}
38+
39+
return path;
40+
}
41+
42+
module.exports = (event, options) => {
43+
const method = event.request.method;
44+
const remoteAddress = event.request.clientIp;
45+
const headers = requestHeaders(event);
46+
const body = requestBody(event);
47+
48+
if (typeof options.requestId === 'string' && options.requestId.length > 0) {
49+
const header = options.requestId.toLowerCase();
50+
headers[header] = headers[header] || event.config.requestId;
51+
}
52+
53+
const req = new Request({
54+
method,
55+
headers,
56+
body,
57+
remoteAddress,
58+
url: getUrl(event.request.uri, event.request.querystring)
59+
});
60+
61+
return req;
62+
};
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict';
2+
const http = require('http');
3+
4+
const isBinary = require('./is-binary');
5+
const Response = require('../../../response');
6+
const sanitizeHeaders = require('./sanitize-headers');
7+
8+
module.exports = (response, options) => {
9+
const { statusCode } = response;
10+
const headers = Response.headers(response);
11+
12+
if (headers['transfer-encoding'] === 'chunked' || response.chunkedEncoding) {
13+
throw new Error('chunked encoding not supported');
14+
}
15+
16+
const isBase64Encoded = isBinary(headers, options);
17+
const encoding = isBase64Encoded ? 'base64' : 'utf8';
18+
let body = Response.body(response).toString(encoding);
19+
20+
return {
21+
status: statusCode.toString(),
22+
statusDescription: http.STATUS_CODES[statusCode],
23+
headers: sanitizeHeaders(headers),
24+
body,
25+
bodyEncoding: isBase64Encoded ? 'base64' : 'text'
26+
};
27+
};

0 commit comments

Comments
 (0)