serverless-express
serverless-express copied to clipboard
serverless-express callback request
s3(image) + cloudfront + lambda@edge I'm only processing image requests from users authenticated with vanilla http.
*** vanilla-http
xxx.cloudfront.net/image.png
const authUtil = require("./middlewares/auth");
exports.handler = (event, context, callback) => { const { request, response } = event.Records[0].cf;
result = authUtil(request);
if(result.success) {
callback(null, request);
}
};
// This works well. (image download)
serverless-express
router.get('/:file', async (req, res) => { const { event, context } = getCurrentInvoke() const eventRequest = event.Records[0].cf.request;
res.json(eventRequest) });
// not working
{"clientIp":"000.000.000.000","headers":{"host":[{"key":"Host","value":"dl78camcjz7wt.cloudfront.net"}],"user-agent":[{"key":"User-Agent","value":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36"}],"
I need help to solve this problem.
@brettstack do you know how this can be done? to summarise the issue and what I understand the question here to be, basically how do you return the request object in Lambda@Edge so that the request passes through to the origin (viewer/origin request events) instead of express returning a response to the client
possible solution using the legacy succeed method of the context which is accessible via getCurrentInvoke
const { getCurrentInvoke } = require('@vendia/serverless-express')
const currentInvoke = getCurrentInvoke()
currentInvoke.context.succeed(currentInvoke.event.Records[0].cf.request)
@robgott I can confirm that this works for the s3 origin purpose from cloudfront through lambda@edge origin request integration.
Getting the lambda context via getCurrentInvoke()
and subsequently calling context.succeed()
with the event would break the abstraction in the route handler of using express request/response model.
An alternative approach is to internally use one of the esoteric HTTP response codes to signal the lambda handler that the request should be passed on to the cloudfront origin.
const routeHandler = async (req, res) => {
if (...) {
// forward the request to the origin
res
.status(203)
.end();
return;
}
// express handler returns a response
res
.status(200)
.send(...);
}
const app = express();
configureApplication(app);
const serverlessExpressHandler = serverlessExpress({ app });
export const handler = async (event, context) => {
const result = await serverlessExpressHandler(event, context);
if (result.status == 203) {
return event.Records[0].cf.request;
}
return result;
}