From 6f3c41659f6a9ba3dc555179b0de5f1850a26cbe Mon Sep 17 00:00:00 2001 From: Opender Singh Date: Thu, 12 Nov 2020 12:42:52 +1300 Subject: [PATCH] Add TLS/SSL support (#2827) --- .../grpc/__tests__/parse-grpc-url.test.js | 43 +++++++++++++++++++ .../insomnia-app/app/network/grpc/index.js | 20 ++++++--- .../app/network/grpc/parse-grpc-url.js | 17 ++++++++ 3 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 packages/insomnia-app/app/network/grpc/__tests__/parse-grpc-url.test.js create mode 100644 packages/insomnia-app/app/network/grpc/parse-grpc-url.js diff --git a/packages/insomnia-app/app/network/grpc/__tests__/parse-grpc-url.test.js b/packages/insomnia-app/app/network/grpc/__tests__/parse-grpc-url.test.js new file mode 100644 index 000000000..fe747e472 --- /dev/null +++ b/packages/insomnia-app/app/network/grpc/__tests__/parse-grpc-url.test.js @@ -0,0 +1,43 @@ +import parseGrpcUrl from '../parse-grpc-url'; + +describe('parseGrpcUrl', () => { + it.each([ + ['grpcb.in:9000', 'grpcb.in:9000'], + ['GRPCB.IN:9000', 'grpcb.in:9000'], + ['custom.co', 'custom.co'], + ])('should not enable tls with no protocol: %s', (input, expected) => { + expect(parseGrpcUrl(input)).toStrictEqual({ + url: expected, + enableTls: false, + }); + }); + + it.each([ + ['grpcs://grpcb.in:9000', 'grpcb.in:9000'], + ['GRPCS://GRPCB.IN:9000', 'grpcb.in:9000'], + ['grpcs://custom.co', 'custom.co'], + ])('should enable tls with grpcs:// protocol: %s', (input, expected) => { + expect(parseGrpcUrl(input)).toStrictEqual({ + url: expected, + enableTls: true, + }); + }); + + it.each([ + ['grpc://grpcb.in:9000', 'grpcb.in:9000'], + ['GRPC://GRPCB.IN:9000', 'grpcb.in:9000'], + ['grpc://custom.co', 'custom.co'], + ])('should not enable tls with no grpc:// protocol: %s', (input, expected) => { + expect(parseGrpcUrl(input)).toStrictEqual({ + url: expected, + enableTls: false, + }); + }); + + it.each([null, undefined, ''])('can handle falsey urls', input => { + expect(parseGrpcUrl(input)).toStrictEqual({ + url: '', + enableTls: false, + }); + }); +}); diff --git a/packages/insomnia-app/app/network/grpc/index.js b/packages/insomnia-app/app/network/grpc/index.js index 2741945a2..845c189ac 100644 --- a/packages/insomnia-app/app/network/grpc/index.js +++ b/packages/insomnia-app/app/network/grpc/index.js @@ -8,15 +8,21 @@ import callCache from './call-cache'; import type { ServiceError } from './service-error'; import { GrpcStatusEnum } from './service-error'; import type { Call } from './call-cache'; +import parseGrpcUrl from './parse-grpc-url'; -const createClient = (req: GrpcRequest, respond: ResponseCallbacks): Object | undefined => { - if (!req.url) { - respond.sendError(req._id, new Error('gRPC url not specified')); // TODO: update wording +const _createClient = (req: GrpcRequest, respond: ResponseCallbacks): Object | undefined => { + const { url, enableTls } = parseGrpcUrl(req.url); + + if (!url) { + respond.sendError(req._id, new Error('gRPC url not specified')); return undefined; } - console.log(`[gRPC] connecting to url=${req.url}`); + + const credentials = enableTls ? grpc.credentials.createSsl() : grpc.credentials.createInsecure(); + + console.log(`[gRPC] connecting to url=${url} ${enableTls ? 'with' : 'without'} TLS`); const Client = grpc.makeGenericClientConstructor({}); - return new Client(req.url, grpc.credentials.createInsecure()); + return new Client(url, credentials); }; export const sendUnary = async (requestId: string, respond: ResponseCallbacks): Promise => { @@ -39,7 +45,7 @@ export const sendUnary = async (requestId: string, respond: ResponseCallbacks): } // Create client - const client = createClient(req, respond); + const client = _createClient(req, respond); if (!client) { return; @@ -81,7 +87,7 @@ export const startClientStreaming = async ( } // Create client - const client = createClient(req, respond); + const client = _createClient(req, respond); if (!client) { return; diff --git a/packages/insomnia-app/app/network/grpc/parse-grpc-url.js b/packages/insomnia-app/app/network/grpc/parse-grpc-url.js new file mode 100644 index 000000000..2e363bee2 --- /dev/null +++ b/packages/insomnia-app/app/network/grpc/parse-grpc-url.js @@ -0,0 +1,17 @@ +// @flow +import url from 'url'; + +const parseGrpcUrl = (grpcUrl?: string): { url: string, enableTls: boolean } => { + const { protocol, host, href } = url.parse(grpcUrl?.toLowerCase() || ''); + + switch (protocol) { + case 'grpcs:': + return { url: host, enableTls: true }; + case 'grpc:': + return { url: host, enableTls: false }; + default: + return { url: href, enableTls: false }; + } +}; + +export default parseGrpcUrl;