Configure redirect routes in Fastly

This commit is contained in:
Ray Schamp 2016-04-19 18:42:03 -04:00
parent b4a7a2884f
commit b8bfe46890
3 changed files with 97 additions and 21 deletions

View file

@ -77,12 +77,17 @@ var getAppRouteCondition = function (pathToStatic, routes, additionalPaths) {
return pathsToCondition(allPaths);
};
var getConditionNameForView = function (view) {
return 'routes/' + view;
var getConditionNameForRoute = function (route, type) {
return 'routes/' + route.pattern + ' (' + type + ')';
};
var getHeaderNameForView = function (view) {
return 'rewrites/' + view;
var getHeaderNameForRoute = function (route) {
if (route.view) return 'rewrites/' + route.view;
if (route.redirect) return 'redirects/' + route.pattern;
};
var getResponseNameForRoute = function (route) {
return 'redirects/' + route.pattern;
};
async.auto({
@ -167,7 +172,7 @@ async.auto({
var conditions = {};
async.forEachOf(routes, function (route, id, cb2) {
var condition = {
name: getConditionNameForView(route.view),
name: getConditionNameForRoute(route, 'request'),
statement: 'req.url ~ "' + route.pattern + '"',
type: 'REQUEST',
priority: id
@ -185,21 +190,60 @@ async.auto({
appRouteHeaders: ['version', 'appRouteRequestConditions', function (cb, results) {
var headers = {};
async.forEachOf(routes, function (route, id, cb2) {
var header = {
name: getHeaderNameForView(route.view),
action: 'set',
ignore_if_set: 0,
type: 'request',
dst: 'url',
src: '"/' + route.view + '.html"',
request_condition: results.appRouteRequestConditions[id].name,
priority: 10
};
fastly.setFastlyHeader(results.version, header, function (err, response) {
if (err) return cb2(err);
headers[id] = response;
cb2(null, response);
});
if (route.redirect) {
async.auto({
responseCondition: function (cb3) {
var condition = {
name: getConditionNameForRoute(route, 'response'),
statement: 'req.url ~ "' + route.pattern + '"',
type: 'RESPONSE',
priority: id
};
fastly.setCondition(results.version, condition, cb3);
},
responseObject: function (cb3) {
var responseObject = {
name: getResponseNameForRoute(route),
status: 301,
response: 'Moved Permanently',
request_condition: getConditionNameForRoute(route, 'request')
};
fastly.setResponseObject(results.version, responseObject, cb3);
},
redirectHeader: ['responseCondition', function (cb3, redirectResults) {
var header = {
name: getHeaderNameForRoute(route),
action: 'set',
ignore_if_set: 0,
type: 'RESPONSE',
dst: 'http.Location',
src: '"' + route.redirect + '"',
response_condition: redirectResults.responseCondition.name
};
fastly.setFastlyHeader(results.version, header, cb3);
}]
}, function (err, redirectResults) {
if (err) return cb2(err);
headers[id] = redirectResults.redirectHeader;
cb2(null, redirectResults);
});
} else {
var header = {
name: getHeaderNameForRoute(route, 'request'),
action: 'set',
ignore_if_set: 0,
type: 'REQUEST',
dst: 'url',
src: '"/' + route.view + '.html"',
request_condition: results.appRouteRequestConditions[id].name,
priority: 10
};
fastly.setFastlyHeader(results.version, header, function (err, response) {
if (err) return cb2(err);
headers[id] = response;
cb2(null, response);
});
}
}, function (err) {
if (err) return cb(err);
cb(null, headers);

View file

@ -110,6 +110,38 @@ module.exports = function (apiKey, serviceId) {
}.bind(this));
};
/*
* setResponseObject: Upsert a Fastly response object
* Attempts to PUT and POSTs if the PUT request is a 404
*
* @param {number} Version number
* @param {object} Response object sent to the API
* @param {callback} Callback for fastly.request
*/
fastly.setResponseObject = function (version, responseObj, cb) {
if (!this.serviceId) {
cb('Failed to set response object. No serviceId configured');
}
var name = responseObj.name;
var putUrl = this.getFastlyAPIPrefix(this.serviceId, version) + '/response_object/' + encodeURIComponent(name);
var postUrl = this.getFastlyAPIPrefix(this.serviceId, version) + '/response_object';
return this.request('PUT', putUrl, responseObj, function (err, response) {
if (err && err.statusCode === 404) {
this.request('POST', postUrl, responseObj, function (err, response) {
if (err) {
return cb('Failed to insert response object: ' + err);
}
return cb(null, response);
});
return;
}
if (err) {
return cb('Failed to update response object: ' + err);
}
return cb(null, response);
}.bind(this));
};
/*
* cloneVersion: Clone a version to create a new version
*

View file

@ -45,7 +45,7 @@
"title": "LEGO WeDo 2.0"
},
{
"pattern": "/info/donate/",
"pattern": "^/info/donate",
"redirect": "https://secure.donationpay.org/scratchfoundation/"
}
]