diff --git a/lib/connection/connections/HttpConnection.ts b/lib/connection/connections/HttpConnection.ts index dc9c3902..8c56019c 100644 --- a/lib/connection/connections/HttpConnection.ts +++ b/lib/connection/connections/HttpConnection.ts @@ -98,7 +98,9 @@ export default class HttpConnection implements IConnectionProvider { this.connection = new ThriftHttpConnection( { - url: `${options.https ? 'https' : 'http'}://${options.host}:${options.port}${options.path ?? '/'}`, + url: `${options.https ? 'https' : 'http'}://${options.host.replace(/\/$/, '')}:${options.port}${ + options.path ? (options.path.startsWith('/') ? '' : '/') + options.path.replace(/\/$/, '') : '/' + }`, transport: thrift.TBufferedTransport, protocol: thrift.TBinaryProtocol, getRetryPolicy: () => this.getRetryPolicy(), diff --git a/tests/unit/connection/connections/HttpConnection.test.ts b/tests/unit/connection/connections/HttpConnection.test.ts index c7b39972..44d38a69 100644 --- a/tests/unit/connection/connections/HttpConnection.test.ts +++ b/tests/unit/connection/connections/HttpConnection.test.ts @@ -2,7 +2,7 @@ import http from 'http'; import { expect } from 'chai'; import HttpConnection from '../../../../lib/connection/connections/HttpConnection'; import ThriftHttpConnection from '../../../../lib/connection/connections/ThriftHttpConnection'; - +import IConnectionOptions from '../../../../lib/connection/contracts/IConnectionOptions'; import ClientContextStub from '../../.stubs/ClientContextStub'; describe('HttpConnection.connect', () => { @@ -127,4 +127,54 @@ describe('HttpConnection.connect', () => { ...extraHeaders, }); }); + + it('should handle trailing slashes in host correctly', async () => { + interface TestCase { + input: { + host: string; + path?: string; + }; + expected: string; + } + + const testCases: TestCase[] = [ + { + input: { host: 'xyz.com/', path: '/sql/v1' }, + expected: 'https://xyz.com:443/sql/v1', + }, + { + input: { host: 'xyz.com', path: '/sql/v1' }, + expected: 'https://xyz.com:443/sql/v1', + }, + { + input: { host: 'xyz.com/', path: undefined }, + expected: 'https://xyz.com:443/', + }, + { + input: { host: 'xyz.com', path: 'sql/v1' }, + expected: 'https://xyz.com:443/sql/v1', + }, + { + input: { host: 'xyz.com/', path: 'sql/v1' }, + expected: 'https://xyz.com:443/sql/v1', + }, + { + input: { host: 'xyz.com', path: 'sql/v1/' }, + expected: 'https://xyz.com:443/sql/v1', + }, + ]; + + for (const testCase of testCases) { + const options: IConnectionOptions = { + host: testCase.input.host, + port: 443, + path: testCase.input.path, + https: true, + }; + + const connection = new HttpConnection(options, new ClientContextStub()); + const thriftConnection = await connection.getThriftConnection(); + expect(thriftConnection.url).to.be.equal(testCase.expected); + } + }); });