Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/packager proxy #1932

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 28 additions & 6 deletions gulpfile.js/packager.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@ const {join} = require('path');
const {sh} = require('@lib/utils/sh.js');
const mri = require('mri');

// Parse commandline arguments
const argv = mri(process.argv.slice(2));

const PACKAGER_ROOT = join(__dirname, '../packager');
const opts = {
workingDir: PACKAGER_ROOT,
};

// Parse commandline arguments
const argv = mri(process.argv.slice(2));
const host = argv.host || 'https://amp.dev';


/**
* Deploys packager to app engine.
*/
Expand All @@ -38,23 +40,43 @@ async function packagerDeploy() {
});
};

/**
* Runs the packager docker image locally.
*/
async function packagerRunLocal() {
const password = argv.password || process.env.AMP_DEV_CERT_PWD;
await sh('pwd', opts);
await sh('docker build -t amppkg .', opts);
return await sh(`docker run -p 8083:8080 --env PASSWORD=${password} amppkg`, opts);
}

/**
* Runs amp-linter checks. Change the host via `--host=https://example.com`.
*/
function packagerTest() {
return sh('curl -si --output - -H "amp-cache-transform: google" -H "accept: application/signed-exchange;v=b3;q=0.9,*/*;q=0.8" "https://amp-dev-staging.appspot.com/index.amp.html"');
return sh(`npx amp-toolbox-linter --force sxg "${host}/index.amp.html`);
}

/**
* Prints the OSCP certificate data. Use it to check the cert's expiration date. Change the host
* via `--host=https://example.com`. Requires https://github.com/dflemstr/rq to be installed.
*/
function packagerTestOSCP() {
const host = argv.host || 'https://amp.dev';
return sh(`curl -s "${host}/amppkg/cert/lWfYk-0jeC_HkleYD4fj98y6GixIjocIkMpjsB8dToA"` +
'| rq -q -c "get \"[1].ocsp\"" | tr -d \" | xxd -r -p ' +
'| openssl ocsp -respin /dev/stdin -text -noverify');
}

/**
* Prints the packager logs to the commandline.
*/
function packagerLog() {
return sh('gcloud app logs tail -s default --project amp-dev-sxg');
}


exports.packagerDeploy = packagerDeploy;
exports.packagerRunLocal = packagerRunLocal;
exports.packagerTest = packagerTest;
exports.packager = packagerTestOSCP;
exports.packagerLog = packagerLog;
exports.packagerTest = packagerTest;
33 changes: 22 additions & 11 deletions platform/lib/routers/packager.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@

const HttpProxy = require('http-proxy');
const config = require('@lib/config');

const proxy = HttpProxy.createProxyServer();

const proxyOptions = {
// The domain serving the web package
const PACKAGED_DOMAIN = 'https://amp.dev';

// Proxy configuration, `target` is the packager domain
const PROXY_OPTIONS = {
target: config.hosts.packager.base,
changeOrigin: true,
};
Expand All @@ -32,42 +35,50 @@ const proxyOptions = {
* - If the URL starts with /amppkg/, forward the request unmodified.
* - If the URL points to an AMP page and the AMP-Cache-Transform request header is present,
* rewrite the URL by prepending /priv/doc and forward the request.
* - Set the vary when serving AMP documents
* - Set the vary header when serving AMP documents
*
* See https://github.com/ampproject/amppackager#productionizing
*/
const packager = (request, response, next) => {
// Redirect all packager requests
// Redirect all requests targeted at the packager
if (request.path.startsWith('/amppkg/')) {
sxgProxy(request, response, request.url, next);
// Add a timestamp to bust potential caches (temporary fix for #1921)
const requestUrl = new URL(request.url, 'https://example.com');
const timestamp = new Date().getTime();
requestUrl.searchParams.set(timestamp, '');
// Proxy request to packager
sxgProxy(request, response, requestUrl.pathname + requestUrl.search, next);
return;
}
// Don't package non valid AMP pages
// Don't package non-valid AMP pages, which is in our case
// determined by the `.amp.` postfix
if (!request.path.endsWith('.amp.html')) {
next();
return;
}
// Tell browsers that we support SXG
response.set('vary', 'Accept, AMP-Cache-Transform');
// Ignore all non AMP cache requests
if (!request.header('amp-cache-transform')) {
next();
return;
}
// Hard-code amp.dev as it has to match the cert
// Construct the packager request URL
const searchParams = new URLSearchParams({
sign: 'https://amp.dev' + request.url,
sign: PACKAGED_DOMAIN + request.url,
}).toString();
const url = `/priv/doc?${searchParams}`;
// Serve webpackage via packager
sxgProxy(request, response, url, next);
};

function sxgProxy(request, response, url, next) {
console.log('[packager] proxy', url);
console.log('[packager] proxy', PROXY_OPTIONS.target + url);
request.url = url;
proxy.web(request, response, proxyOptions, (error) => {
proxy.web(request, response, PROXY_OPTIONS, (error) => {
console.error(error);
// let the normal request handler deal with it (serve a page or a 404)
// Let the normal request handler handle the request, which either serves
// the non-packaged version or a 404
next();
});
}
Expand Down