UNPKG

polyserve

Version:
95 lines 3.46 kB
"use strict"; /** * @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