Browse Source

Refactoring

pull/7153/head
Thomas Kaul 3 weeks ago
parent
commit
d58c0e2713
  1. 47
      apps/api/src/services/fetch/fetch.service.ts
  2. 5
      apps/api/src/services/fetch/interfaces/proxy-route.interface.ts

47
apps/api/src/services/fetch/fetch.service.ts

@ -41,10 +41,6 @@ export class FetchService implements OnModuleInit {
} }
public async fetch(input: RequestInfo | URL, init?: RequestInit) { public async fetch(input: RequestInfo | URL, init?: RequestInit) {
// Apply a generic per-domain origin override (e.g. route a provider through
// a local proxy) before doing anything else with the request
input = this.applyProxyRoute(input);
const method = ( const method = (
init?.method ?? init?.method ??
(input instanceof Request ? input.method : undefined) ?? (input instanceof Request ? input.method : undefined) ??
@ -71,8 +67,10 @@ export class FetchService implements OnModuleInit {
} }
} }
const proxiedInput = this.applyProxyRoute(input);
try { try {
return await globalThis.fetch(input, init); return await globalThis.fetch(proxiedInput, init);
} catch (error) { } catch (error) {
if (error instanceof Error) { if (error instanceof Error) {
this.logger.error( this.logger.error(
@ -189,33 +187,44 @@ export class FetchService implements OnModuleInit {
* the input unchanged when no route matches or parsing fails. * the input unchanged when no route matches or parsing fails.
*/ */
private applyProxyRoute(input: RequestInfo | URL): RequestInfo | URL { private applyProxyRoute(input: RequestInfo | URL): RequestInfo | URL {
let requestUrl: URL;
try { try {
const requestUrl = new URL( requestUrl = new URL(
input instanceof Request ? input.url : input.toString() input instanceof Request ? input.url : input.toString()
); );
} catch {
return input;
}
const route = this.proxyRoutes.find(({ domain }) => { const route = this.proxyRoutes.find(({ domain }) => {
return this.hostnameMatchesDomain({ return this.hostnameMatchesDomain({
domain, domain,
hostname: requestUrl.hostname hostname: requestUrl.hostname
});
}); });
});
if (!route) { if (!route) {
return input; return input;
} }
try {
const proxyUrl = new URL(route.url); const proxyUrl = new URL(route.url);
requestUrl.protocol = proxyUrl.protocol;
requestUrl.hostname = proxyUrl.hostname; requestUrl.hostname = proxyUrl.hostname;
requestUrl.port = proxyUrl.port; requestUrl.port = proxyUrl.port;
requestUrl.protocol = proxyUrl.protocol;
return input instanceof Request
? new Request(requestUrl.toString(), input)
: requestUrl.toString();
} catch { } catch {
this.logger.warn(
`Skipping proxy route for "${route.domain}": invalid url "${route.url}"`
);
return input; return input;
} }
return input instanceof Request
? new Request(requestUrl.toString(), input)
: requestUrl.toString();
} }
private getMatchingWebFetchRoute(url: string) { private getMatchingWebFetchRoute(url: string) {

5
apps/api/src/services/fetch/interfaces/proxy-route.interface.ts

@ -1,9 +1,6 @@
/** /**
* Overrides the origin (protocol, host and port) of outgoing requests for a * Overrides the origin (protocol, host and port) of outgoing requests for a
* given domain. This lets a self-hosted instance transparently route a * given domain.
* provider's traffic through a local proxy (e.g. one that solves a bot
* challenge) without changing any call sites the request path and query are
* preserved.
* *
* Configured via the `PROXY_ROUTES` property as a JSON array, e.g. * Configured via the `PROXY_ROUTES` property as a JSON array, e.g.
* *

Loading…
Cancel
Save