Skip to content

Commit

Permalink
fix: proxy logging and allow to pass options without the target opt…
Browse files Browse the repository at this point in the history
…ion (#3651)
  • Loading branch information
alexander-akait committed Aug 16, 2021
1 parent c9ccc96 commit 6e2cbde
Show file tree
Hide file tree
Showing 2 changed files with 224 additions and 33 deletions.
77 changes: 45 additions & 32 deletions lib/Server.js
Expand Up @@ -492,8 +492,12 @@ class Server {
* }
*/
if (typeof options.proxy !== "undefined") {
// TODO remove in the next major release, only accept `Array`
if (!Array.isArray(options.proxy)) {
if (Object.prototype.hasOwnProperty.call(options.proxy, "target")) {
if (
Object.prototype.hasOwnProperty.call(options.proxy, "target") ||
Object.prototype.hasOwnProperty.call(options.proxy, "router")
) {
options.proxy = [options.proxy];
} else {
options.proxy = Object.keys(options.proxy).map((context) => {
Expand All @@ -513,38 +517,42 @@ class Server {
proxyOptions.context = correctedContext;
}

const getLogLevelForProxy = (level) => {
if (level === "none") {
return "silent";
}
return proxyOptions;
});
}
}

if (level === "log") {
return "info";
}
options.proxy = options.proxy.map((item) => {
const getLogLevelForProxy = (level) => {
if (level === "none") {
return "silent";
}

if (level === "verbose") {
return "debug";
}
if (level === "log") {
return "info";
}

return level;
};
if (level === "verbose") {
return "debug";
}

if (typeof proxyOptions.logLevel === "undefined") {
proxyOptions.logLevel = getLogLevelForProxy(
compilerOptions.infrastructureLogging
? compilerOptions.infrastructureLogging.level
: "info"
);
}
return level;
};

if (typeof proxyOptions.logProvider === "undefined") {
proxyOptions.logProvider = () => this.logger;
}
if (typeof item.logLevel === "undefined") {
item.logLevel = getLogLevelForProxy(
compilerOptions.infrastructureLogging
? compilerOptions.infrastructureLogging.level
: "info"
);
}

return proxyOptions;
});
if (typeof item.logProvider === "undefined") {
item.logProvider = () => this.logger;
}
}

return item;
});
}

if (typeof options.setupExitSignals === "undefined") {
Expand Down Expand Up @@ -875,22 +883,24 @@ class Server {

// It is possible to use the `bypass` method without a `target`.
// However, the proxy middleware has no use in this case, and will fail to instantiate.
if (proxyConfig.target) {
if (context) {
return createProxyMiddleware(context, proxyConfig);
}

return createProxyMiddleware(proxyConfig);
};
/**
* Assume a proxy configuration specified as:
* proxy: [
* {
* context: ...,
* ...options...
* context: "value",
* ...options,
* },
* // or:
* function() {
* return {
* context: ...,
* ...options...
* context: "context",
* ...options,
* };
* }
* ]
Expand All @@ -903,7 +913,9 @@ class Server {
? proxyConfigOrCallback()
: proxyConfigOrCallback;

proxyMiddleware = getProxyMiddleware(proxyConfig);
if (!proxyConfig.bypass) {
proxyMiddleware = getProxyMiddleware(proxyConfig);
}

if (proxyConfig.ws) {
this.webSocketProxies.push(proxyMiddleware);
Expand All @@ -922,6 +934,7 @@ class Server {
// - Check if we have a bypass function defined
// - In case the bypass function is defined we'll retrieve the
// bypassUrl from it otherwise bypassUrl would be null
// TODO remove in the next major in favor `context` and `router` options
const isByPassFuncDefined = typeof proxyConfig.bypass === "function";
const bypassUrl = isByPassFuncDefined
? await proxyConfig.bypass(req, res, proxyConfig)
Expand Down
180 changes: 179 additions & 1 deletion test/server/proxy-option.test.js
Expand Up @@ -66,13 +66,35 @@ const proxyOptionOfArray = [
bypass: () => {
if (req && req.query.foo) {
res.end(`foo+${next.name}+${typeof next}`);

return false;
}
},
};
},
];

const proxyOptionOfArrayWithoutTarget = [
{
router: () => `http://localhost:${port1}`,
},
];

const proxyWithPath = {
"/proxy1": {
path: `http://localhost:${port1}`,
target: `http://localhost:${port1}`,
},
};

const proxyWithString = {
"/proxy1": `http://localhost:${port1}`,
};

const proxyWithRouterAsObject = {
router: () => `http://localhost:${port1}`,
};

describe("proxy option", () => {
let proxyServer1;
let proxyServer2;
Expand Down Expand Up @@ -204,7 +226,7 @@ describe("proxy option", () => {
});
});

describe("as an option is an object", () => {
describe("as an option is an object with the `context` option", () => {
let server;
let req;

Expand Down Expand Up @@ -243,6 +265,123 @@ describe("proxy option", () => {
});
});

describe("as an option is an object with `context` and `target` as string", () => {
let server;
let req;

beforeAll(async () => {
const compiler = webpack(config);

server = new Server(
{
static: {
directory: staticDirectory,
watch: false,
},
proxy: proxyWithString,
port: port3,
},
compiler
);

await server.start();

await listenProxyServers();

req = request(server.app);
});

afterAll(async () => {
await server.stop();
await closeProxyServers();
});

it("respects a proxy option", async () => {
const response = await req.get("/proxy1");

expect(response.status).toEqual(200);
expect(response.text).toContain("from proxy1");
});
});

describe("as an option is an object with the `path` option (`context` alias)", () => {
let server;
let req;

beforeAll(async () => {
const compiler = webpack(config);

server = new Server(
{
static: {
directory: staticDirectory,
watch: false,
},
proxy: proxyWithPath,
port: port3,
},
compiler
);

await server.start();

await listenProxyServers();

req = request(server.app);
});

afterAll(async () => {
await server.stop();
await closeProxyServers();
});

it("respects a proxy option", async () => {
const response = await req.get("/proxy1");

expect(response.status).toEqual(200);
expect(response.text).toContain("from proxy1");
});
});

describe("as an option is an object with the `router` option", () => {
let server;
let req;

beforeAll(async () => {
const compiler = webpack(config);

server = new Server(
{
static: {
directory: staticDirectory,
watch: false,
},
proxy: proxyWithRouterAsObject,
port: port3,
},
compiler
);

await server.start();

await listenProxyServers();

req = request(server.app);
});

afterAll(async () => {
await server.stop();
await closeProxyServers();
});

it("respects a proxy option", async () => {
const response = await req.get("/proxy1");

expect(response.status).toEqual(200);
expect(response.text).toContain("from proxy1");
});
});

describe("as an array", () => {
let server;
let req;
Expand Down Expand Up @@ -296,6 +435,45 @@ describe("proxy option", () => {
});
});

describe("as an array without the `route` option", () => {
let server;
let req;

beforeAll(async () => {
const compiler = webpack(config);

server = new Server(
{
static: {
directory: staticDirectory,
watch: false,
},
proxy: proxyOptionOfArrayWithoutTarget,
port: port3,
},
compiler
);

await server.start();

await listenProxyServers();

req = request(server.app);
});

afterAll(async () => {
await server.stop();
await closeProxyServers();
});

it("respects a proxy option", async () => {
const response = await req.get("/proxy1");

expect(response.status).toEqual(200);
expect(response.text).toContain("from proxy1");
});
});

describe("should sharing a proxy option", () => {
let server;
let req;
Expand Down

0 comments on commit 6e2cbde

Please sign in to comment.