pg-server
Version:
Postgres DB server emulator, proxy or honeypot
109 lines • 4.33 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createAdvancedProxy = exports.createSimpleProxy = void 0;
const net_1 = require("net");
const server_1 = require("./server");
const commands_1 = require("./protocol/commands");
const responses_1 = require("./protocol/responses");
const util_1 = __importDefault(require("util"));
const utils_1 = require("./utils");
const response_parser_1 = require("./protocol/response-parser");
const command_writer_1 = require("./protocol/command-writer");
/**
* Create a db proxying server which only gives you a chance to intercepts/modify queries on the fly.
*
* This is a wrapper for @see createLowLevelProxy .
*
* Must call .listen() to start listening.
*/
function createSimpleProxy(db, ctor) {
return createAdvancedProxy(db, class extends ctor {
async onCommand({ command, getRawData }, { client, db }) {
var _a;
if (command.type === commands_1.CommandCode.parse || command.type === commands_1.CommandCode.query) {
try {
const _transformed = (_a = this.onQuery(command.query)) !== null && _a !== void 0 ? _a : command.query;
let transformed;
if ((0, utils_1.isThenable)(_transformed)) {
getRawData(); // force get raw data before awaiting
transformed = await _transformed;
}
else {
transformed = _transformed;
}
if (typeof transformed === 'object') {
client.error(transformed.error);
client.readyForQuery();
return;
}
if (transformed !== command.query) {
command.query = transformed;
db.send(command);
return;
}
}
catch (e) {
client.error(e);
client.readyForQuery();
return;
}
}
db.sendRaw(getRawData());
}
});
}
exports.createSimpleProxy = createSimpleProxy;
/**
* Create a db proxying server.
*
* Must call .listen() to start listening.
*/
function createAdvancedProxy(db, ctor) {
return (0, net_1.createServer)(socket => {
var _a;
const instance = new ctor();
(_a = instance.onConnect) === null || _a === void 0 ? void 0 : _a.call(instance, socket);
const dbSock = typeof db === 'function'
? db()
: (0, net_1.connect)(db.port, db.host);
let parties;
// === when receiving a command from client...
const { writer } = (0, server_1.bindSocket)(socket, command => {
if (instance.onCommand) {
// ... either ask the proxy what to do
instance.onCommand(command, parties);
}
else {
// ... or just forward it
dbSock.write(command.getRawData());
}
});
// === when receiving response from db...
const parser = new response_parser_1.DbResponseParser();
dbSock.on('data', buffer => {
if (instance.onResult) {
// ... either ask the proxy what to do
parser.parse(buffer, c => {
if (utils_1.isDebug) {
console.log(' 🕋 db ', (0, responses_1.messageToStr)(c.response.type), c.response);
}
instance.onResult(c, parties);
});
}
else {
// ... or just forward it
socket.write(buffer);
}
});
parties = { client: writer, db: new command_writer_1.CommandWriter(dbSock) };
// === bind errors
dbSock.on('error', e => writer.error(util_1.default.inspect(e)));
dbSock.on('close', () => socket.destroy());
dbSock.setNoDelay(true);
});
}
exports.createAdvancedProxy = createAdvancedProxy;
//# sourceMappingURL=proxy.js.map
;