Skip to content

Commit 9884d73

Browse files
[FSSDK-12865] url parse fix (#1161)
1 parent fc368a2 commit 9884d73

3 files changed

Lines changed: 26 additions & 6 deletions

File tree

lib/message/error_message.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ export const OUT_OF_BOUNDS =
8787
export const REQUEST_TIMEOUT = 'Request timeout';
8888
export const REQUEST_ERROR = 'Request error';
8989
export const NO_STATUS_CODE_IN_RESPONSE = 'No status code in response';
90+
export const INVALID_REQUEST_URL = 'Invalid request URL: %s';
9091
export const UNSUPPORTED_PROTOCOL = 'Unsupported protocol: %s';
9192
export const RETRY_CANCELLED = 'Retry cancelled';
9293
export const ONLY_POST_REQUESTS_ARE_SUPPORTED = 'Only POST requests are supported';

lib/utils/http_request_handler/request_handler.node.spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import nock from 'nock';
2121
import zlib from 'zlib';
2222
import { NodeRequestHandler } from './request_handler.node';
2323
import { getMockLogger } from '../../tests/mock/mock_logger';
24+
import { OptimizelyError } from '../../error/optimizly_error';
25+
import { INVALID_REQUEST_URL } from 'error_message';
2426

2527
beforeAll(() => {
2628
nock.disableNetConnect();
@@ -173,6 +175,16 @@ describe('NodeRequestHandler', () => {
173175
await expect(request.responsePromise).rejects.toThrow();
174176
});
175177

178+
it('should return a rejected response promise when the URL is malformed', async () => {
179+
const malformedUrl = 'not a valid url';
180+
const request = nodeRequestHandler.makeRequest(malformedUrl, {}, 'get');
181+
182+
const error = await request.responsePromise.catch((e) => e);
183+
expect(error).toBeInstanceOf(OptimizelyError);
184+
expect(error.baseMessage).toBe(INVALID_REQUEST_URL);
185+
expect(error.params).toEqual([malformedUrl]);
186+
});
187+
176188
it('should return a rejected promise when there is a request error', async () => {
177189
const scope = nock(host)
178190
.get(path)

lib/utils/http_request_handler/request_handler.node.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,11 @@
1515
*/
1616
import http from 'http';
1717
import https from 'https';
18-
import url from 'url';
1918
import { AbortableRequest, Headers, RequestHandler, Response } from './http';
2019
import decompressResponse from 'decompress-response';
2120
import { LoggerFacade } from '../../logging/logger';
2221
import { REQUEST_TIMEOUT_MS } from '../enums';
23-
import { NO_STATUS_CODE_IN_RESPONSE, REQUEST_ERROR, REQUEST_TIMEOUT, UNSUPPORTED_PROTOCOL } from 'error_message';
22+
import { INVALID_REQUEST_URL, NO_STATUS_CODE_IN_RESPONSE, REQUEST_ERROR, REQUEST_TIMEOUT, UNSUPPORTED_PROTOCOL } from 'error_message';
2423
import { OptimizelyError } from '../../error/optimizly_error';
2524
import { Platform } from '../../platform_support';
2625
/**
@@ -46,7 +45,15 @@ export class NodeRequestHandler implements RequestHandler {
4645
* @returns AbortableRequest contains both the response Promise and capability to abort()
4746
*/
4847
makeRequest(requestUrl: string, headers: Headers, method: string, data?: string): AbortableRequest {
49-
const parsedUrl = url.parse(requestUrl);
48+
let parsedUrl: URL;
49+
try {
50+
parsedUrl = new URL(requestUrl);
51+
} catch {
52+
return {
53+
responsePromise: Promise.reject(new OptimizelyError(INVALID_REQUEST_URL, requestUrl)),
54+
abort: () => {},
55+
};
56+
}
5057

5158
if (parsedUrl.protocol !== 'https:' && parsedUrl.protocol !== 'http:') {
5259
return {
@@ -79,11 +86,11 @@ export class NodeRequestHandler implements RequestHandler {
7986
* @private
8087
* @returns http.RequestOptions Standard request options dictionary compatible with both http and https
8188
*/
82-
private getRequestOptionsFromUrl(url: url.UrlWithStringQuery): http.RequestOptions {
89+
private getRequestOptionsFromUrl(url: URL): http.RequestOptions {
8390
return {
8491
hostname: url.hostname,
85-
path: url.path,
86-
port: url.port,
92+
path: url.pathname + url.search,
93+
port: url.port || null,
8794
protocol: url.protocol,
8895
};
8996
}

0 commit comments

Comments
 (0)