diff --git a/lib/serve.js b/lib/serve.js index d40b9e0e..b39413e3 100644 --- a/lib/serve.js +++ b/lib/serve.js @@ -1,16 +1,16 @@ -var express = require('express'); -var bodyParser = require('body-parser'); -var expressLogging = require('express-logging'); -var queryString = require('querystring'); -var path = require('path'); -var conf = require('./config'); -var jwtDecode = require('jwt-decode'); +var express = require("express"); +var bodyParser = require("body-parser"); +var expressLogging = require("express-logging"); +var queryString = require("querystring"); +var path = require("path"); +var conf = require("./config"); +var jwtDecode = require("jwt-decode"); function handleErr(err, response) { response.statusCode = 500; - response.write('Function invocation failed: ' + err.toString()); + response.write("Function invocation failed: " + err.toString()); response.end(); - console.log('Error during invocation: ', err); + console.log("Error during invocation: ", err); return; } @@ -40,12 +40,12 @@ function createCallback(response) { if (lambdaResponse.body) { response.write( lambdaResponse.isBase64Encoded - ? Buffer.from(lambdaResponse.body, 'base64') + ? Buffer.from(lambdaResponse.body, "base64") : lambdaResponse.body ); } else { if ( - process.env.CONTEXT !== 'production' || + process.env.CONTEXT !== "production" || !process.env.SILENCE_EMPTY_LAMBDA_WARNING ) console.log( @@ -59,8 +59,8 @@ function createCallback(response) { function promiseCallback(promise, callback) { if (!promise) return; - if (typeof promise.then !== 'function') return; - if (typeof callback !== 'function') return; + if (typeof promise.then !== "function") return; + if (typeof callback !== "function") return; return promise.then( function(data) { @@ -74,16 +74,16 @@ function promiseCallback(promise, callback) { function buildClientContext(headers) { // inject a client context based on auth header https://github.com/netlify/netlify-lambda/pull/57 - if (!headers['authorization']) return; + if (!headers["authorization"]) return; - const parts = headers['authorization'].split(' '); - if (parts.length !== 2 || parts[0] !== 'Bearer') return; + const parts = headers["authorization"].split(" "); + if (parts.length !== 2 || parts[0] !== "Bearer") return; try { return { identity: { - url: 'NETLIFY_LAMBDA_LOCALLY_EMULATED_IDENTITY_URL', - token: 'NETLIFY_LAMBDA_LOCALLY_EMULATED_IDENTITY_TOKEN' + url: "NETLIFY_LAMBDA_LOCALLY_EMULATED_IDENTITY_URL", + token: "NETLIFY_LAMBDA_LOCALLY_EMULATED_IDENTITY_TOKEN" }, user: jwtDecode(parts[1]) }; @@ -95,11 +95,21 @@ function buildClientContext(headers) { function createHandler(dir, static, timeout) { return function(request, response) { // handle proxies without path re-writes (http-servr) - var cleanPath = request.path.replace(/^\/.netlify\/functions/, ''); - - var func = cleanPath.split('/').filter(function(e) { - return e; - })[0]; + var cleanPath = request.path.replace(/^\/.netlify\/functions/, ""); + + var func = cleanPath.split("/").filter(e => !!e)[0]; + if (typeof func === "undefined") { + console.error( + `Something went wrong and the function path derived from ${cleanPath} (raw form: ${ + request.path + }) was undefined. Please doublecheck your function naming and toml configuration.` + ); + } + if (typeof dir === "undefined") { + console.error( + `Something went wrong and the function directory ${dir} was undefined. Please doublecheck your toml configuration.` + ); + } var module = path.join(process.cwd(), dir, func); if (static) { delete require.cache[require.resolve(module)]; @@ -114,7 +124,7 @@ function createHandler(dir, static, timeout) { var isBase64 = request.body && - !(request.headers['content-type'] || '').match( + !(request.headers["content-type"] || "").match( /text|application|multipart\/form-data/ ); var lambdaRequest = { @@ -123,7 +133,7 @@ function createHandler(dir, static, timeout) { queryStringParameters: queryString.parse(request.url.split(/\?(.+)/)[1]), headers: request.headers, body: isBase64 - ? Buffer.from(request.body.toString(), 'utf8').toString('base64') + ? Buffer.from(request.body.toString(), "utf8").toString("base64") : request.body, isBase64Encoded: isBase64 }; @@ -163,22 +173,29 @@ exports.listen = function(port, static, timeout) { var config = conf.load(); var app = express(); var dir = config.build.functions || config.build.Functions; - app.use(bodyParser.raw({ limit: '6mb' })); - app.use(bodyParser.text({ limit: '6mb', type: '*/*' })); + app.use(bodyParser.raw({ limit: "6mb" })); + app.use(bodyParser.text({ limit: "6mb", type: "*/*" })); app.use( expressLogging(console, { - blacklist: ['/favicon.ico'] + blacklist: ["/favicon.ico"] }) ); - app.get('/favicon.ico', function(req, res) { + app.get("/favicon.ico", function(req, res) { res.status(204).end(); }); - app.all('*', createHandler(dir, static, timeout)); + app.get("/", function(req, res) { + res + .status(404) + .send( + `You have requested the root of http://localhost:${port}. This is likely a mistake. netlify-lambda serves functions at htttp://localhost:${port}/.netlify/functions/your-function-name, please fix your code.` + ); + }); + app.all("*", createHandler(dir, static, timeout)); app.listen(port, function(err) { if (err) { - console.error('Unable to start lambda server: ', err); + console.error("Unable to start lambda server: ", err); process.exit(1); }