polyserve
Version:
A simple dev server for bower components
95 lines • 3.46 kB
JavaScript
/**
* @license
* Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
const fs = require("fs");
const mime = require("mime");
const path = require("path");
/** h2 push manifest cache */
const _pushManifest = {};
/**
* Asserts file existence for all specified files in a push-manifest
* @param root path to root directory
* @param manifest manifest object
*/
function assertValidManifest(root, manifest) {
function assertExists(filename) {
const fname = path.join(root, filename);
try {
// Ignore root path, since that always exists for the router
if (filename !== '/') {
assert(fs.existsSync(fname), `not found: ${fname}`);
}
}
catch (err) {
throw new Error(`invalid h2-push manifest: ${err}`);
}
}
for (const refFile of Object.keys(manifest)) {
assertExists(refFile);
for (const pushFile of Object.keys(manifest[refFile])) {
assertExists(pushFile);
}
}
}
/**
* Reads a push-manifest from the specified path, or a cached version
* of the file
* @param root path to root directory
* @param manifestPath path to manifest file
* @returns the manifest
*/
function getPushManifest(root, manifestPath) {
if (!_pushManifest[manifestPath]) {
const data = fs.readFileSync(manifestPath);
const manifest = JSON.parse(data.toString());
assertValidManifest(root, manifest);
_pushManifest[manifestPath] = manifest;
}
return _pushManifest[manifestPath];
}
exports.getPushManifest = getPushManifest;
/**
* Pushes any resources for the requested file
* @param options server options
* @param req HTTP request
* @param res HTTP response
*/
function pushResources(options, req, res) {
if (res.push && options.protocol === 'h2' && options.pushManifestPath &&
!req.get('x-is-push')) {
// TODO: Handle preload link headers
const pushManifest = getPushManifest(options.root, options.pushManifestPath);
const resources = pushManifest[req.path];
if (resources) {
const root = options.root;
for (const filename of Object.keys(resources)) {
const stream = res.push(filename, {
request: { accept: '*/*' },
response: {
'content-type': mime.getType(filename),
// Add an X-header to the pushed request so we
// don't trigger pushes for pushes
'x-is-push': 'true'
}
})
.on('error', (err) => console.error('failed to push', filename, err));
fs.createReadStream(path.join(root, filename)).pipe(stream);
}
}
}
}
exports.pushResources = pushResources;
//# sourceMappingURL=push.js.map
;