В фокусе нашей компании произошел общий сдвиг по мере того, как мы отказываемся от обслуживания контента из корзин S3 согласно следующим вопросам для обсуждения:
Теперь вместо этого мы хотим обслуживать его из другого места, внутреннего / внешнего маршрута, в котором находится веб-сайт. Шаги следующие:
Пользователь переходит на adoring-elion-23496793.ourwebsite.com (где adoring-elion-23496793 - название их веб-сайта).
Внутри лямбда-функции выполняется вызов API: https://us-central1-ourwebsite-dev.cloudfunctions.net/getWebsiteIdByName/adoring-elion-23496793
Это возвращает websiteId лямбда-функции в формате, например: { "websiteId": "0e7bzyt5IcGPMtX9wKzn" }
Затем функция Lambda принимает websiteId и обслуживает контент из URL-адреса. ourwebsite.com/websites/0e7bzyt5IcGPMtX9wKzn
к adoring-elion-23496793.ourwebsite.com
Я считаю, что для этого уже есть шаги, например: jolly-kepler-12154838.ourwebsite.com
в настоящее время обслуживает контент в локации корзины S3. Как мне обновить эту функцию, чтобы она обслуживалась исключительно из поддомена? Я думаю, что потребуется изменить только функцию Lambda, однако я не уверен, как вызвать наш API, получить данные и использовать их для обслуживания контента:
'use strict';
// if the end of incoming Host header matches this string,
// strip this part and prepend the remaining characters onto the request path,
// along with a new leading slash (otherwise, the request will be handled
// with an unmodified path, at the root of the bucket)
const remove_suffix = '.ourwebsite.com';
// provide the correct origin hostname here so that we send the correct
// Host header to the S3 website endpoint
const origin_hostname = 'apps.ourwebsite.com.s3.amazonaws.com'; // see comments, below
exports.handler = (event, context, callback) => {
const request = event.Records[0].cf.request;
const headers = request.headers;
const host_header = headers.host[0].value;
if(host_header.endsWith(remove_suffix))
{
// prepend '/' + the subdomain onto the existing request path ("uri")
request.uri = '/' + host_header.substring(0,host_header.length - remove_suffix.length) + request.uri;
}
// fix the host header so that S3 understands the request
headers.host[0].value = origin_hostname;
// return control to CloudFront with the modified request
return callback(null,request);
};
С тех пор я обновил лямбда-функцию до следующего:
'use strict';
const remove_suffix = '.ourwebsite.com';
const origin_hostname = 'ourwebsite.com/website/';
const redirect_api = 'us-central1-ourwebsite.cloudfunctions.net'
const https = require('https');
exports.handler = (event, context, callback) => {
const request = event.Records[0].cf.request;
const headers = request.headers;
const host_header = headers.host[0].value;
if(host_header.endsWith(remove_suffix)) {
const website_name = host_header.substring(0,host_header.length - remove_suffix.length);
httprequest(website_name).then((data) => {
const response = {
statusCode: 200,
body: data
};
const website_id = response['body']['websiteId'];
if (website_id) {
console.log('Corresponding website id found: ' + website_id);
request.uri = '/' + website_id;
} else {
console.log('Corresponding website id not found');
}
});
}
headers.host[0].value = origin_hostname;
return callback(null,request);
};
function httprequest(website_name) {
return new Promise((resolve, reject) => {
const options = {
host: redirect_api,
path: '/getWebsiteIdByName/' + website_name,
port: 443,
method: 'GET'
};
const req = https.request(options, (res) => {
if (res.statusCode < 200 || res.statusCode >= 300) {
return reject(new Error('statusCode=' + res.statusCode));
}
var body = [];
res.on('data', function(chunk) {
body.push(chunk);
});
res.on('end', function() {
try {
body = JSON.parse(Buffer.concat(body).toString());
} catch(e) {
reject(e);
}
resolve(body);
});
});
req.on('error', (e) => {
reject(e.message);
});
req.end();
});
}
Каждый раз, когда я посещаю URL-адрес в https://test.mywebsite.com/
, Я получаю сообщение об ошибке:
502 ERROR
The request could not be satisfied.
The Lambda function result failed validation: The header contains invalid characters. We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
Generated by cloudfront (CloudFront)
Request ID: ivbaTst7dgcnOxlv7QxDOMzBncDCvvNb-MBpl0ukBCciP97NzGuQJw==
Есть идеи, как лучше всего подойти к этому?