Repository URL to install this package:
|
Version:
1.1.0 ▾
|
#!/usr/bin/env node
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const cafe_utility_1 = require("cafe-utility");
const http_1 = require("http");
const node_fetch_1 = __importDefault(require("node-fetch"));
const target_1 = require("./target");
const utility_1 = require("./utility");
const PORT_ENV = 'ETHERPROXY_PORT';
const EXPIRY_ENV = 'ETHERPROXY_EXPIRY';
const TARGET_ENV = 'ETHERPROXY_TARGET';
const DEFAULT_PORT = 9000;
const DEFAULT_EXPIRY = 2000;
const DEFAULT_TARGET = 'http://localhost:8545';
main();
function main() {
const port = cafe_utility_1.Arrays.getNumberArgument(process.argv, 'port', process.env, PORT_ENV) || DEFAULT_PORT;
const target = cafe_utility_1.Arrays.getArgument(process.argv, 'target', process.env, TARGET_ENV) || DEFAULT_TARGET;
const expiry = cafe_utility_1.Arrays.getNumberArgument(process.argv, 'expiry', process.env, EXPIRY_ENV) || DEFAULT_EXPIRY;
const fastIndex = cafe_utility_1.Objects.createFastIndex();
const targets = target.split(',').map(x => ({
url: x,
lastErrorAt: 0
}));
const server = (0, http_1.createServer)((request, response) => __awaiter(this, void 0, void 0, function* () {
request.on('error', error => {
console.error(error);
});
response.on('error', error => {
console.error(error);
});
if (request.url === '/health' || request.url === '/readiness') {
for (let i = 0; i < targets.length; i++) {
const target = (0, target_1.getHealthyTarget)(targets);
try {
yield (0, node_fetch_1.default)(target.url, { timeout: 10000 });
response.statusCode = 200;
response.end('200 OK');
return;
}
catch (error) {
target.lastErrorAt = Date.now();
console.error(error);
}
}
response.statusCode = 503;
response.end('503 Service Unavailable');
return;
}
const chunks = [];
request.on('data', (chunk) => {
chunks.push(chunk);
});
request.on('end', () => __awaiter(this, void 0, void 0, function* () {
for (let i = 0; i < targets.length; i++) {
const target = (0, target_1.getHealthyTarget)(targets);
try {
const context = {
method: request.method || 'GET',
url: target.url,
headers: request.headers,
body: Buffer.concat(chunks).toString('utf-8')
};
const parsedBody = JSON.parse(context.body);
const id = parsedBody.id;
delete parsedBody.id;
const key = `${target.url}_${JSON.stringify(parsedBody)}`;
const cachedPromise = cafe_utility_1.Objects.getFromFastIndexWithExpiracy(fastIndex, key);
if (cachedPromise) {
process.stdout.write(`Cache hit: ${key}\n`);
const successful = yield (0, utility_1.respondWithFetchPromise)(id, response, cachedPromise);
if (successful) {
return;
}
else {
target.lastErrorAt = Date.now();
continue;
}
}
process.stdout.write(`Key: ${key}\n`);
delete context.headers.host;
delete context.headers['user-agent'];
delete context.headers['content-length'];
const responsePromise = (0, utility_1.fetchWithTimeout)(context.url, {
method: context.method,
headers: context.headers,
body: context.body
});
cafe_utility_1.Objects.pushToFastIndexWithExpiracy(fastIndex, key, responsePromise, expiry);
const successful = yield (0, utility_1.respondWithFetchPromise)(id, response, responsePromise);
if (successful) {
return;
}
else {
target.lastErrorAt = Date.now();
continue;
}
}
catch (error) {
target.lastErrorAt = Date.now();
console.error(error);
}
}
response.statusCode = 503;
response.end('503 Service Unavailable');
}));
}));
server.listen(port);
console.log(`Etherproxy is running on port ${port}`);
}