proxy-protocol-js
Version:
A PROXY protocol builder and parser for JavaScript
167 lines • 8.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.V2ProxyProtocol = exports.V2ProxyProtocolParseError = void 0;
var AddressFamily_1 = require("./enum/AddressFamily");
var Command_1 = require("./enum/Command");
var TransportProtocol_1 = require("./enum/TransportProtocol");
var IPv4ProxyAddress_1 = require("./proxy_address/IPv4ProxyAddress");
var IPv6ProxyAddress_1 = require("./proxy_address/IPv6ProxyAddress");
var UnixProxyAddress_1 = require("./proxy_address/UnixProxyAddress");
var V2ProxyProtocolParseError = (function () {
function V2ProxyProtocolParseError(message) {
this.message = message;
this.name = this.constructor.name;
}
return V2ProxyProtocolParseError;
}());
exports.V2ProxyProtocolParseError = V2ProxyProtocolParseError;
var V2ProxyProtocol = (function () {
function V2ProxyProtocol(command, transportProtocol, proxyAddress, data) {
this.command = command;
this.transportProtocol = transportProtocol;
this.proxyAddress = proxyAddress;
this.data = data;
this.addressFamilyType = proxyAddress.getAddressFamilyType();
}
V2ProxyProtocol.prototype.build = function () {
var proto = this.initProto();
var cursor = V2ProxyProtocol.initialHeaderOffset;
if (this.addressFamilyType === AddressFamily_1.AddressFamilyType.INET && this.proxyAddress instanceof IPv4ProxyAddress_1.IPv4ProxyAddress) {
for (var i = 0; i < 4; i++) {
proto[cursor++] = this.proxyAddress.sourceAddress.address[i];
}
for (var i = 0; i < 4; i++) {
proto[cursor++] = this.proxyAddress.destinationAddress.address[i];
}
var srcPort = V2ProxyProtocol.separate32bitTo16bitPair(this.proxyAddress.sourcePort);
proto[cursor++] = srcPort[0];
proto[cursor++] = srcPort[1];
var dstPort = V2ProxyProtocol.separate32bitTo16bitPair(this.proxyAddress.destinationPort);
proto[cursor++] = dstPort[0];
proto[cursor++] = dstPort[1];
}
else if (this.addressFamilyType === AddressFamily_1.AddressFamilyType.INET6 && this.proxyAddress instanceof IPv6ProxyAddress_1.IPv6ProxyAddress) {
for (var i = 0; i < 16; i++) {
proto[cursor++] = this.proxyAddress.sourceAddress.address[i];
}
for (var i = 0; i < 16; i++) {
proto[cursor++] = this.proxyAddress.destinationAddress.address[i];
}
var srcPort = V2ProxyProtocol.separate32bitTo16bitPair(this.proxyAddress.sourcePort);
proto[cursor++] = srcPort[0];
proto[cursor++] = srcPort[1];
var dstPort = V2ProxyProtocol.separate32bitTo16bitPair(this.proxyAddress.destinationPort);
proto[cursor++] = dstPort[0];
proto[cursor++] = dstPort[1];
}
else if (this.addressFamilyType === AddressFamily_1.AddressFamilyType.UNIX && this.proxyAddress instanceof UnixProxyAddress_1.UnixProxyAddress) {
for (var i = 0; i < 108; i++) {
proto[cursor++] = this.proxyAddress.sourceAddress.address[i];
}
for (var i = 0; i < 108; i++) {
proto[cursor++] = this.proxyAddress.destinationAddress.address[i];
}
}
if (this.data) {
var dataLen = this.data.length;
for (var i = 0; i < dataLen; i++) {
proto[cursor++] = this.data[i];
}
}
return proto;
};
V2ProxyProtocol.parse = function (input) {
if (!this.isValidProtocolSignature(input)) {
throw new V2ProxyProtocolParseError("given binary doesn't have v2 PROXY protocol's signature");
}
var cursor = this.protocolSignatureLength;
var versionAndCommandByte = input[cursor++];
if (versionAndCommandByte === undefined) {
throw new V2ProxyProtocolParseError("given binary doesn't have a byte for version and command (13rd byte)");
}
var versionAndCommand = this.separate8bit(versionAndCommandByte);
if (versionAndCommand[0] !== this.protocolVersion) {
throw new V2ProxyProtocolParseError('given protocol version is invalid');
}
var command = Command_1.Command[Command_1.Command[versionAndCommand[1]]];
if (command === undefined) {
throw new V2ProxyProtocolParseError('given command is invalid');
}
var afAndTransportProtocolByte = input[cursor++];
if (afAndTransportProtocolByte === undefined) {
throw new V2ProxyProtocolParseError("given binary doesn't have a byte for address family and transport protocol (14th byte)");
}
var afAndTransportProtocol = this.separate8bit(afAndTransportProtocolByte);
var addressFamilyType = AddressFamily_1.AddressFamilyType[AddressFamily_1.AddressFamilyType[afAndTransportProtocol[0]]];
if (addressFamilyType === undefined) {
throw new V2ProxyProtocolParseError('given address family is invalid');
}
var transportProtocol = TransportProtocol_1.TransportProtocol[TransportProtocol_1.TransportProtocol[afAndTransportProtocol[1]]];
if (transportProtocol === undefined) {
throw new V2ProxyProtocolParseError('given transport protocol is invalid');
}
var upperLengthByte = input[cursor++];
var lowerLengthByte = input[cursor];
if (upperLengthByte === undefined || lowerLengthByte === undefined) {
throw new V2ProxyProtocolParseError("given binary doesn't have bytes for specifying length");
}
var length = (upperLengthByte << 8) + lowerLengthByte;
var addressFamily = new AddressFamily_1.AddressFamily(addressFamilyType);
var addressFamilyLength = addressFamily.getLength();
if (length < addressFamilyLength) {
throw new V2ProxyProtocolParseError("given specified length is shorter than address family's length");
}
return new V2ProxyProtocol(command, transportProtocol, addressFamily.getFactoryMethod()(input.slice(16)), input.slice(addressFamilyLength + 16));
};
V2ProxyProtocol.prototype.initProto = function () {
var proto = new Uint8Array(this.proxyAddress.getLength() +
V2ProxyProtocol.protocolSignatureLength +
V2ProxyProtocol.protocolMetaLength +
(this.data ? this.data.length : 0));
var cursor = 0;
for (var i = 0; i < V2ProxyProtocol.protocolSignatureLength; i++) {
proto[cursor++] = V2ProxyProtocol.protocolSignature[i];
}
proto[cursor++] = this.unionProtocolVersionAndCommand();
proto[cursor++] = this.unionAddressFamilyAndTransportProtocol();
var len = V2ProxyProtocol.separate32bitTo16bitPair(this.proxyAddress.getLength());
proto[cursor++] = len[0];
proto[cursor] = len[1];
return proto;
};
V2ProxyProtocol.prototype.unionProtocolVersionAndCommand = function () {
return V2ProxyProtocol.protocolVersion | this.command;
};
V2ProxyProtocol.prototype.unionAddressFamilyAndTransportProtocol = function () {
return this.addressFamilyType | this.transportProtocol;
};
V2ProxyProtocol.separate32bitTo16bitPair = function (num) {
var masked = num & 0xff00;
var high = num >> 8;
var low = num - masked;
return [high, low];
};
V2ProxyProtocol.separate8bit = function (num) {
var high = num & 0xf0;
var low = num - high;
return [high, low];
};
V2ProxyProtocol.isValidProtocolSignature = function (input) {
for (var i = 0; i < V2ProxyProtocol.protocolSignatureLength; i++) {
if (input[i] !== V2ProxyProtocol.protocolSignature[i]) {
return false;
}
}
return true;
};
V2ProxyProtocol.protocolSignature = new Uint8Array([
0x0d, 0x0a, 0x0d, 0x0a, 0x00, 0x0d, 0x0a, 0x51, 0x55, 0x49, 0x54, 0x0a,
]);
V2ProxyProtocol.protocolSignatureLength = V2ProxyProtocol.protocolSignature.length;
V2ProxyProtocol.protocolMetaLength = 4;
V2ProxyProtocol.protocolVersion = 0x20;
V2ProxyProtocol.initialHeaderOffset = V2ProxyProtocol.protocolSignatureLength + V2ProxyProtocol.protocolMetaLength;
return V2ProxyProtocol;
}());
exports.V2ProxyProtocol = V2ProxyProtocol;
//# sourceMappingURL=V2ProxyProtocol.js.map