aboutsummaryrefslogtreecommitdiffstats
path: root/apps/workers/utils.ts
blob: 55204570cdea2393588e01292b036770911068c9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import { HttpProxyAgent } from "http-proxy-agent";
import { HttpsProxyAgent } from "https-proxy-agent";
import fetch from "node-fetch";

import serverConfig from "@karakeep/shared/config";

export function withTimeout<T, Ret>(
  func: (param: T) => Promise<Ret>,
  timeoutSec: number,
) {
  return async (param: T): Promise<Ret> => {
    return await Promise.race([
      func(param),
      new Promise<Ret>((_resolve, reject) =>
        setTimeout(
          () => reject(new Error(`Timed-out after ${timeoutSec} secs`)),
          timeoutSec * 1000,
        ),
      ),
    ]);
  };
}

function getProxyAgent(url: string) {
  const { proxy } = serverConfig;

  if (!proxy.httpProxy && !proxy.httpsProxy) {
    return undefined;
  }

  const urlObj = new URL(url);
  const protocol = urlObj.protocol;

  // Check if URL should bypass proxy
  if (proxy.noProxy) {
    const noProxyList = proxy.noProxy.split(",").map((host) => host.trim());
    const hostname = urlObj.hostname;

    for (const noProxyHost of noProxyList) {
      if (
        noProxyHost === hostname ||
        (noProxyHost.startsWith(".") && hostname.endsWith(noProxyHost)) ||
        hostname.endsWith("." + noProxyHost)
      ) {
        return undefined;
      }
    }
  }

  if (protocol === "https:" && proxy.httpsProxy) {
    return new HttpsProxyAgent(proxy.httpsProxy);
  } else if (protocol === "http:" && proxy.httpProxy) {
    return new HttpProxyAgent(proxy.httpProxy);
  } else if (proxy.httpProxy) {
    // Fallback to HTTP proxy for HTTPS if HTTPS proxy not configured
    return new HttpProxyAgent(proxy.httpProxy);
  }

  return undefined;
}

export const fetchWithProxy = (
  url: string,
  options: Record<string, unknown> = {},
) => {
  const agent = getProxyAgent(url);
  if (agent) {
    options.agent = agent;
  }
  return fetch(url, options);
};