Skip to content

Commit

Permalink
fix: use new URL instead of url.parse (#4048)
Browse files Browse the repository at this point in the history
  • Loading branch information
dead-horse authored Nov 15, 2019
1 parent afed910 commit b7718c1
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 114 deletions.
11 changes: 9 additions & 2 deletions lib/core/dnscache_httpclient.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

const dns = require('mz/dns');
const LRU = require('ylru');
const urlparse = require('url').parse;
const HttpClient = require('./httpclient');
const utility = require('utility');
const utils = require('./utils');

const IP_REGEX = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
const DNSLOOKUP = Symbol('DNSCacheHttpClient#dnslookup');
Expand Down Expand Up @@ -44,7 +44,14 @@ class DNSCacheHttpClient extends HttpClient {
}

async [DNSLOOKUP](url, args) {
const parsed = typeof url === 'string' ? urlparse(url) : url;
let parsed;
if (typeof url === 'string') {
parsed = utils.safeParseURL(url);
// invalid url or relative url
if (!parsed) return { url, args };
} else {
parsed = url;
}
// hostname must exists
const hostname = parsed.hostname;

Expand Down
10 changes: 10 additions & 0 deletions lib/core/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

const util = require('util');
const is = require('is-type-of');
const URL = require('url').URL;

module.exports = {
convertObject,
safeParseURL,
};

function convertObject(obj, ignore) {
Expand Down Expand Up @@ -60,3 +62,11 @@ function convertValue(key, value, ignore) {
/* istanbul ignore next */
return util.format(value);
}

function safeParseURL(url) {
try {
return new URL(url);
} catch (err) {
return null;
}
}
238 changes: 126 additions & 112 deletions test/lib/core/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,125 +4,139 @@ const assert = require('assert');
const utils = require('../../../lib/core/utils');

describe('test/lib/core/utils.test.js', () => {
it('should convert primitive', () => {
const s = Symbol('symbol');
const obj = {
string$: 'string',
number$: 1,
null$: null,
undefined$: undefined,
boolean$: true,
symbol$: s,
};
utils.convertObject(obj);
assert(obj.string$ === 'string');
assert(obj.number$ === 1);
assert(obj.null$ === null);
assert(obj.undefined$ === undefined);
assert(obj.boolean$ === true);
assert(obj.symbol$ === 'Symbol(symbol)');
});
describe('convertObject()', () => {
it('should convert primitive', () => {
const s = Symbol('symbol');
const obj = {
string$: 'string',
number$: 1,
null$: null,
undefined$: undefined,
boolean$: true,
symbol$: s,
};
utils.convertObject(obj);
assert(obj.string$ === 'string');
assert(obj.number$ === 1);
assert(obj.null$ === null);
assert(obj.undefined$ === undefined);
assert(obj.boolean$ === true);
assert(obj.symbol$ === 'Symbol(symbol)');
});

it('should convert regexp', () => {
const obj = {
regexp$: /^a$/g,
};
utils.convertObject(obj);
assert(obj.regexp$ === '/^a$/g');
});
it('should convert regexp', () => {
const obj = {
regexp$: /^a$/g,
};
utils.convertObject(obj);
assert(obj.regexp$ === '/^a$/g');
});

it('should convert date', () => {
const obj = {
date$: new Date(),
};
utils.convertObject(obj);
assert(obj.date$ === '<Date>');
});
it('should convert date', () => {
const obj = {
date$: new Date(),
};
utils.convertObject(obj);
assert(obj.date$ === '<Date>');
});

it('should convert function', () => {
const obj = {
function$: function a() { console.log(a); },
arrowFunction$: a => { console.log(a); },
/* eslint object-shorthand: 0 */
anonymousFunction$: function(a) { console.log(a); },
generatorFunction$: function* a(a) { console.log(a); },
asyncFunction$: async function a(a) { console.log(a); },
};
utils.convertObject(obj);
assert(obj.function$ === '<Function a>');
assert(obj.arrowFunction$ === '<Function arrowFunction$>');
assert(obj.anonymousFunction$ === '<Function anonymousFunction$>');
assert(obj.generatorFunction$ === '<GeneratorFunction a>');
assert(obj.asyncFunction$ === '<AsyncFunction a>');
});
it('should convert function', () => {
const obj = {
function$: function a() { console.log(a); },
arrowFunction$: a => { console.log(a); },
/* eslint object-shorthand: 0 */
anonymousFunction$: function(a) { console.log(a); },
generatorFunction$: function* a(a) { console.log(a); },
asyncFunction$: async function a(a) { console.log(a); },
};
utils.convertObject(obj);
assert(obj.function$ === '<Function a>');
assert(obj.arrowFunction$ === '<Function arrowFunction$>');
assert(obj.anonymousFunction$ === '<Function anonymousFunction$>');
assert(obj.generatorFunction$ === '<GeneratorFunction a>');
assert(obj.asyncFunction$ === '<AsyncFunction a>');
});

it('should convert error', () => {
class TestError extends Error {}
const obj = {
errorClass$: Error,
errorClassExtend$: TestError,
error$: new Error('a'),
errorExtend$: new TestError('a'),
};
utils.convertObject(obj);
assert(obj.errorClass$ === '<Function Error>');
assert(obj.errorClassExtend$ === '<Class TestError>');
assert(obj.error$ === '<Error>');
assert(obj.errorExtend$ === '<TestError>');
});
it('should convert error', () => {
class TestError extends Error { }
const obj = {
errorClass$: Error,
errorClassExtend$: TestError,
error$: new Error('a'),
errorExtend$: new TestError('a'),
};
utils.convertObject(obj);
assert(obj.errorClass$ === '<Function Error>');
assert(obj.errorClassExtend$ === '<Class TestError>');
assert(obj.error$ === '<Error>');
assert(obj.errorExtend$ === '<TestError>');
});

it('should convert class', () => {
class BaseClass {}
class Class extends BaseClass {}
const obj = {
class$: BaseClass,
classExtend$: Class,
};
utils.convertObject(obj);
assert(obj.class$ === '<Class BaseClass>');
assert(obj.classExtend$ === '<Class Class>');
});
it('should convert class', () => {
class BaseClass { }
class Class extends BaseClass { }
const obj = {
class$: BaseClass,
classExtend$: Class,
};
utils.convertObject(obj);
assert(obj.class$ === '<Class BaseClass>');
assert(obj.classExtend$ === '<Class Class>');
});

it('should convert buffer', () => {
class SlowBuffer extends Buffer {}
const obj = {
bufferClass$: Buffer,
bufferClassExtend$: SlowBuffer,
buffer$: Buffer.from('123'),
bufferExtend$: new SlowBuffer('123'),
};
utils.convertObject(obj);
assert(obj.bufferClass$ === '<Function Buffer>');
assert(obj.bufferClassExtend$ === '<Class SlowBuffer>');
assert(obj.buffer$ === '<Buffer len: 3>');
assert(obj.bufferExtend$ === '<Buffer len: 3>');
it('should convert buffer', () => {
class SlowBuffer extends Buffer { }
const obj = {
bufferClass$: Buffer,
bufferClassExtend$: SlowBuffer,
buffer$: Buffer.from('123'),
bufferExtend$: new SlowBuffer('123'),
};
utils.convertObject(obj);
assert(obj.bufferClass$ === '<Function Buffer>');
assert(obj.bufferClassExtend$ === '<Class SlowBuffer>');
assert(obj.buffer$ === '<Buffer len: 3>');
assert(obj.bufferExtend$ === '<Buffer len: 3>');
});

it('should convert ignore', () => {
const s = Symbol('symbol');
const obj = {
string$: 'string',
number$: 1,
null$: null,
undefined$: undefined,
boolean$: true,
symbol$: s,
regexp$: /^a$/g,
};
utils.convertObject(obj, [
'string$',
'number$',
'null$',
'undefined$',
'boolean$',
'symbol$',
'regexp$',
]);
assert(obj.string$ === '<String len: 6>');
assert(obj.number$ === '<Number>');
assert(obj.null$ === null);
assert(obj.undefined$ === undefined);
assert(obj.boolean$ === '<Boolean>');
assert(obj.symbol$ === '<Symbol>');
});
});

it('should convert ignore', () => {
const s = Symbol('symbol');
const obj = {
string$: 'string',
number$: 1,
null$: null,
undefined$: undefined,
boolean$: true,
symbol$: s,
regexp$: /^a$/g,
};
utils.convertObject(obj, [
'string$',
'number$',
'null$',
'undefined$',
'boolean$',
'symbol$',
'regexp$',
]);
assert(obj.string$ === '<String len: 6>');
assert(obj.number$ === '<Number>');
assert(obj.null$ === null);
assert(obj.undefined$ === undefined);
assert(obj.boolean$ === '<Boolean>');
assert(obj.symbol$ === '<Symbol>');
describe('safeParseURL()', () => {
it('should return null if url invalid', () => {
assert(utils.safeParseURL('https://eggjs.org%0a.com') === null);
assert(utils.safeParseURL('/path/for') === null);
});

it('should return parsed url', () => {
assert(utils.safeParseURL('https://eggjs.org').hostname === 'eggjs.org');
assert(utils.safeParseURL('https://eggjs.org!.foo.com').hostname === 'eggjs.org!.foo.com');
});
});
});

0 comments on commit b7718c1

Please sign in to comment.