DEV: Add `--forward-host` option to `bin/ember-cli` (#17244)
This allows to e.g. test multisite setup in a local dev environment. Also fixes some minor proxy issues.
This commit is contained in:
parent
39a025c7af
commit
16f22e3c36
|
@ -8,6 +8,8 @@ const path = require("path");
|
|||
const { promises: fs } = require("fs");
|
||||
const { JSDOM } = require("jsdom");
|
||||
const { shouldLoadPluginTestJs } = require("discourse/lib/plugin-js");
|
||||
const { Buffer } = require("node:buffer");
|
||||
const { cwd, env } = require("node:process");
|
||||
|
||||
// via https://stackoverflow.com/a/6248722/165668
|
||||
function generateUID() {
|
||||
|
@ -202,7 +204,7 @@ async function applyBootstrap(bootstrap, template, response, baseURL, preload) {
|
|||
async function buildFromBootstrap(proxy, baseURL, req, response, preload) {
|
||||
try {
|
||||
const template = await fs.readFile(
|
||||
path.join(process.cwd(), "dist", "index.html"),
|
||||
path.join(cwd(), "dist", "index.html"),
|
||||
"utf8"
|
||||
);
|
||||
|
||||
|
@ -221,8 +223,23 @@ async function buildFromBootstrap(proxy, baseURL, req, response, preload) {
|
|||
}
|
||||
|
||||
async function handleRequest(proxy, baseURL, req, res) {
|
||||
const originalHost = req.headers["x-forwarded-host"] || req.headers.host;
|
||||
req.headers.host = new URL(proxy).host;
|
||||
// x-forwarded-host is used in e.g. GitHub CodeSpaces
|
||||
let originalHost = req.headers["x-forwarded-host"] || req.headers.host;
|
||||
|
||||
if (env["FORWARD_HOST"] === "true") {
|
||||
if (/^localhost(\:|$)/.test(originalHost)) {
|
||||
// Can't access default site in multisite via "localhost", redirect to 127.0.0.1
|
||||
res.redirect(
|
||||
307,
|
||||
`http://${originalHost.replace("localhost", "127.0.0.1")}${req.path}`
|
||||
);
|
||||
return;
|
||||
} else {
|
||||
req.headers.host = originalHost;
|
||||
}
|
||||
} else {
|
||||
req.headers.host = new URL(proxy).host;
|
||||
}
|
||||
|
||||
if (req.headers["Origin"]) {
|
||||
req.headers["Origin"] = req.headers["Origin"]
|
||||
|
@ -270,34 +287,39 @@ async function handleRequest(proxy, baseURL, req, res) {
|
|||
`http://${originalHost}/assets/`,
|
||||
`http://${originalHost}/ember-cli-live-reload.js`,
|
||||
`http://${originalHost}/_lr/`,
|
||||
];
|
||||
].join(" ");
|
||||
|
||||
const newCSP = csp
|
||||
.replace(new RegExp(proxy, "g"), `http://${originalHost}`)
|
||||
.replace(
|
||||
new RegExp("script-src ", "g"),
|
||||
`script-src ${emberCliAdditions.join(" ")} `
|
||||
);
|
||||
.replaceAll(proxy, `http://${originalHost}`)
|
||||
.replaceAll("script-src ", `script-src ${emberCliAdditions}`);
|
||||
|
||||
res.set("content-security-policy", newCSP);
|
||||
}
|
||||
|
||||
const contentType = response.headers.get("content-type");
|
||||
const isHTML = contentType && contentType.startsWith("text/html");
|
||||
const responseText = await response.text();
|
||||
const preloadJson = isHTML ? extractPreloadJson(responseText) : null;
|
||||
const isHTML = contentType?.startsWith("text/html");
|
||||
|
||||
if (preloadJson) {
|
||||
const html = await buildFromBootstrap(
|
||||
proxy,
|
||||
baseURL,
|
||||
req,
|
||||
response,
|
||||
extractPreloadJson(responseText)
|
||||
);
|
||||
res.set("content-type", "text/html");
|
||||
res.send(html);
|
||||
res.status(response.status);
|
||||
|
||||
if (isHTML) {
|
||||
const responseText = await response.text();
|
||||
const preloadJson = isHTML ? extractPreloadJson(responseText) : null;
|
||||
|
||||
if (preloadJson) {
|
||||
const html = await buildFromBootstrap(
|
||||
proxy,
|
||||
baseURL,
|
||||
req,
|
||||
response,
|
||||
extractPreloadJson(responseText)
|
||||
);
|
||||
res.set("content-type", "text/html");
|
||||
res.send(html);
|
||||
} else {
|
||||
res.send(responseText);
|
||||
}
|
||||
} else {
|
||||
res.status(response.status);
|
||||
res.send(responseText);
|
||||
res.send(Buffer.from(await response.arrayBuffer()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -308,7 +330,7 @@ module.exports = {
|
|||
return true;
|
||||
},
|
||||
|
||||
contentFor: function (type, config) {
|
||||
contentFor(type, config) {
|
||||
if (shouldLoadPluginTestJs() && type === "test-plugin-js") {
|
||||
return `
|
||||
<script src="${config.rootURL}assets/discourse/tests/active-plugins.js"></script>
|
||||
|
@ -339,8 +361,11 @@ to serve API requests. For example:
|
|||
|
||||
app.use(rawMiddleware, async (req, res, next) => {
|
||||
try {
|
||||
if (this.shouldHandleRequest(req)) {
|
||||
if (this.shouldForwardRequest(req)) {
|
||||
await handleRequest(proxy, baseURL, req, res);
|
||||
} else {
|
||||
// Fixes issues when using e.g. "localhost" instead of loopback IP address
|
||||
req.headers.host = "127.0.0.1";
|
||||
}
|
||||
} catch (error) {
|
||||
res.send(`
|
||||
|
@ -357,28 +382,19 @@ to serve API requests. For example:
|
|||
});
|
||||
},
|
||||
|
||||
shouldHandleRequest(request) {
|
||||
if (request.path === "/tests/index.html") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (request.get("Accept") && request.get("Accept").includes("text/html")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const contentType = request.get("Content-Type");
|
||||
if (!contentType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
shouldForwardRequest(request) {
|
||||
if (
|
||||
contentType.includes("application/x-www-form-urlencoded") ||
|
||||
contentType.includes("multipart/form-data") ||
|
||||
contentType.includes("application/json")
|
||||
["/tests/index.html", "/ember-cli-live-reload.js", "/testem.js"].includes(
|
||||
request.path
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
if (request.path.startsWith("/_lr/")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
|
|
@ -6,8 +6,8 @@ require 'pathname'
|
|||
RAILS_ROOT = File.expand_path("../../", Pathname.new(__FILE__).realpath)
|
||||
PORT = ENV["UNICORN_PORT"] ||= "3000"
|
||||
HOSTNAME = ENV["DISCOURSE_HOSTNAME"] ||= "127.0.0.1"
|
||||
yarn_dir = File.join(RAILS_ROOT, "app/assets/javascripts/discourse")
|
||||
|
||||
YARN_DIR = File.join(RAILS_ROOT, "app/assets/javascripts/discourse")
|
||||
CUSTOM_ARGS = ["--try", "--test", "--unicorn", "-u", "--forward-host"]
|
||||
PROXY =
|
||||
if ARGV.include?("--try")
|
||||
"https://try.discourse.org"
|
||||
|
@ -38,19 +38,22 @@ if ARGV.include?("-h") || ARGV.include?("--help")
|
|||
puts "#{"--test".cyan} To run the test suite"
|
||||
puts "#{"--unicorn, -u".cyan} To run a unicorn server as well"
|
||||
puts "The rest of the arguments are passed to ember server per:", ""
|
||||
exec "yarn -s --cwd #{yarn_dir} run ember #{command} --help"
|
||||
exec "yarn -s --cwd #{YARN_DIR} run ember #{command} --help"
|
||||
end
|
||||
|
||||
args = ["-s", "--cwd", yarn_dir, "run", "ember", command] + ARGV.reject do |a|
|
||||
["--try", "--test", "--unicorn", "-u"].include?(a)
|
||||
end
|
||||
args = ["-s", "--cwd", YARN_DIR, "run", "ember", command] + (ARGV - CUSTOM_ARGS)
|
||||
|
||||
if !args.include?("test") && !args.include?("--proxy")
|
||||
args << "--proxy"
|
||||
args << PROXY
|
||||
end
|
||||
|
||||
exit 1 if !system "yarn -s install --cwd #{yarn_dir}"
|
||||
exit 1 if !system "yarn -s install --cwd #{YARN_DIR}"
|
||||
|
||||
yarn_env = {}
|
||||
if ARGV.include?("--forward-host")
|
||||
yarn_env["FORWARD_HOST"] = "true"
|
||||
end
|
||||
|
||||
if ARGV.include?("-u") || ARGV.include?("--unicorn")
|
||||
unicorn_env = { "DISCOURSE_PORT" => ENV["DISCOURSE_PORT"] || "4200" }
|
||||
|
@ -58,7 +61,7 @@ if ARGV.include?("-u") || ARGV.include?("--unicorn")
|
|||
|
||||
Thread.new do
|
||||
require 'open3'
|
||||
Open3.popen2e("yarn", *args.to_a.flatten) do |i, oe, t|
|
||||
Open3.popen2e(yarn_env, "yarn", *args.to_a.flatten) do |i, oe, t|
|
||||
puts "Ember CLI running on PID: #{t.pid}"
|
||||
oe.each do |line|
|
||||
if line.include?("\e[32m200\e") || line.include?("\e[36m304\e[0m") || line.include?("POST /message-bus")
|
||||
|
@ -77,5 +80,5 @@ if ARGV.include?("-u") || ARGV.include?("--unicorn")
|
|||
|
||||
Process.wait(unicorn_pid)
|
||||
else
|
||||
exec "yarn", *args.to_a.flatten
|
||||
exec(yarn_env, "yarn", *args.to_a.flatten)
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue