Skip to content

Commit

Permalink
Merge pull request #1373 from aligent/fix/always_use_custom_s3_cache_…
Browse files Browse the repository at this point in the history
…module

always use custom s3 cache middleware for better logging
  • Loading branch information
crispy101 authored May 20, 2024
2 parents 677252f + 0c32f0b commit f75110d
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 91 deletions.
175 changes: 85 additions & 90 deletions packages/prerender-fargate/lib/prerender/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,111 +72,106 @@ if (process.env.ENABLE_PRERENDER_HEADER.toLowerCase() === 'true'){
server.use(prerender.sendPrerenderHeader());
}

if (process.env.ENABLE_REDIRECT_CACHE.toLowerCase() === 'true'){
var he = require('he');
var s3 = new (require('aws-sdk')).S3({params:{Bucket: process.env.S3_BUCKET_NAME}});

server.use({
// The requestReceived and pageLoaded functions are a modified version of
// httpHeader plugin - https://github.com/prerender/prerender/blob/478fa6d0a5196ea29c88c69e64e72eb5507b6d2c/lib/plugins/httpHeaders.js combined with
// s3cache plugin - https://github.com/prerender/prerender-aws-s3-cache/blob/98707fa0f787de83aa41583682cd2c2d330a9cca/index.js
requestReceived: function(req, res, next) {
const fetchCachedObject = function (err, result) {
if (!err && result) {
console.log(`Found cached object: ${key}`);
if (result.Metadata.location){
res.setHeader('Location', result.Metadata.location);
}
// default 200 for legacy objects that do not have Metadata.httpreturncode defined
return res.send(result.Metadata.httpreturncode || 200, result.Body);
} else {
console.error(`Fetching cached object from S3 bucket failed with error: ${err.code}`);
var he = require('he');
var s3 = new (require('aws-sdk')).S3({params:{Bucket: process.env.S3_BUCKET_NAME}});

server.use({
// The requestReceived and pageLoaded functions are a modified version of
// httpHeader plugin - https://github.com/prerender/prerender/blob/478fa6d0a5196ea29c88c69e64e72eb5507b6d2c/lib/plugins/httpHeaders.js combined with
// s3cache plugin - https://github.com/prerender/prerender-aws-s3-cache/blob/98707fa0f787de83aa41583682cd2c2d330a9cca/index.js
requestReceived: function(req, res, next) {
const fetchCachedObject = function (err, result) {
if (!err && result) {
console.log(`Found cached object: ${key}`);
if (result.Metadata.location){
res.setHeader('Location', result.Metadata.location);
}
next();
// default 200 for legacy objects that do not have Metadata.httpreturncode defined
return res.send(result.Metadata.httpreturncode || 200, result.Body);
} else {
console.error(`Fetching cached object from S3 bucket failed with error: ${err.code}`);
}
next();
}

if(req.method !== 'GET' && req.method !== 'HEAD') {
return next();
}
if(req.method !== 'GET' && req.method !== 'HEAD') {
return next();
}

var key = req.prerender.url;
var key = req.prerender.url;

if (process.env.S3_PREFIX_KEY) {
key = process.env.S3_PREFIX_KEY + '/' + key;
}
if (process.env.S3_PREFIX_KEY) {
key = process.env.S3_PREFIX_KEY + '/' + key;
}

s3.getObject({
Key: key
}, fetchCachedObject);
}});
s3.getObject({
Key: key
}, fetchCachedObject);
}});

server.use(prerender.removeScriptTags());
server.use(prerender.removeScriptTags());

server.use({
pageLoaded: function(req, res, next) {
const statusCodesToCache = ['200', '301', '302'];
var s3Metadata = {}
const cacheObject = function (err, result) {
if (!err && result) {
console.log(`Cached object ${key} already present. Skipping caching...`);
} else {
console.log(`Caching the object ${req.prerender.url} with statusCode ${req.prerender.statusCode}`);
s3.putObject({
Key: key,
ContentType: 'text/html;charset=UTF-8',
StorageClass: 'REDUCED_REDUNDANCY',
Body: req.prerender.content,
Metadata: s3Metadata
}, function(err, result) {
console.log(result);
if (err) console.error(err);
});
}
server.use({
pageLoaded: function(req, res, next) {
const statusCodesToCache = process.env.ENABLE_REDIRECT_CACHE.toLowerCase() === 'true' ? ['200', '301', '302'] : ['200'];
var s3Metadata = {}
const cacheObject = function (err, result) {
if (!err && result) {
console.log(`Cached object ${key} already present. Skipping caching...`);
} else {
console.log(`Caching the object ${req.prerender.url} with statusCode ${req.prerender.statusCode}`);
s3.putObject({
Key: key,
ContentType: 'text/html;charset=UTF-8',
StorageClass: 'REDUCED_REDUNDANCY',
Body: req.prerender.content,
Metadata: s3Metadata
}, function(err, result) {
console.log(result);
if (err) console.error(err);
});
}
}
// Inspect prerender meta tags and update response accordingly
if (req.prerender.content && req.prerender.renderType == 'html') {
const statusMatchRegex = /<meta[^<>]*(?:name=['"]prerender-status-code['"][^<>]*content=['"]([0-9]{3})['"]|content=['"]([0-9]{3})['"][^<>]*name=['"]prerender-status-code['"])[^<>]*>/i;
const headerMatchRegex = /<meta[^<>]*(?:name=['"]prerender-header['"][^<>]*content=['"]([^'"]*?): ?([^'"]*?)['"]|content=['"]([^'"]*?): ?([^'"]*?)['"][^<>]*name=['"]prerender-header['"])[^<>]*>/gi
const head = req.prerender.content.toString().split('</head>', 1).pop()

const statusMatch = statusMatchRegex.exec(head)
if (statusMatch) {
req.prerender.statusCode = statusMatch[1] || statusMatch[2];
req.prerender.content = req.prerender.content.toString().replace(statusMatch[0], '');
}
// Inspect prerender meta tags and update response accordingly
if (req.prerender.content && req.prerender.renderType == 'html') {
const statusMatchRegex = /<meta[^<>]*(?:name=['"]prerender-status-code['"][^<>]*content=['"]([0-9]{3})['"]|content=['"]([0-9]{3})['"][^<>]*name=['"]prerender-status-code['"])[^<>]*>/i;
const headerMatchRegex = /<meta[^<>]*(?:name=['"]prerender-header['"][^<>]*content=['"]([^'"]*?): ?([^'"]*?)['"]|content=['"]([^'"]*?): ?([^'"]*?)['"][^<>]*name=['"]prerender-header['"])[^<>]*>/gi
const head = req.prerender.content.toString().split('</head>', 1).pop()

const statusMatch = statusMatchRegex.exec(head)
if (statusMatch) {
req.prerender.statusCode = statusMatch[1] || statusMatch[2];
req.prerender.content = req.prerender.content.toString().replace(statusMatch[0], '');
}

let headerMatch = headerMatchRegex.exec(head)
while (headerMatch) {
s3Metadata.location = headerMatch[1].toLowerCase() == 'location' ? he.decode(headerMatch[2] || headerMatch[4]) : '';
res.setHeader(headerMatch[1] || headerMatch[3], s3Metadata.location);
req.prerender.content = req.prerender.content.toString().replace(headerMatch[0], '');
headerMatch = headerMatchRegex.exec(head)
}
let headerMatch = headerMatchRegex.exec(head)
while (headerMatch) {
s3Metadata.location = headerMatch[1].toLowerCase() == 'location' ? he.decode(headerMatch[2] || headerMatch[4]) : '';
res.setHeader(headerMatch[1] || headerMatch[3], s3Metadata.location);
req.prerender.content = req.prerender.content.toString().replace(headerMatch[0], '');
headerMatch = headerMatchRegex.exec(head)
}

if ( statusCodesToCache.includes(req.prerender.statusCode.toString()) ){
s3Metadata.httpreturncode = req.prerender.statusCode.toString()
if ( statusCodesToCache.includes(req.prerender.statusCode.toString()) ){
s3Metadata.httpreturncode = req.prerender.statusCode.toString()

var key = req.prerender.url;
var key = req.prerender.url;

if (process.env.S3_PREFIX_KEY) {
key = process.env.S3_PREFIX_KEY + '/' + key;
}
s3.getObject({
Key: key
}, cacheObject);
} else {
// Skip caching for the http response codes not in the list, such as 404
console.log(`StatusCode ${req.prerender.statusCode} for ${req.prerender.url} is not in the cachable code list. Returning without caching the result.`);
if (process.env.S3_PREFIX_KEY) {
key = process.env.S3_PREFIX_KEY + '/' + key;
}

next();
s3.getObject({
Key: key
}, cacheObject);
} else {
// Skip caching for the http response codes not in the list, such as 404
console.log(`StatusCode ${req.prerender.statusCode} for ${req.prerender.url} is not in the cachable code list. Returning without caching the result.`);
}

next();
}
});
} else {
server.use(prerender.httpHeaders());
server.use(prerender.removeScriptTags());
server.use(s3Cache);
}
}
});


server.start();
2 changes: 1 addition & 1 deletion packages/prerender-fargate/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aligent/cdk-prerender-fargate",
"version": "2.3.5",
"version": "2.3.8",
"description": "A construct to host Prerender in Fargate",
"main": "index.js",
"scripts": {
Expand Down

0 comments on commit f75110d

Please sign in to comment.