From 7941460749ca02c4ce5d74b372f596fdacfe200e Mon Sep 17 00:00:00 2001 From: Prince Mendiratta Date: Fri, 17 Feb 2023 02:16:28 +0530 Subject: [PATCH 01/10] map api request to host Signed-off-by: Prince Mendiratta --- config/webpack/webpack.dev.js | 2 ++ src/CONST.js | 4 +++ src/libs/HttpUtils.js | 10 +++++--- src/libs/shouldUseStagingServer/index.js | 13 ---------- .../shouldUseStagingServer/index.native.js | 13 ---------- web/proxy.js | 25 +++++++++++-------- 6 files changed, 27 insertions(+), 40 deletions(-) delete mode 100644 src/libs/shouldUseStagingServer/index.js delete mode 100644 src/libs/shouldUseStagingServer/index.native.js diff --git a/config/webpack/webpack.dev.js b/config/webpack/webpack.dev.js index 0b48c4e5f35a..926dcd0bcc1a 100644 --- a/config/webpack/webpack.dev.js +++ b/config/webpack/webpack.dev.js @@ -21,6 +21,8 @@ module.exports = (env = {}) => portfinder.getPortPromise({port: BASE_PORT}) : { proxy: { '/api': 'http://[::1]:9000', + '/staging-api': 'http://[::1]:9000', + '/staging-secure-api': 'http://[::1]:9000', '/chat-attachments': 'http://[::1]:9000', }, }; diff --git a/src/CONST.js b/src/CONST.js index accd263483f4..effc12f92a57 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -1189,6 +1189,10 @@ const CONST = { SAMPLE_INPUT: '123456.789', EXPECTED_OUTPUT: 'FCFA 123,457', }, + API_MAP: { + STAGING: 'staging-', + STAGING_SECURE: 'staging-secure-', + }, }; export default CONST; diff --git a/src/libs/HttpUtils.js b/src/libs/HttpUtils.js index 5fedc22f4d56..e9b5c758d05d 100644 --- a/src/libs/HttpUtils.js +++ b/src/libs/HttpUtils.js @@ -5,7 +5,6 @@ import CONFIG from '../CONFIG'; import CONST from '../CONST'; import ONYXKEYS from '../ONYXKEYS'; import HttpsError from './Errors/HttpsError'; -import shouldUseStagingServer from './shouldUseStagingServer'; import getPlatform from './getPlatform'; // Desktop and web use staging config too so we we should default to staging API endpoint if on those platforms @@ -109,10 +108,13 @@ function xhr(command, data, type = CONST.NETWORK.METHOD.POST, shouldUseSecure = let apiRoot = shouldUseSecure ? CONFIG.EXPENSIFY.SECURE_EXPENSIFY_URL : CONFIG.EXPENSIFY.URL_API_ROOT; - if (shouldUseStagingServer(stagingServerToggleState)) { - apiRoot = shouldUseSecure ? CONFIG.EXPENSIFY.STAGING_SECURE_EXPENSIFY_URL : CONFIG.EXPENSIFY.STAGING_EXPENSIFY_URL; + if (stagingServerToggleState) { + if (CONFIG.EXPENSIFY.URL_API_ROOT === '/') { + apiRoot += shouldUseSecure ? CONST.API_MAP.STAGING_SECURE : CONST.API_MAP.STAGING; + } else { + apiRoot = shouldUseSecure ? CONFIG.EXPENSIFY.STAGING_SECURE_EXPENSIFY_URL : CONFIG.EXPENSIFY.STAGING_EXPENSIFY_URL; + } } - return processHTTPRequest(`${apiRoot}api?command=${command}`, type, formData, data.canCancel); } diff --git a/src/libs/shouldUseStagingServer/index.js b/src/libs/shouldUseStagingServer/index.js deleted file mode 100644 index 745dd03b4489..000000000000 --- a/src/libs/shouldUseStagingServer/index.js +++ /dev/null @@ -1,13 +0,0 @@ -import CONFIG from '../../CONFIG'; - -/** - * Helper method used to decide which API endpoint to call - * - * @param {Boolean} stagingServerToggleState - * @returns {Boolean} - */ -function shouldUseStagingServer(stagingServerToggleState) { - return CONFIG.IS_IN_STAGING && stagingServerToggleState; -} - -export default shouldUseStagingServer; diff --git a/src/libs/shouldUseStagingServer/index.native.js b/src/libs/shouldUseStagingServer/index.native.js deleted file mode 100644 index 92baff89c835..000000000000 --- a/src/libs/shouldUseStagingServer/index.native.js +++ /dev/null @@ -1,13 +0,0 @@ -import * as Environment from '../Environment/Environment'; - -/** - * Helper method used to decide which API endpoint to call in the Native apps. - * We build the staging native apps with production env config so we cannot rely on those values, - * hence we will decide solely on the value of the shouldUseStagingServer value (always false in production). - * - * @param {Boolean} stagingServerToggleState - * @returns {Boolean} - */ -export default function shouldUseStagingServer(stagingServerToggleState) { - return !Environment.isDevelopment() && stagingServerToggleState; -} diff --git a/web/proxy.js b/web/proxy.js index 768963d0810c..aa0daefeb19d 100644 --- a/web/proxy.js +++ b/web/proxy.js @@ -1,5 +1,6 @@ const http = require('http'); const https = require('https'); +const lodashGet = require('lodash/get'); require('dotenv').config(); if (process.env.USE_WEB_PROXY === 'false') { @@ -7,15 +8,16 @@ if (process.env.USE_WEB_PROXY === 'false') { process.exit(); } -let host = 'www.expensify.com'; - -// If we are testing against the staging API then we must use the correct host here or nothing with work. -if (/staging/.test(process.env.EXPENSIFY_URL)) { - host = 'staging.expensify.com'; -} +const host = new URL(lodashGet(process.env.EXPENSIFY_URL, 'EXPENSIFY_URL', 'https://www.expensify.com')).hostname; +const stagingHost = new URL(lodashGet(process.env.STAGING_EXPENSIFY_URL, 'STAGING_EXPENSIFY_URL', 'https://staging.expensify.com')).hostname; +const stagingSecureHost = new URL(lodashGet(process.env.STAGING_SECURE_EXPENSIFY_URL, 'STAGING_SECURE_EXPENSIFY_URL', 'https://staging-secure.expensify.com')).hostname; +const HOST_MAP = { + 'staging-api': stagingHost, + 'staging-secure-api': stagingSecureHost, +}; // eslint-disable-next-line no-console -console.log(`Creating proxy with host: ${host}`); +console.log(`Creating proxy with host: ${host} for production API and ${stagingHost} for staging API`); /** * Local proxy server that hits the production endpoint @@ -24,13 +26,16 @@ console.log(`Creating proxy with host: ${host}`); * environment that has no local API. */ const server = http.createServer((request, response) => { + const apiRegex = /\/(.*api)/g; + const apiRoot = apiRegex.exec(request.url)[1]; + const hostname = HOST_MAP[apiRoot] || host; const proxyRequest = https.request({ - hostname: host, + hostname, method: 'POST', - path: request.url, + path: request.url.replace(apiRoot, 'api'), headers: { ...request.headers, - host, + host: hostname, 'user-agent': request.headers['user-agent'].concat(' Development-NewDot/1.0'), }, port: 443, From 7d383932033fd64bcdb75aff661e20bb71311f18 Mon Sep 17 00:00:00 2001 From: Prince Mendiratta Date: Fri, 17 Feb 2023 02:20:51 +0530 Subject: [PATCH 02/10] comments Signed-off-by: Prince Mendiratta --- src/libs/HttpUtils.js | 1 + web/proxy.js | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/libs/HttpUtils.js b/src/libs/HttpUtils.js index e9b5c758d05d..d77f6e1a1e68 100644 --- a/src/libs/HttpUtils.js +++ b/src/libs/HttpUtils.js @@ -109,6 +109,7 @@ function xhr(command, data, type = CONST.NETWORK.METHOD.POST, shouldUseSecure = let apiRoot = shouldUseSecure ? CONFIG.EXPENSIFY.SECURE_EXPENSIFY_URL : CONFIG.EXPENSIFY.URL_API_ROOT; if (stagingServerToggleState) { + // If web proxy is used, URL will always be / if (CONFIG.EXPENSIFY.URL_API_ROOT === '/') { apiRoot += shouldUseSecure ? CONST.API_MAP.STAGING_SECURE : CONST.API_MAP.STAGING; } else { diff --git a/web/proxy.js b/web/proxy.js index aa0daefeb19d..f9c2e19b6095 100644 --- a/web/proxy.js +++ b/web/proxy.js @@ -26,12 +26,15 @@ console.log(`Creating proxy with host: ${host} for production API and ${stagingH * environment that has no local API. */ const server = http.createServer((request, response) => { + // regex not declared globally to reset internal regex pointer for each request const apiRegex = /\/(.*api)/g; const apiRoot = apiRegex.exec(request.url)[1]; const hostname = HOST_MAP[apiRoot] || host; const proxyRequest = https.request({ hostname, method: 'POST', + + // replace the mapping url with the actual path path: request.url.replace(apiRoot, 'api'), headers: { ...request.headers, From 6dd53408be2474795290b73159220bbbb4085164 Mon Sep 17 00:00:00 2001 From: Prince Mendiratta Date: Tue, 28 Feb 2023 01:59:06 +0530 Subject: [PATCH 03/10] account for chat attachments on proxy Signed-off-by: Prince Mendiratta --- web/proxy.js | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/web/proxy.js b/web/proxy.js index f9c2e19b6095..687942746663 100644 --- a/web/proxy.js +++ b/web/proxy.js @@ -26,16 +26,27 @@ console.log(`Creating proxy with host: ${host} for production API and ${stagingH * environment that has no local API. */ const server = http.createServer((request, response) => { - // regex not declared globally to reset internal regex pointer for each request - const apiRegex = /\/(.*api)/g; - const apiRoot = apiRegex.exec(request.url)[1]; - const hostname = HOST_MAP[apiRoot] || host; + let hostname = host; + let requestPath = request.url; + + // regex not declared globally to avoid internal regex pointer reset for each request + // We only match for staging related root since default host is prod + const apiRegex = /\/(staging.*api)/g; + const apiRootMatch = apiRegex.exec(request.url); + + // Switch host only if API call, not on chat attachments + if (apiRootMatch) { + const apiRoot = apiRootMatch[1]; + hostname = HOST_MAP[apiRoot]; + + // replace the mapping url with the actual path + requestPath = request.url.replace(apiRoot, 'api'); + } const proxyRequest = https.request({ hostname, method: 'POST', - // replace the mapping url with the actual path - path: request.url.replace(apiRoot, 'api'), + path: requestPath, headers: { ...request.headers, host: hostname, From 2ad74537e76dd230ee5a1007884df3d047dc94d7 Mon Sep 17 00:00:00 2001 From: Prince Mendiratta Date: Tue, 28 Feb 2023 17:13:45 +0530 Subject: [PATCH 04/10] redundant newline Signed-off-by: Prince Mendiratta --- web/proxy.js | 1 - 1 file changed, 1 deletion(-) diff --git a/web/proxy.js b/web/proxy.js index 687942746663..8068b16d5dd9 100644 --- a/web/proxy.js +++ b/web/proxy.js @@ -45,7 +45,6 @@ const server = http.createServer((request, response) => { const proxyRequest = https.request({ hostname, method: 'POST', - path: requestPath, headers: { ...request.headers, From 0f92967e830705782119b31d17394af669a271c4 Mon Sep 17 00:00:00 2001 From: Prince Mendiratta Date: Tue, 28 Feb 2023 17:59:42 +0530 Subject: [PATCH 05/10] remove use of lodash Signed-off-by: Prince Mendiratta --- web/proxy.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/web/proxy.js b/web/proxy.js index 8068b16d5dd9..37e30aebd73f 100644 --- a/web/proxy.js +++ b/web/proxy.js @@ -1,16 +1,14 @@ const http = require('http'); const https = require('https'); -const lodashGet = require('lodash/get'); require('dotenv').config(); if (process.env.USE_WEB_PROXY === 'false') { process.stdout.write('Skipping proxy as USE_WEB_PROXY was set to false.\n'); process.exit(); } - -const host = new URL(lodashGet(process.env.EXPENSIFY_URL, 'EXPENSIFY_URL', 'https://www.expensify.com')).hostname; -const stagingHost = new URL(lodashGet(process.env.STAGING_EXPENSIFY_URL, 'STAGING_EXPENSIFY_URL', 'https://staging.expensify.com')).hostname; -const stagingSecureHost = new URL(lodashGet(process.env.STAGING_SECURE_EXPENSIFY_URL, 'STAGING_SECURE_EXPENSIFY_URL', 'https://staging-secure.expensify.com')).hostname; +const host = new URL(process.env.EXPENSIFY_URL || 'https://www.expensify.com').hostname; +const stagingHost = new URL(process.env.STAGING_EXPENSIFY_URL || 'https://staging.expensify.com').hostname; +const stagingSecureHost = new URL(process.env.STAGING_SECURE_EXPENSIFY_URL || 'https://staging-secure.expensify.com').hostname; const HOST_MAP = { 'staging-api': stagingHost, 'staging-secure-api': stagingSecureHost, From 9cb02b530075f7f2d966ee8e28a2e5eb3b4b7dfb Mon Sep 17 00:00:00 2001 From: Prince Mendiratta Date: Wed, 1 Mar 2023 09:23:16 +0530 Subject: [PATCH 06/10] explain the proxy map design Signed-off-by: Prince Mendiratta --- src/CONFIG.js | 1 + src/libs/HttpUtils.js | 8 ++++---- web/proxy.js | 21 +++++++++++++++++---- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/CONFIG.js b/src/CONFIG.js index 2dd63730b84c..63d4c94b4719 100644 --- a/src/CONFIG.js +++ b/src/CONFIG.js @@ -78,4 +78,5 @@ export default { DEV_PORT: process.env.PORT || 8080, E2E_TESTING: lodashGet(Config, 'E2E_TESTING', 'false') === 'true', SEND_CRASH_REPORTS: lodashGet(Config, 'SEND_CRASH_REPORTS', 'false') === 'true', + IS_USING_WEB_PROXY: expensifyComWithProxy === '/', }; diff --git a/src/libs/HttpUtils.js b/src/libs/HttpUtils.js index d77f6e1a1e68..28228aece9e8 100644 --- a/src/libs/HttpUtils.js +++ b/src/libs/HttpUtils.js @@ -9,10 +9,10 @@ import getPlatform from './getPlatform'; // Desktop and web use staging config too so we we should default to staging API endpoint if on those platforms const shouldDefaultToStaging = _.contains([CONST.PLATFORM.WEB, CONST.PLATFORM.DESKTOP], getPlatform()); -let stagingServerToggleState = false; +let shouldUseStagingServer = false; Onyx.connect({ key: ONYXKEYS.USER, - callback: val => stagingServerToggleState = lodashGet(val, 'shouldUseStagingServer', shouldDefaultToStaging), + callback: val => shouldUseStagingServer = lodashGet(val, 'shouldUseStagingServer', shouldDefaultToStaging), }); let shouldFailAllRequests = false; @@ -108,9 +108,9 @@ function xhr(command, data, type = CONST.NETWORK.METHOD.POST, shouldUseSecure = let apiRoot = shouldUseSecure ? CONFIG.EXPENSIFY.SECURE_EXPENSIFY_URL : CONFIG.EXPENSIFY.URL_API_ROOT; - if (stagingServerToggleState) { + if (shouldUseStagingServer) { // If web proxy is used, URL will always be / - if (CONFIG.EXPENSIFY.URL_API_ROOT === '/') { + if (CONFIG.IS_USING_WEB_PROXY) { apiRoot += shouldUseSecure ? CONST.API_MAP.STAGING_SECURE : CONST.API_MAP.STAGING; } else { apiRoot = shouldUseSecure ? CONFIG.EXPENSIFY.STAGING_SECURE_EXPENSIFY_URL : CONFIG.EXPENSIFY.STAGING_EXPENSIFY_URL; diff --git a/web/proxy.js b/web/proxy.js index 37e30aebd73f..905a68b90d9e 100644 --- a/web/proxy.js +++ b/web/proxy.js @@ -27,17 +27,30 @@ const server = http.createServer((request, response) => { let hostname = host; let requestPath = request.url; - // regex not declared globally to avoid internal regex pointer reset for each request - // We only match for staging related root since default host is prod + // Regex not declared globally to avoid internal regex pointer reset for each request. const apiRegex = /\/(staging.*api)/g; + + /** + * We only match staging api root to redirect requests to the staging server if the request + * is an API call, instead of chat attachments. By default, requests are sent to the prod server. + * For example, + * /api?command=OpenReport => request sent to production server + * /staging-api?command=OpenReport => request sent to staging server + * /staging-secure-api?command=OpenReport => request sent to secure staging server + * /chat-attachments/46545... => request sent to production server + */ const apiRootMatch = apiRegex.exec(request.url); - // Switch host only if API call, not on chat attachments + // Switch host only if API call, not on chat attachments. if (apiRootMatch) { const apiRoot = apiRootMatch[1]; hostname = HOST_MAP[apiRoot]; - // replace the mapping url with the actual path + /** + * Replace the mapping url with the actual path. + * This is done because the staging api root is only intended for the proxy, + * the actual server request must use the /api path. + */ requestPath = request.url.replace(apiRoot, 'api'); } const proxyRequest = https.request({ From f971b8037d8cc2989f2173b3b003b3cf72a9237e Mon Sep 17 00:00:00 2001 From: Prince Mendiratta Date: Wed, 1 Mar 2023 09:28:16 +0530 Subject: [PATCH 07/10] remove redundant comment Signed-off-by: Prince Mendiratta --- src/libs/HttpUtils.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/HttpUtils.js b/src/libs/HttpUtils.js index 28228aece9e8..9281b26e8d33 100644 --- a/src/libs/HttpUtils.js +++ b/src/libs/HttpUtils.js @@ -109,7 +109,6 @@ function xhr(command, data, type = CONST.NETWORK.METHOD.POST, shouldUseSecure = let apiRoot = shouldUseSecure ? CONFIG.EXPENSIFY.SECURE_EXPENSIFY_URL : CONFIG.EXPENSIFY.URL_API_ROOT; if (shouldUseStagingServer) { - // If web proxy is used, URL will always be / if (CONFIG.IS_USING_WEB_PROXY) { apiRoot += shouldUseSecure ? CONST.API_MAP.STAGING_SECURE : CONST.API_MAP.STAGING; } else { From bd27ca33239484e6f147ee97f023d9b214dbc139 Mon Sep 17 00:00:00 2001 From: Prince Mendiratta Date: Thu, 2 Mar 2023 00:36:16 +0530 Subject: [PATCH 08/10] make use of a proxyConfig Signed-off-by: Prince Mendiratta --- config/proxyConfig.js | 9 +++++++++ src/CONFIG.js | 2 +- src/CONST.js | 4 ---- src/libs/HttpUtils.js | 3 ++- web/proxy.js | 17 ++++++++--------- 5 files changed, 20 insertions(+), 15 deletions(-) create mode 100644 config/proxyConfig.js diff --git a/config/proxyConfig.js b/config/proxyConfig.js new file mode 100644 index 000000000000..0af64857d7bc --- /dev/null +++ b/config/proxyConfig.js @@ -0,0 +1,9 @@ +/** + * These are the base API root used to send requests to the proxy. + * We only specify for staging URLs as API requests are sent to the production + * servers by default. + */ +module.exports = { + STAGING: '/staging-', + STAGING_SECURE: '/staging-secure-', +}; diff --git a/src/CONFIG.js b/src/CONFIG.js index 63d4c94b4719..f6db312b7a19 100644 --- a/src/CONFIG.js +++ b/src/CONFIG.js @@ -78,5 +78,5 @@ export default { DEV_PORT: process.env.PORT || 8080, E2E_TESTING: lodashGet(Config, 'E2E_TESTING', 'false') === 'true', SEND_CRASH_REPORTS: lodashGet(Config, 'SEND_CRASH_REPORTS', 'false') === 'true', - IS_USING_WEB_PROXY: expensifyComWithProxy === '/', + IS_USING_WEB_PROXY: getPlatform() === 'web' && useWebProxy, }; diff --git a/src/CONST.js b/src/CONST.js index effc12f92a57..accd263483f4 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -1189,10 +1189,6 @@ const CONST = { SAMPLE_INPUT: '123456.789', EXPECTED_OUTPUT: 'FCFA 123,457', }, - API_MAP: { - STAGING: 'staging-', - STAGING_SECURE: 'staging-secure-', - }, }; export default CONST; diff --git a/src/libs/HttpUtils.js b/src/libs/HttpUtils.js index 9281b26e8d33..0aa379f6b633 100644 --- a/src/libs/HttpUtils.js +++ b/src/libs/HttpUtils.js @@ -6,6 +6,7 @@ import CONST from '../CONST'; import ONYXKEYS from '../ONYXKEYS'; import HttpsError from './Errors/HttpsError'; import getPlatform from './getPlatform'; +import proxyConfig from '../../config/proxyConfig'; // Desktop and web use staging config too so we we should default to staging API endpoint if on those platforms const shouldDefaultToStaging = _.contains([CONST.PLATFORM.WEB, CONST.PLATFORM.DESKTOP], getPlatform()); @@ -110,7 +111,7 @@ function xhr(command, data, type = CONST.NETWORK.METHOD.POST, shouldUseSecure = if (shouldUseStagingServer) { if (CONFIG.IS_USING_WEB_PROXY) { - apiRoot += shouldUseSecure ? CONST.API_MAP.STAGING_SECURE : CONST.API_MAP.STAGING; + apiRoot = shouldUseSecure ? proxyConfig.STAGING_SECURE : proxyConfig.STAGING; } else { apiRoot = shouldUseSecure ? CONFIG.EXPENSIFY.STAGING_SECURE_EXPENSIFY_URL : CONFIG.EXPENSIFY.STAGING_EXPENSIFY_URL; } diff --git a/web/proxy.js b/web/proxy.js index 905a68b90d9e..407b3c72a7d3 100644 --- a/web/proxy.js +++ b/web/proxy.js @@ -1,5 +1,6 @@ const http = require('http'); const https = require('https'); +const proxyConfig = require('../config/proxyConfig'); require('dotenv').config(); if (process.env.USE_WEB_PROXY === 'false') { @@ -9,10 +10,6 @@ if (process.env.USE_WEB_PROXY === 'false') { const host = new URL(process.env.EXPENSIFY_URL || 'https://www.expensify.com').hostname; const stagingHost = new URL(process.env.STAGING_EXPENSIFY_URL || 'https://staging.expensify.com').hostname; const stagingSecureHost = new URL(process.env.STAGING_SECURE_EXPENSIFY_URL || 'https://staging-secure.expensify.com').hostname; -const HOST_MAP = { - 'staging-api': stagingHost, - 'staging-secure-api': stagingSecureHost, -}; // eslint-disable-next-line no-console console.log(`Creating proxy with host: ${host} for production API and ${stagingHost} for staging API`); @@ -28,30 +25,32 @@ const server = http.createServer((request, response) => { let requestPath = request.url; // Regex not declared globally to avoid internal regex pointer reset for each request. - const apiRegex = /\/(staging.*api)/g; + const apiRegex = /(\/staging.*)api/g; /** * We only match staging api root to redirect requests to the staging server if the request - * is an API call, instead of chat attachments. By default, requests are sent to the prod server. + * is an API call, except chat attachments. By default, requests are sent to the prod server. * For example, * /api?command=OpenReport => request sent to production server * /staging-api?command=OpenReport => request sent to staging server * /staging-secure-api?command=OpenReport => request sent to secure staging server * /chat-attachments/46545... => request sent to production server */ - const apiRootMatch = apiRegex.exec(request.url); + const apiRootMatch = apiRegex.exec(requestPath); // Switch host only if API call, not on chat attachments. if (apiRootMatch) { const apiRoot = apiRootMatch[1]; - hostname = HOST_MAP[apiRoot]; + + // apiRoot can only be staging or secure staging + hostname = apiRoot === proxyConfig.STAGING ? stagingHost : stagingSecureHost; /** * Replace the mapping url with the actual path. * This is done because the staging api root is only intended for the proxy, * the actual server request must use the /api path. */ - requestPath = request.url.replace(apiRoot, 'api'); + requestPath = request.url.replace(apiRoot, '/'); } const proxyRequest = https.request({ hostname, From 030cbb20297134746e4f86e2dcd914effcb848c2 Mon Sep 17 00:00:00 2001 From: Prince Mendiratta Date: Thu, 2 Mar 2023 16:59:49 +0530 Subject: [PATCH 09/10] secure/non secure staging check update Signed-off-by: Prince Mendiratta --- web/proxy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/proxy.js b/web/proxy.js index 407b3c72a7d3..b7993d0fd019 100644 --- a/web/proxy.js +++ b/web/proxy.js @@ -43,7 +43,7 @@ const server = http.createServer((request, response) => { const apiRoot = apiRootMatch[1]; // apiRoot can only be staging or secure staging - hostname = apiRoot === proxyConfig.STAGING ? stagingHost : stagingSecureHost; + hostname = apiRoot === proxyConfig.STAGING_SECURE ? stagingSecureHost : stagingHost; /** * Replace the mapping url with the actual path. From 7323183b30f58f4623c0b2614edb1833742a8df1 Mon Sep 17 00:00:00 2001 From: Prince Mendiratta Date: Fri, 3 Mar 2023 23:06:34 +0530 Subject: [PATCH 10/10] avoid regex matching Signed-off-by: Prince Mendiratta --- web/proxy.js | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/web/proxy.js b/web/proxy.js index b7993d0fd019..4dc1a1018c13 100644 --- a/web/proxy.js +++ b/web/proxy.js @@ -24,34 +24,25 @@ const server = http.createServer((request, response) => { let hostname = host; let requestPath = request.url; - // Regex not declared globally to avoid internal regex pointer reset for each request. - const apiRegex = /(\/staging.*)api/g; - /** - * We only match staging api root to redirect requests to the staging server if the request - * is an API call, except chat attachments. By default, requests are sent to the prod server. + * When a request is matching a proxy config path we might direct it to a different host (e.g. staging) + * For requests matching proxy config patterns we replace the mapping url (prefix) with the actual path. + * This is done because the staging api root is only intended for the proxy, + * the actual server request must use the /api path. * For example, * /api?command=OpenReport => request sent to production server * /staging-api?command=OpenReport => request sent to staging server * /staging-secure-api?command=OpenReport => request sent to secure staging server * /chat-attachments/46545... => request sent to production server */ - const apiRootMatch = apiRegex.exec(requestPath); - - // Switch host only if API call, not on chat attachments. - if (apiRootMatch) { - const apiRoot = apiRootMatch[1]; - - // apiRoot can only be staging or secure staging - hostname = apiRoot === proxyConfig.STAGING_SECURE ? stagingSecureHost : stagingHost; - - /** - * Replace the mapping url with the actual path. - * This is done because the staging api root is only intended for the proxy, - * the actual server request must use the /api path. - */ - requestPath = request.url.replace(apiRoot, '/'); + if (request.url.startsWith(proxyConfig.STAGING_SECURE)) { + hostname = stagingSecureHost; + requestPath = request.url.replace(proxyConfig.STAGING_SECURE, '/'); + } else if (request.url.startsWith(proxyConfig.STAGING)) { + hostname = stagingHost; + requestPath = request.url.replace(proxyConfig.STAGING, '/'); } + const proxyRequest = https.request({ hostname, method: 'POST',