const http = require('http') module.exports = function serverless(app) { return async function handler(event) { const method = String(event.httpMethod || event.method || 'GET').toUpperCase() const path = event.path || '/' const headers = event.headers || {} const qs = event.queryStringParameters || {} const qsStr = Object.keys(qs).map(k => encodeURIComponent(k) + '=' + encodeURIComponent(qs[k])).join('&') const url = path + (qsStr ? '?' + qsStr : '') let rawBody = event.body || '' if (event.isBase64Encoded && rawBody) { rawBody = Buffer.from(rawBody, 'base64') } else if (typeof rawBody === 'string') { rawBody = Buffer.from(rawBody, 'utf8') } return new Promise((resolve) => { const req = new http.IncomingMessage() req.method = method req.url = url req.headers = {} Object.keys(headers).forEach(k => { req.headers[k.toLowerCase()] = headers[k] }) if (event.requestContext && event.requestContext.sourceIp) { req.headers['x-forwarded-for'] = req.headers['x-forwarded-for'] || event.requestContext.sourceIp } if (rawBody.length > 0) { req.headers['content-length'] = String(rawBody.length) } const res = new http.ServerResponse(req) let body = '' const resHeaders = {} res.writeHead = function (statusCode, reasonOrHeaders, maybeHeaders) { res.statusCode = statusCode const h = maybeHeaders || (typeof reasonOrHeaders === 'object' ? reasonOrHeaders : {}) Object.assign(resHeaders, h) } const originalSetHeader = res.setHeader.bind(res) res.setHeader = function (name, value) { resHeaders[name.toLowerCase()] = value originalSetHeader(name, value) } res.end = function (chunk) { if (chunk) body += chunk resolve({ isBase64Encoded: false, statusCode: res.statusCode || 200, headers: Object.assign({ 'content-type': 'application/json; charset=utf-8' }, resHeaders), body }) } res.write = function (chunk) { body += chunk } if (rawBody.length > 0) { req.push(rawBody) } req.push(null) app(req, res) }) } }