123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- // global initializer
- {{
- function $set(obj, path, value) {
- if (Object(obj) !== obj) return obj;
- if (!Array.isArray(path)) path = path.toString().match(/[^.[\]]+/g) || [];
- path
- .slice(0, -1)
- .reduce((a, c, i) => (Object(a[c]) === a[c] ? a[c] : (a[c] = Math.abs(path[i + 1]) >> 0 === +path[i + 1] ? [] : {})), obj)[
- path[path.length - 1]
- ] = value;
- return obj;
- }
- function toBool(str) {
- if (typeof str === 'undefined' || str === null) return undefined;
- return /(TRUE)|1/i.test(str);
- }
- }}
- {
- const proxy = {};
- const obfs = {};
- const $ = {};
- const params = {};
- }
- start = (trojan) {
- return proxy
- }
- trojan = "trojan://" password:password "@" server:server ":" port:port "/"? params? name:name?{
- proxy.type = "trojan";
- proxy.password = password;
- proxy.server = server;
- proxy.port = port;
- proxy.name = name;
- // name may be empty
- if (!proxy.name) {
- proxy.name = server + ":" + port;
- }
- };
- password = match:$[^@]+ {
- return decodeURIComponent(match);
- };
- server = ip/domain;
- domain = match:[0-9a-zA-z-_.]+ {
- const domain = match.join("");
- if (/(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]/.test(domain)) {
- return domain;
- }
- }
- ip = & {
- const start = peg$currPos;
- let end;
- let j = start;
- while (j < input.length) {
- if (input[j] === ",") break;
- if (input[j] === ":") end = j;
- j++;
- }
- peg$currPos = end || j;
- $.ip = input.substring(start, end).trim();
- return true;
- } { return $.ip; }
- port = digits:[0-9]+ {
- const port = parseInt(digits.join(""), 10);
- if (port >= 0 && port <= 65535) {
- return port;
- } else {
- throw new Error("Invalid port: " + port);
- }
- }
- params = "?" head:param tail:("&"@param)* {
- proxy["skip-cert-verify"] = toBool(params["allowInsecure"]);
- proxy.sni = params["sni"] || params["peer"];
- if (toBool(params["ws"])) {
- proxy.network = "ws";
- $set(proxy, "ws-opts.path", params["wspath"]);
- }
-
- if (params["type"]) {
- let httpupgrade
- proxy.network = params["type"]
- if(proxy.network === 'httpupgrade') {
- proxy.network = 'ws'
- httpupgrade = true
- }
- if (['grpc'].includes(proxy.network)) {
- proxy[proxy.network + '-opts'] = {
- 'grpc-service-name': params["serviceName"],
- '_grpc-type': params["mode"],
- };
- } else {
- if (params["path"]) {
- $set(proxy, proxy.network+"-opts.path", decodeURIComponent(params["path"]));
- }
- if (params["host"]) {
- $set(proxy, proxy.network+"-opts.headers.Host", decodeURIComponent(params["host"]));
- }
- if (httpupgrade) {
- $set(proxy, proxy.network+"-opts.v2ray-http-upgrade", true);
- $set(proxy, proxy.network+"-opts.v2ray-http-upgrade-fast-open", true);
- }
- }
- }
- proxy.udp = toBool(params["udp"]);
- proxy.tfo = toBool(params["tfo"]);
- }
- param = kv/single;
- kv = key:$[a-z]i+ "=" value:$[^&#]i* {
- params[key] = value;
- }
- single = key:$[a-z]i+ {
- params[key] = true;
- };
- name = "#" + match:$.* {
- return decodeURIComponent(match);
- }
|