Skip to content
This repository has been archived by the owner on Aug 15, 2022. It is now read-only.

Commit

Permalink
fix: fail to build
Browse files Browse the repository at this point in the history
  • Loading branch information
under-ctrl committed Mar 9, 2020
1 parent c882aea commit f813af9
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 93 deletions.
2 changes: 1 addition & 1 deletion electron/process_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ import { powerMonitor } from "electron";
import { checkUdpForwardingEnabled, isServerReachable } from "./connectivity";
import { ChildProcess, spawn } from "child_process";
import { pathToEmbeddedBinary, RemoteServer, pathToConfig } from "./utils";
import { validateServerCredentials } from "../src/utils/connectivity";
import { SMART_DNS_ADDRESS } from "../src/constants";
import { BrowserWindow } from "electron";
import { validateServerCredentials } from "../src/share";

export type Dns =
| {
Expand Down
2 changes: 1 addition & 1 deletion electron/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
SMART_DNS_WHITE_LIST_SERVERS
} from "./constant";
import { AdditionalRoute } from "./main";
import { lookupIp } from "../src/utils/helper";
import { lookupIp } from "../src/share";

export const setMenu = (mainWindow: BrowserWindow) => {
if (process.env.NODE_ENV === "development") {
Expand Down
7 changes: 2 additions & 5 deletions src/components/Cards/LatencyCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,9 @@ import React, { useCallback, useEffect, useRef } from "react";
import { useSelector } from "react-redux";
import { AppState } from "../../reducers/rootReducer";
import { getActivatedServer } from "../Proxies/util";
import {
checkServer,
checkDns,
validateServerCredentials
} from "../../utils/connectivity";
import { checkServer, checkDns } from "../../utils/connectivity";
import { useAsync } from "../../hooks";
import { validateServerCredentials } from "../../share";

//TODO: Remove repeated code
export const LatencyCard = () => {
Expand Down
88 changes: 88 additions & 0 deletions src/share/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
//The code is used by main and renderer process.
//TODO: Remove shared code
import * as dns from "dns";
import { SocksClient } from "socks";

const DNS_LOOKUP_TIMEOUT_MS = 2000;
const SERVER_TEST_TIMEOUT_MS = 2000;
const CREDENTIALS_TEST_DOMAIN = "google.com";
export const NS_PER_MILLI_SECOND = 1e6;

export function timeoutPromise<T = any>(
promise: Promise<any>,
ms: number,
name = ""
): Promise<T> {
let winner: Promise<any>;
const timeout = new Promise<void>((resolve, reject) => {
const timeoutId = setTimeout(() => {
clearTimeout(timeoutId);
if (winner) {
console.log(`Promise "${name}" resolved before ${ms} ms.`);
resolve();
} else {
console.log(`Promise "${name}" timed out after ${ms} ms.`);
reject("Promise timeout");
}
}, ms);
});
winner = Promise.race([promise, timeout]);
return winner;
}

// Effectively a no-op if hostname is already an IP.
export function lookupIp(hostname: string) {
return timeoutPromise<string>(
new Promise<string>((fulfill, reject) => {
dns.lookup(hostname, 4, (e, address) => {
if (e || !address) {
return reject("could not resolve proxy server hostname");
}
fulfill(address);
});
}),
DNS_LOOKUP_TIMEOUT_MS,
"DNS lookup"
);
}

export function financial(x: number, fractionDigits = 2) {
return Number(Number.parseFloat(x.toString()).toFixed(fractionDigits));
}

// Resolves with true iff a response can be received from a semi-randomly-chosen website through the
// Shadowsocks proxy.
export const validateServerCredentials = (address: string, port: number) =>
new Promise<number>((fulfill, reject) => {
const lastTime = process.hrtime();
SocksClient.createConnection({
proxy: { host: address, port, type: 5 },
destination: { host: CREDENTIALS_TEST_DOMAIN, port: 80 },
command: "connect",
timeout: SERVER_TEST_TIMEOUT_MS
})
.then(client => {
client.socket.write(
`HEAD / HTTP/1.1\r\nHost: ${CREDENTIALS_TEST_DOMAIN}\r\n\r\n`
);
client.socket.on("data", data => {
if (data.toString().startsWith("HTTP/1.1")) {
client.socket.end();
fulfill(
financial(process.hrtime(lastTime)[1] / NS_PER_MILLI_SECOND, 0)
);
} else {
client.socket.end();
reject("unexpected response from remote test website");
}
});

client.socket.on("close", () => {
reject("could not connect to remote test website");
});
client.socket.resume();
})
.catch(e => {
reject(e);
});
});
43 changes: 1 addition & 42 deletions src/utils/connectivity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,8 @@
// limitations under the License.
import * as net from "net";
import * as dns from "dns";
import { financial, timeoutPromise } from "./helper";
import { SocksClient } from "socks";
import { financial, NS_PER_MILLI_SECOND, timeoutPromise } from "../share";

const SERVER_TEST_TIMEOUT_MS = 2000;
const CREDENTIALS_TEST_DOMAIN = "google.com";
const NS_PER_MILLI_SECOND = 1e6;
const DNS_TEST_SERVER = "8.8.8.8";
const DNS_TEST_DOMAIN = "google.com";
const DNS_TEST_TIMEOUT_MS = 2000;
Expand Down Expand Up @@ -85,40 +81,3 @@ export const checkDns = () =>
}),
DNS_TEST_TIMEOUT_MS
);

// Resolves with true iff a response can be received from a semi-randomly-chosen website through the
// Shadowsocks proxy.
export const validateServerCredentials = (address: string, port: number) =>
new Promise<number>((fulfill, reject) => {
const lastTime = process.hrtime();
SocksClient.createConnection({
proxy: { host: address, port, type: 5 },
destination: { host: CREDENTIALS_TEST_DOMAIN, port: 80 },
command: "connect",
timeout: SERVER_TEST_TIMEOUT_MS
})
.then(client => {
client.socket.write(
`HEAD / HTTP/1.1\r\nHost: ${CREDENTIALS_TEST_DOMAIN}\r\n\r\n`
);
client.socket.on("data", data => {
if (data.toString().startsWith("HTTP/1.1")) {
client.socket.end();
fulfill(
financial(process.hrtime(lastTime)[1] / NS_PER_MILLI_SECOND, 0)
);
} else {
client.socket.end();
reject("unexpected response from remote test website");
}
});

client.socket.on("close", () => {
reject("could not connect to remote test website");
});
client.socket.resume();
})
.catch(e => {
reject(e);
});
});
45 changes: 1 addition & 44 deletions src/utils/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,12 @@ import regions from "i18n-iso-countries";
import path from "path";
import ip2region from "./ip2region";
import promiseIpc from "electron-promise-ipc";
import * as dns from "dns";

const DNS_LOOKUP_TIMEOUT_MS = 2000;

export function timeoutPromise<T = any>(
promise: Promise<any>,
ms: number,
name = ""
): Promise<T> {
let winner: Promise<any>;
const timeout = new Promise<void>((resolve, reject) => {
const timeoutId = setTimeout(() => {
clearTimeout(timeoutId);
if (winner) {
console.log(`Promise "${name}" resolved before ${ms} ms.`);
resolve();
} else {
console.log(`Promise "${name}" timed out after ${ms} ms.`);
reject("Promise timeout");
}
}, ms);
});
winner = Promise.race([promise, timeout]);
return winner;
}
import { financial, lookupIp } from "../share";

regions.registerLocale(require("i18n-iso-countries/langs/zh.json"));

// Uses the OS' built-in functions, i.e. /etc/hosts, et al.:
// https://nodejs.org/dist/latest-v10.x/docs/api/dns.html#dns_dns
// Effectively a no-op if hostname is already an IP.
export function lookupIp(hostname: string) {
return timeoutPromise<string>(
new Promise<string>((fulfill, reject) => {
dns.lookup(hostname, 4, (e, address) => {
if (e || !address) {
return reject("could not resolve proxy server hostname");
}
fulfill(address);
});
}),
DNS_LOOKUP_TIMEOUT_MS,
"DNS lookup"
);
}

export const lookupRegionCodes = async (hosts: string[]) => {
const ips = await Promise.all(
Expand Down Expand Up @@ -94,10 +55,6 @@ export const lookupRegionCodes = async (hosts: string[]) => {
return regionCodes;
};

export function financial(x: number, fractionDigits = 2) {
return Number(Number.parseFloat(x.toString()).toFixed(fractionDigits));
}

export const convertTrafficData = (data: number) => {
if (data < 1024) return `${financial(data)} B`;
if (data < 1024 * 1024) return `${financial(data / 1024)} KB`;
Expand Down

0 comments on commit f813af9

Please sign in to comment.