Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/message/error_message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export const OUT_OF_BOUNDS =
export const REQUEST_TIMEOUT = 'Request timeout';
export const REQUEST_ERROR = 'Request error';
export const NO_STATUS_CODE_IN_RESPONSE = 'No status code in response';
export const INVALID_REQUEST_URL = 'Invalid request URL: %s';
export const UNSUPPORTED_PROTOCOL = 'Unsupported protocol: %s';
export const RETRY_CANCELLED = 'Retry cancelled';
export const ONLY_POST_REQUESTS_ARE_SUPPORTED = 'Only POST requests are supported';
Expand Down
6 changes: 6 additions & 0 deletions lib/utils/http_request_handler/request_handler.node.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,12 @@ describe('NodeRequestHandler', () => {
await expect(request.responsePromise).rejects.toThrow();
});

it('should return a rejected response promise when the URL is malformed', async () => {
const request = nodeRequestHandler.makeRequest('not a valid url', {}, 'get');

await expect(request.responsePromise).rejects.toThrow();
});
Comment thread
junaed-optimizely marked this conversation as resolved.

it('should return a rejected promise when there is a request error', async () => {
const scope = nock(host)
.get(path)
Expand Down
19 changes: 13 additions & 6 deletions lib/utils/http_request_handler/request_handler.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@
*/
import http from 'http';
import https from 'https';
import url from 'url';
import { AbortableRequest, Headers, RequestHandler, Response } from './http';
import decompressResponse from 'decompress-response';
import { LoggerFacade } from '../../logging/logger';
import { REQUEST_TIMEOUT_MS } from '../enums';
import { NO_STATUS_CODE_IN_RESPONSE, REQUEST_ERROR, REQUEST_TIMEOUT, UNSUPPORTED_PROTOCOL } from 'error_message';
import { INVALID_REQUEST_URL, NO_STATUS_CODE_IN_RESPONSE, REQUEST_ERROR, REQUEST_TIMEOUT, UNSUPPORTED_PROTOCOL } from 'error_message';
import { OptimizelyError } from '../../error/optimizly_error';
import { Platform } from '../../platform_support';
/**
Expand All @@ -46,7 +45,15 @@ export class NodeRequestHandler implements RequestHandler {
* @returns AbortableRequest contains both the response Promise and capability to abort()
*/
makeRequest(requestUrl: string, headers: Headers, method: string, data?: string): AbortableRequest {
const parsedUrl = url.parse(requestUrl);
let parsedUrl: URL;
try {
parsedUrl = new URL(requestUrl);
} catch {
return {
Comment thread
junaed-optimizely marked this conversation as resolved.
responsePromise: Promise.reject(new OptimizelyError(INVALID_REQUEST_URL, requestUrl)),
abort: () => {},
};
Comment thread
junaed-optimizely marked this conversation as resolved.
}

if (parsedUrl.protocol !== 'https:' && parsedUrl.protocol !== 'http:') {
return {
Expand Down Expand Up @@ -79,11 +86,11 @@ export class NodeRequestHandler implements RequestHandler {
* @private
* @returns http.RequestOptions Standard request options dictionary compatible with both http and https
*/
private getRequestOptionsFromUrl(url: url.UrlWithStringQuery): http.RequestOptions {
private getRequestOptionsFromUrl(url: URL): http.RequestOptions {
return {
hostname: url.hostname,
path: url.path,
port: url.port,
path: url.pathname + url.search,
port: url.port || null,
protocol: url.protocol,
Comment thread
junaed-optimizely marked this conversation as resolved.
Comment on lines 91 to 94
};
}
Expand Down
Loading