Skip to content

Commit

Permalink
Merge pull request #4 from firecomm/bind
Browse files Browse the repository at this point in the history
Bind
  • Loading branch information
iangeckeler committed Aug 14, 2019
2 parents f0243c5 + 0ab1cd7 commit a5fa831
Show file tree
Hide file tree
Showing 8 changed files with 236 additions and 131 deletions.
10 changes: 5 additions & 5 deletions __tests__/Server.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,21 +86,21 @@ describe("Tests for addService", () => {
xdescribe("Unit tests for bind.", () => {
xit("Bind should support a single port insecurely if no config supplied.", () => {
const server = new Server();
const boundPorts = server.bind("0.0.0.0:3000");
server.bind("0.0.0.0:3000");
expect(server._ports.length).toBe(1);
});

xit("If no cert/key is passed with an array of ports, they are all generated but insecure.", () => {
const server = new Server();
const boundPorts = server.bind(["0.0.0.0:3001", "0.0.0.0:3002"]);
server.bind(["0.0.0.0:3001", "0.0.0.0:3002"]);
expect(server._ports.length).toBe(2);
});

xit("Properly binds one SSL", () => {
const server = new Server();
let certPath = path.join(__dirname, "/test1.crt");
let keyPath = path.join(__dirname, "/test1.key");
const boundPorts = server.bind("0.0.0.0:3003", {
server.bind("0.0.0.0:3003", {
privateKey: keyPath,
certificate: certPath
});
Expand All @@ -111,7 +111,7 @@ xdescribe("Unit tests for bind.", () => {
const server = new Server();
let certPath = path.join(__dirname, "/test1.crt");
let keyPath = path.join(__dirname, "/test1.key");
const boundPorts = server.bind(
server.bind(
["0.0.0.0:3004", "0.0.0.0.3005"],
[
{
Expand All @@ -128,7 +128,7 @@ xdescribe("Unit tests for bind.", () => {
const server = new Server();
let certPath = path.join(__dirname, "/test1.crt");
let keyPath = path.join(__dirname, "/test1.key");
const boundPorts = server.bind(["0.0.0.0:3006", "0.0.0.0.3007"], {
server.bind(["0.0.0.0:3006", "0.0.0.0.3007"], {
privateKey: keyPath,
certificate: certPath
});
Expand Down
5 changes: 3 additions & 2 deletions examples/firecomm/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,11 @@ server.addService(
let certPath = path.join(__dirname, "/server.crt");
let keyPath = path.join(__dirname, "/server.key");

const result = server.bind(["0.0.0.0:3000", "192.168.10.82:3001"], {
// const result =
server.bind(["0.0.0.0:3000", "0.0.0.0:2999"], [{
privateKey: keyPath,
certificate: certPath
});
}, null]);
// console.log({ result });
// console.log({ server });
// console.log(server.__proto__);
Expand Down
268 changes: 198 additions & 70 deletions lib/Server.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,87 +179,215 @@ const server = new Server();
server.bind( '0.0.0.0:3000', {certificate, privateKey } )
*/
bind(PORT, config) {
if (!Array.isArray(PORT) && typeof PORT !== "string") {
throw new Error("PORT must be a string or array of strings.");
}
// Future: support an array of ports or unlimited args
let ports = new Array();
let configs = new Array();
if (!Array.isArray(PORT)) {
ports.push(PORT);
} else {
// going to assume its not an object and is in fact an array
PORT.forEach(e => ports.push(e));
}
if (!Array.isArray(config)) {
configs.push(config);
} else {
// going to assume its not an object and is in fact an array
config.forEach(e => configs.push(e));
}
if (ports.length !== configs.length && configs.length !== 1) {
throw new Error(
"Ports and configs lengths should match, unless you want the same certificate and key to encrypt all ports. In that case, ports is an array, and supply a single config."
);
}
let singleConfig = configs.length === 1;
bind(ports, sslConfigs) {
const boundPorts = [];

for (let i = 0; i < ports.length; i++) {
// if config does not exist, create an Insecure server
// else, take the contents of config (certificate and private key) and
// apply them to create an encrypted connection
if (!configs[i]) {
let readCertificate;
let readPrivateKey;
if (typeof ports !== "string" && !Array.isArray(ports) && !sslConfigs) {
throw new Error("PORT must be a string or array of strings.");
}
else if (typeof ports === "string" && !sslConfigs) {
boundPorts.push(
super.bind(ports[i], grpc.ServerCredentials.createInsecure())
super.bind(
ports,
grpc.ServerCredentials.createInsecure(),
)
)
}
else if (typeof ports === "string" && !Array.isArray(sslConfigs) && typeof sslConfigs === 'object') {
readCertificate = fs.readFileSync(
sslConfigs.certificate
);
readPrivateKey = fs.readFileSync(
sslConfigs.privateKey
);
} else {
// we are deconstructing keys here that have the PATH value to the file
let privateKey;
let certificate;
if (singleConfig) {
const {
privateKey: unreadPrivateKey,
certificate: unreadCertificate
} = configs[0];
privateKey = unreadPrivateKey;
certificate = unreadCertificate;
} else {
const {
privateKey: unreadPrivateKey,
certificate: unreadCertificate
} = configs[i];
privateKey = unreadPrivateKey;
certificate = unreadCertificate;
}
if (privateKey === undefined || certificate === undefined) {
throw new Error(
"If supplying credentials, config object must have privateKey and certificate properties"
);
}
// creating buffer data types here
let readCertificate = fs.readFileSync(certificate);
let readPrivateKey = fs.readFileSync(privateKey);

// create an array which is "A list of private key and certificate chain
// pairs to be used for authenticating the server"
let listOfObjects = [
{ private_key: readPrivateKey, cert_chain: readCertificate }
];

boundPorts.push(
super.bind(
ports[i],
grpc.ServerCredentials.createSsl(readCertificate, listOfObjects)
ports,
grpc.ServerCredentials.createSsl(
readCertificate,
[{
private_key: readPrivateKey,
cert_chain: readCertificate
}]
),
)
)
} else if (typeof ports === "string" && Array.isArray(sslConfigs)) {
readCertificate = fs.readFileSync(
sslConfigs[0].certificate
);
readPrivateKey = fs.readFileSync(
sslConfigs[0].privateKey
);
boundPorts.push(
super.bind(
ports,
grpc.ServerCredentials.createSsl(
readCertificate,
[{
private_key: readPrivateKey,
cert_chain: readCertificate
}]
),
)
)
} else if (Array.isArray(ports) && !sslConfigs) {
console.log(sslConfigs)
ports.forEach(port => {
boundPorts.push(
super.bind(
port,
grpc.ServerCredentials.createInsecure(),
)
)
})
} else if (Array.isArray(ports) && !Array.isArray(sslConfigs) && typeof sslConfigs === 'object') {
readCertificate = fs.readFileSync(
sslConfigs.certificate
);
readPrivateKey = fs.readFileSync(
sslConfigs.privateKey
);
ports.forEach(port => {
boundPorts.push(
super.bind(
port,
grpc.ServerCredentials.createSsl(
readCertificate,
[{
private_key: readPrivateKey,
cert_chain: readCertificate
}]
),
)
)
})
} else if (Array.isArray(ports) && Array.isArray(sslConfigs) && ports.length !== sslConfigs.length) {
readCertificate = fs.readFileSync(
sslConfigs[0].certificate
);
readPrivateKey = fs.readFileSync(
sslConfigs[0].privateKey
);
ports.forEach((port, index) => {
boundPorts.push(
super.bind(
port,
grpc.ServerCredentials.createSsl(
readCertificate,
[{
private_key: readPrivateKey,
cert_chain: readCertificate
}]
),
)
)
})
} else if (Array.isArray(ports) && Array.isArray(sslConfigs) && ports.length === sslConfigs.length) {
ports.forEach((port, index) => {
readCertificate = fs.readFileSync(
sslConfigs[0].certificate
);
readPrivateKey = fs.readFileSync(
sslConfigs[0].privateKey
);
boundPorts.push(
super.bind(
port,
grpc.ServerCredentials.createSsl(
readCertificate,
[{
private_key: readPrivateKey,
cert_chain: readCertificate
}]
),
)
)
})
}
}
// Future: support an array of ports or unlimited args
// let ports = [];
// let configs = [];
// if (!Array.isArray(PORT)) {
// ports.push(PORT);
// } else {
// // going to assume its not an object and is in fact an array
// PORT.forEach(e => ports.push(e));
// }
// if (!Array.isArray(config)) {
// configs.push(config);
// } else {
// // going to assume its not an object and is in fact an array
// config.forEach(e => configs.push(e));
// }
// if (ports.length !== configs.length && configs.length !== 1) {
// throw new Error(
// "Ports and configs lengths should match, unless you want the same certificate and key to encrypt all ports. In that case, ports is an array, and supply a single config."
// );
// }
// let singleConfig = configs.length === 1;
// const boundPorts = [];

// for (let i = 0; i < ports.length; i++) {
// // if config does not exist, create an Insecure server
// // else, take the contents of config (certificate and private key) and
// // apply them to create an encrypted connection
// // if (singleConfig && config === undefined) {
// // boundPorts.push(
// // super.bindAsync(ports[i], grpc.ServerCredentials.createInsecure())
// // );
// // continue;
// // }
// // else if (!configs[i]) {
// // boundPorts.push(
// // super.bindAsync(ports[i], grpc.ServerCredentials.createInsecure())
// // );
// // } else {
// // // we are deconstructing keys here that have the PATH value to the file
// // let privateKey;
// // let certificate;
// // if (singleConfig) {
// // const {
// // privateKey: unreadPrivateKey,
// // certificate: unreadCertificate
// // } = configs[0];
// // privateKey = unreadPrivateKey;
// // certificate = unreadCertificate;
// // } else {
// // const {
// // privateKey: unreadPrivateKey,
// // certificate: unreadCertificate
// // } = configs[i];
// // privateKey = unreadPrivateKey;
// // certificate = unreadCertificate;
// // }
// // if (privateKey === undefined || certificate === undefined) {
// // throw new Error(
// // "If supplying credentials, config object must have privateKey and certificate properties"
// // );
// // }
// // // creating buffer data types here
// // let readCertificate = fs.readFileSync(certificate);
// // let readPrivateKey = fs.readFileSync(privateKey);

// // // create an array which is "A list of private key and certificate chain
// // // pairs to be used for authenticating the server"
// // let listOfObjects = [
// // { private_key: readPrivateKey, cert_chain: readCertificate }
// // ];

// // boundPorts.push(
// // super.bindAsync(
// // ports[i],
// // grpc.ServerCredentials.createSsl(readCertificate, listOfObjects)
// // )
// // );
// }
// }
this._ports = this._ports.concat(boundPorts);
return this;
}

/**
* Starts your server instance.
*/
Expand Down
3 changes: 3 additions & 0 deletions lib/callFactories/callDecorators/basicCallDecorator.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ module.exports = function(customCall, originalCall) {
customCall.call = originalCall;
customCall.state = null;
customCall.head = originalCall.metadata;
customCall.getPeer = function() {
return originalCall.getPeer();
};
};
10 changes: 7 additions & 3 deletions lib/callFactories/callDecorators/clientStreamDecorator.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@
module.exports = function(customCall, originalCall) {
customCall.on = function(event, callback) {
if (typeof event === "function") {
this.call.on("data", event);
originalCall.on("data", event);
} else if (typeof event === "string") {
if (event === "data") {
this.call.on("data", callback);
originalCall.on("data", callback);
} else if (event === "metadata") {
callback(this.head);
} else if (event === "cancelled") {
originalCall.on("cancelled", callback);
} else {
this.call.on(event, callback);
originalCall.on(event, callback);
}
} else {
throw new Error(
Expand Down
6 changes: 4 additions & 2 deletions lib/callFactories/callDecorators/clientUnaryDecorator.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,17 @@ module.exports = function clientUnaryDecorator(customCall, originalCall) {
} else {
if (typeof string !== "string") {
throw new Error(
'.on takes "data" parameter and a callback to be invoked on data, or just the callback.'
'.on takes "data" or "metadata" parameter and a callback to be invoked on data, or just the callback.'
);
} else {
if (string === "data") {
callback(this.body);
} else if (string === "metadata") {
callback(this.head);
} else if (event === "cancelled") {
originalCall.on("cancelled", callback);
} else {
throw new Error('Only the "data" event is support by unary .on');
throw new Error('Only the "data" and "metadata" events are supported by unary .on');
}
}
}
Expand Down

0 comments on commit a5fa831

Please sign in to comment.