Skip to content
Permalink
Browse files

url: refactor binding imports in internal/url

PR-URL: #12717
Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com
  • Loading branch information...
jasnell committed Apr 28, 2017
1 parent b331ba6 commit 97ec72b76dac67ca4792444c0df16ee798ef5dad
Showing with 79 additions and 61 deletions.
  1. +79 −61 lib/internal/url.js
@@ -5,20 +5,44 @@ const {
hexTable,
isHexTable
} = require('internal/querystring');

const { getConstructorOf } = require('internal/util');
const errors = require('internal/errors');
const binding = process.binding('url');
const querystring = require('querystring');

const { platform } = process;
const isWindows = platform === 'win32';

const {
domainToASCII: _domainToASCII,
domainToUnicode: _domainToUnicode,
encodeAuth,
toUSVString: _toUSVString,
parse: _parse,
setURLConstructor,
URL_FLAGS_CANNOT_BE_BASE,
URL_FLAGS_HAS_FRAGMENT,
URL_FLAGS_HAS_HOST,
URL_FLAGS_HAS_PASSWORD,
URL_FLAGS_HAS_PATH,
URL_FLAGS_HAS_QUERY,
URL_FLAGS_HAS_USERNAME,
URL_FLAGS_SPECIAL,
kFragment,
kHost,
kHostname,
kPathStart,
kPort,
kQuery,
kSchemeStart
} = process.binding('url');

const context = Symbol('context');
const cannotBeBase = Symbol('cannot-be-base');
const cannotHaveUsernamePasswordPort =
Symbol('cannot-have-username-password-port');
const special = Symbol('special');
const searchParams = Symbol('query');
const querystring = require('querystring');

const { platform } = process;
const isWindows = platform === 'win32';

const kFormat = Symbol('format');

// https://tc39.github.io/ecma262/#sec-%iteratorprototype%-object
@@ -35,7 +59,7 @@ function toUSVString(val) {
const match = unpairedSurrogateRe.exec(str);
if (!match)
return str;
return binding.toUSVString(str, match.index);
return _toUSVString(str, match.index);
}

// Refs: https://html.spec.whatwg.org/multipage/browsers.html#concept-origin-opaque
@@ -74,10 +98,10 @@ function onParseComplete(flags, protocol, username, password,
var ctx = this[context];
ctx.flags = flags;
ctx.scheme = protocol;
ctx.username = (flags & binding.URL_FLAGS_HAS_USERNAME) !== 0 ? username : '';
ctx.password = (flags & binding.URL_FLAGS_HAS_PASSWORD) !== 0 ? password : '';
ctx.username = (flags & URL_FLAGS_HAS_USERNAME) !== 0 ? username : '';
ctx.password = (flags & URL_FLAGS_HAS_PASSWORD) !== 0 ? password : '';
ctx.port = port;
ctx.path = (flags & binding.URL_FLAGS_HAS_PATH) !== 0 ? path : [];
ctx.path = (flags & URL_FLAGS_HAS_PATH) !== 0 ? path : [];
ctx.query = query;
ctx.fragment = fragment;
ctx.host = host;
@@ -98,31 +122,30 @@ function onParseError(flags, input) {
function parse(url, input, base) {
const base_context = base ? base[context] : undefined;
url[context] = new URLContext();
binding.parse(input.trim(), -1,
base_context, undefined,
onParseComplete.bind(url), onParseError);
_parse(input.trim(), -1, base_context, undefined,
onParseComplete.bind(url), onParseError);
}

function onParseProtocolComplete(flags, protocol, username, password,
host, port, path, query, fragment) {
const ctx = this[context];
if ((flags & binding.URL_FLAGS_SPECIAL) !== 0) {
ctx.flags |= binding.URL_FLAGS_SPECIAL;
if ((flags & URL_FLAGS_SPECIAL) !== 0) {
ctx.flags |= URL_FLAGS_SPECIAL;
} else {
ctx.flags &= ~binding.URL_FLAGS_SPECIAL;
ctx.flags &= ~URL_FLAGS_SPECIAL;
}
ctx.scheme = protocol;
}

function onParseHostComplete(flags, protocol, username, password,
host, port, path, query, fragment) {
const ctx = this[context];
if ((flags & binding.URL_FLAGS_HAS_HOST) !== 0) {
if ((flags & URL_FLAGS_HAS_HOST) !== 0) {
ctx.host = host;
ctx.flags |= binding.URL_FLAGS_HAS_HOST;
ctx.flags |= URL_FLAGS_HAS_HOST;
} else {
ctx.host = null;
ctx.flags &= ~binding.URL_FLAGS_HAS_HOST;
ctx.flags &= ~URL_FLAGS_HAS_HOST;
}
if (port !== null)
ctx.port = port;
@@ -131,12 +154,12 @@ function onParseHostComplete(flags, protocol, username, password,
function onParseHostnameComplete(flags, protocol, username, password,
host, port, path, query, fragment) {
const ctx = this[context];
if ((flags & binding.URL_FLAGS_HAS_HOST) !== 0) {
if ((flags & URL_FLAGS_HAS_HOST) !== 0) {
ctx.host = host;
ctx.flags |= binding.URL_FLAGS_HAS_HOST;
ctx.flags |= URL_FLAGS_HAS_HOST;
} else {
ctx.host = null;
ctx.flags &= ~binding.URL_FLAGS_HAS_HOST;
ctx.flags &= ~URL_FLAGS_HAS_HOST;
}
}

@@ -148,18 +171,18 @@ function onParsePortComplete(flags, protocol, username, password,
function onParsePathComplete(flags, protocol, username, password,
host, port, path, query, fragment) {
const ctx = this[context];
if ((flags & binding.URL_FLAGS_HAS_PATH) !== 0) {
if ((flags & URL_FLAGS_HAS_PATH) !== 0) {
ctx.path = path;
ctx.flags |= binding.URL_FLAGS_HAS_PATH;
ctx.flags |= URL_FLAGS_HAS_PATH;
} else {
ctx.path = [];
ctx.flags &= ~binding.URL_FLAGS_HAS_PATH;
ctx.flags &= ~URL_FLAGS_HAS_PATH;
}

// The C++ binding may set host to empty string.
if ((flags & binding.URL_FLAGS_HAS_HOST) !== 0) {
if ((flags & URL_FLAGS_HAS_HOST) !== 0) {
ctx.host = host;
ctx.flags |= binding.URL_FLAGS_HAS_HOST;
ctx.flags |= URL_FLAGS_HAS_HOST;
}
}

@@ -185,11 +208,11 @@ class URL {
}

get [special]() {
return (this[context].flags & binding.URL_FLAGS_SPECIAL) !== 0;
return (this[context].flags & URL_FLAGS_SPECIAL) !== 0;
}

get [cannotBeBase]() {
return (this[context].flags & binding.URL_FLAGS_CANNOT_BE_BASE) !== 0;
return (this[context].flags & URL_FLAGS_CANNOT_BE_BASE) !== 0;
}

// https://url.spec.whatwg.org/#cannot-have-a-username-password-port
@@ -348,8 +371,8 @@ Object.defineProperties(URL.prototype, {
(ctx.host === '' || ctx.host === null)) {
return;
}
binding.parse(scheme, binding.kSchemeStart, null, ctx,
onParseProtocolComplete.bind(this));
_parse(scheme, kSchemeStart, null, ctx,
onParseProtocolComplete.bind(this));
}
},
username: {
@@ -366,11 +389,11 @@ Object.defineProperties(URL.prototype, {
const ctx = this[context];
if (username === '') {
ctx.username = '';
ctx.flags &= ~binding.URL_FLAGS_HAS_USERNAME;
ctx.flags &= ~URL_FLAGS_HAS_USERNAME;
return;
}
ctx.username = binding.encodeAuth(username);
ctx.flags |= binding.URL_FLAGS_HAS_USERNAME;
ctx.username = encodeAuth(username);
ctx.flags |= URL_FLAGS_HAS_USERNAME;
}
},
password: {
@@ -387,11 +410,11 @@ Object.defineProperties(URL.prototype, {
const ctx = this[context];
if (password === '') {
ctx.password = '';
ctx.flags &= ~binding.URL_FLAGS_HAS_PASSWORD;
ctx.flags &= ~URL_FLAGS_HAS_PASSWORD;
return;
}
ctx.password = binding.encodeAuth(password);
ctx.flags |= binding.URL_FLAGS_HAS_PASSWORD;
ctx.password = encodeAuth(password);
ctx.flags |= URL_FLAGS_HAS_PASSWORD;
}
},
host: {
@@ -412,8 +435,7 @@ Object.defineProperties(URL.prototype, {
// Cannot set the host if cannot-be-base is set
return;
}
binding.parse(host, binding.kHost, null, ctx,
onParseHostComplete.bind(this));
_parse(host, kHost, null, ctx, onParseHostComplete.bind(this));
}
},
hostname: {
@@ -430,8 +452,7 @@ Object.defineProperties(URL.prototype, {
// Cannot set the host if cannot-be-base is set
return;
}
binding.parse(host, binding.kHostname, null, ctx,
onParseHostnameComplete.bind(this));
_parse(host, kHostname, null, ctx, onParseHostnameComplete.bind(this));
}
},
port: {
@@ -451,8 +472,7 @@ Object.defineProperties(URL.prototype, {
ctx.port = null;
return;
}
binding.parse(port, binding.kPort, null, ctx,
onParsePortComplete.bind(this));
_parse(port, kPort, null, ctx, onParsePortComplete.bind(this));
}
},
pathname: {
@@ -471,8 +491,8 @@ Object.defineProperties(URL.prototype, {
path = `${path}`;
if (this[cannotBeBase])
return;
binding.parse(path, binding.kPathStart, null, this[context],
onParsePathComplete.bind(this));
_parse(path, kPathStart, null, this[context],
onParsePathComplete.bind(this));
}
},
search: {
@@ -489,14 +509,13 @@ Object.defineProperties(URL.prototype, {
search = toUSVString(search);
if (search === '') {
ctx.query = null;
ctx.flags &= ~binding.URL_FLAGS_HAS_QUERY;
ctx.flags &= ~URL_FLAGS_HAS_QUERY;
} else {
if (search[0] === '?') search = search.slice(1);
ctx.query = '';
ctx.flags |= binding.URL_FLAGS_HAS_QUERY;
ctx.flags |= URL_FLAGS_HAS_QUERY;
if (search) {
binding.parse(search, binding.kQuery, null, ctx,
onParseSearchComplete.bind(this));
_parse(search, kQuery, null, ctx, onParseSearchComplete.bind(this));
}
}
initSearchParams(this[searchParams], search);
@@ -524,14 +543,13 @@ Object.defineProperties(URL.prototype, {
hash = `${hash}`;
if (!hash) {
ctx.fragment = null;
ctx.flags &= ~binding.URL_FLAGS_HAS_FRAGMENT;
ctx.flags &= ~URL_FLAGS_HAS_FRAGMENT;
return;
}
if (hash[0] === '#') hash = hash.slice(1);
ctx.fragment = '';
ctx.flags |= binding.URL_FLAGS_HAS_FRAGMENT;
binding.parse(hash, binding.kFragment, null, ctx,
onParseHashComplete.bind(this));
ctx.flags |= URL_FLAGS_HAS_FRAGMENT;
_parse(hash, kFragment, null, ctx, onParseHashComplete.bind(this));
}
},
toJSON: {
@@ -553,10 +571,10 @@ function update(url, params) {
const serializedParams = params.toString();
if (serializedParams) {
ctx.query = serializedParams;
ctx.flags |= binding.URL_FLAGS_HAS_QUERY;
ctx.flags |= URL_FLAGS_HAS_QUERY;
} else {
ctx.query = null;
ctx.flags &= ~binding.URL_FLAGS_HAS_QUERY;
ctx.flags &= ~URL_FLAGS_HAS_QUERY;
}
}

@@ -1257,15 +1275,15 @@ function domainToASCII(domain) {
throw new errors.TypeError('ERR_MISSING_ARGS', 'domain');

// toUSVString is not needed.
return binding.domainToASCII(`${domain}`);
return _domainToASCII(`${domain}`);
}

function domainToUnicode(domain) {
if (arguments.length < 1)
throw new errors.TypeError('ERR_MISSING_ARGS', 'domain');

// toUSVString is not needed.
return binding.domainToUnicode(`${domain}`);
return _domainToUnicode(`${domain}`);
}

// Utility function that converts a URL object into an ordinary
@@ -1365,10 +1383,10 @@ function constructUrl(flags, protocol, username, password,
var ctx = new URLContext();
ctx.flags = flags;
ctx.scheme = protocol;
ctx.username = (flags & binding.URL_FLAGS_HAS_USERNAME) !== 0 ? username : '';
ctx.password = (flags & binding.URL_FLAGS_HAS_PASSWORD) !== 0 ? password : '';
ctx.username = (flags & URL_FLAGS_HAS_USERNAME) !== 0 ? username : '';
ctx.password = (flags & URL_FLAGS_HAS_PASSWORD) !== 0 ? password : '';
ctx.port = port;
ctx.path = (flags & binding.URL_FLAGS_HAS_PATH) !== 0 ? path : [];
ctx.path = (flags & URL_FLAGS_HAS_PATH) !== 0 ? path : [];
ctx.query = query;
ctx.fragment = fragment;
ctx.host = host;
@@ -1378,7 +1396,7 @@ function constructUrl(flags, protocol, username, password,
initSearchParams(url[searchParams], query);
return url;
}
binding.setURLConstructor(constructUrl);
setURLConstructor(constructUrl);

module.exports = {
toUSVString,

0 comments on commit 97ec72b

Please sign in to comment.
You can’t perform that action at this time.