diff --git a/samples/node-headless-ssr-proxy/config.js b/samples/node-headless-ssr-proxy/config.js index ba86f0d987..27286d49e7 100644 --- a/samples/node-headless-ssr-proxy/config.js +++ b/samples/node-headless-ssr-proxy/config.js @@ -1,4 +1,5 @@ const fs = require('fs'); +const keepAlive = require("agentkeepalive"); const ipaddr = require('ipaddr.js'); const fetch = require('node-fetch'); const NodeCache = require('node-cache'); @@ -19,8 +20,36 @@ const bundlePath = process.env.SITECORE_JSS_SERVER_BUNDLE || `./dist/${appName}/ const serverBundle = require(bundlePath); +const apiHost = process.env.SITECORE_API_HOST || 'http://my.sitecore.host' + appName = appName || serverBundle.appName; +/** + * Enable connection pooling. Adds `connection: keep-alive` header + * @param {string} apiHost sitecore api host + */ +const keepAliveAgent = (apiHost) => { + const keepAliveConfig = { + maxSockets: 100, + maxFreeSockets: 10, + timeout: 240 * 1000, + freeSocketTimeout: 240 * 1000, + }; + + if (!apiHost) { + throw new Error("[KEEP-ALIVE-CONFIG] SITECORE_API_HOST value is required, but was undefined") + } + + if (!apiHost.indexOf("http://")) return new keepAlive(keepAliveConfig); + + if (!apiHost.indexOf("https://")) return new keepAlive.HttpsAgent(keepAliveConfig); + + throw new Error( + "[KEEP-ALIVE-CONFIG] Unexpected SITECORE_API_HOST value, expected http:// or https://, but was " + + apiHost + ); +} + /** * @type {ProxyConfig} */ @@ -34,7 +63,7 @@ const config = { * Should be https for production. Must be https to use SSC auth service, * if supporting Sitecore authentication. */ - apiHost: process.env.SITECORE_API_HOST || 'http://my.sitecore.host', + apiHost, /** * layoutServiceRoot: The path to layout service for the JSS application. * Some apps, like advanced samples, use a custom LS configuration, @@ -82,6 +111,8 @@ const config = { * Options object for http-proxy-middleware. Consult its docs. */ proxyOptions: { + // Enable connection pooling + agent: keepAliveAgent(apiHost), // Setting this to false will disable SSL certificate validation // when proxying to a SSL Sitecore instance. // This is a major security issue, so NEVER EVER set this to false diff --git a/samples/node-headless-ssr-proxy/package-lock.json b/samples/node-headless-ssr-proxy/package-lock.json index 17be3c71d6..e07be2dd76 100644 --- a/samples/node-headless-ssr-proxy/package-lock.json +++ b/samples/node-headless-ssr-proxy/package-lock.json @@ -4,6 +4,16 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@sitecore-jss/sitecore-jss-proxy": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@sitecore-jss/sitecore-jss-proxy/-/sitecore-jss-proxy-14.0.1.tgz", + "integrity": "sha512-knwtkVP6vhYl5P1YFCdy2jIf6s2S05m2FBtGGdxSbcwmVY2mzIcOQzZcLBr+qj+teFGWJKdRyGNZOnx15tj74Q==", + "requires": { + "http-proxy-middleware": "^0.20.0", + "http-status-codes": "^1.3.2", + "set-cookie-parser": "^2.2.1" + } + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -13,6 +23,31 @@ "negotiator": "0.6.2" } }, + "agentkeepalive": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.1.3.tgz", + "integrity": "sha512-wn8fw19xKZwdGPO47jivonaHRTd+nGOMP1z11sgGeQzDy2xd5FG0R67dIMcKHDE2cJ5y+YXV30XVGUBPRSY7Hg==", + "requires": { + "debug": "^4.1.0", + "depd": "^1.1.2", + "humanize-ms": "^1.2.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -35,6 +70,14 @@ "type-is": "~1.6.16" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -125,6 +168,11 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, + "eventemitter3": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", + "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==" + }, "express": { "version": "4.16.4", "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", @@ -162,6 +210,14 @@ "vary": "~1.1.2" } }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, "finalhandler": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", @@ -176,6 +232,11 @@ "unpipe": "~1.0.0" } }, + "follow-redirects": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.12.1.tgz", + "integrity": "sha512-tmRv0AVuR7ZyouUHLeNSiO6pqulF7dYa3s19c6t+wz9LD69/uSzdMxJ2S91nTI9U3rt/IldxpzMOFejp6f0hjg==" + }, "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", @@ -197,6 +258,40 @@ "statuses": ">= 1.4.0 < 2" } }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-middleware": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.20.0.tgz", + "integrity": "sha512-dNJAk71nEJhPiAczQH9hGvE/MT9kEs+zn2Dh+Hi94PGZe1GluQirC7mw5rdREUtWx6qGS1Gu0bZd4qEAg+REgw==", + "requires": { + "http-proxy": "^1.17.0", + "is-glob": "^4.0.1", + "lodash": "^4.17.14", + "micromatch": "^4.0.2" + } + }, + "http-status-codes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-1.4.0.tgz", + "integrity": "sha512-JrT3ua+WgH8zBD3HEJYbeEgnuQaAnUeRRko/YojPAJjGmIfGD3KPU/asLdsLwKjfxOmQe5nXMQ0pt/7MyapVbQ==" + }, + "humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", + "requires": { + "ms": "^2.0.0" + } + }, "iconv-lite": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", @@ -215,6 +310,24 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.1.tgz", "integrity": "sha1-+kt5+kf9Pe9eOxWYJRYcClGclCc=" }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", @@ -235,6 +348,15 @@ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, "mime": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", @@ -300,6 +422,11 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" + }, "proxy-addr": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", @@ -337,6 +464,11 @@ "unpipe": "1.0.0" } }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -378,6 +510,11 @@ "send": "0.16.2" } }, + "set-cookie-parser": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.4.6.tgz", + "integrity": "sha512-mNCnTUF0OYPwYzSHbdRdCfNNHqrne+HS5tS5xNb6yJbdP9wInV0q5xPLE0EyfV/Q3tImo3y/OXpD8Jn0Jtnjrg==" + }, "setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", @@ -388,6 +525,14 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", diff --git a/samples/node-headless-ssr-proxy/package.json b/samples/node-headless-ssr-proxy/package.json index f83a6a81a0..f2c4606b76 100644 --- a/samples/node-headless-ssr-proxy/package.json +++ b/samples/node-headless-ssr-proxy/package.json @@ -26,6 +26,7 @@ "license": "Apache-2.0", "dependencies": { "@sitecore-jss/sitecore-jss-proxy": "^14.0.1", + "agentkeepalive": "^4.1.3", "compression": "~1.7.3", "express": "~4.16.4", "ipaddr.js": "~1.8.1",