Skip to content

Commit 1fa6352

Browse files
anonrigtargos
authored andcommitted
url: offload URLSearchParams initialization
PR-URL: #46867 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Filip Skokan <panva.ip@gmail.com>
1 parent 5c7fc92 commit 1fa6352

4 files changed

Lines changed: 48 additions & 52 deletions

File tree

‎lib/_http_client.js‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ const {
6363
constAgent=require('_http_agent');
6464
const{ Buffer }=require('buffer');
6565
const{ defaultTriggerAsyncIdScope }=require('internal/async_hooks');
66-
const{URL, urlToHttpOptions,searchParamsSymbol}=require('internal/url');
66+
const{URL, urlToHttpOptions,isURL}=require('internal/url');
6767
const{
6868
kOutHeaders,
6969
kNeedDrain,
@@ -133,8 +133,7 @@ function ClientRequest(input, options, cb) {
133133
if(typeofinput==='string'){
134134
consturlStr=input;
135135
input=urlToHttpOptions(newURL(urlStr));
136-
}elseif(input&&input[searchParamsSymbol]&&
137-
input[searchParamsSymbol][searchParamsSymbol]){
136+
}elseif(isURL(input)){
138137
// url.URL instance
139138
input=urlToHttpOptions(input);
140139
}else{

‎lib/https.js‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const { ClientRequest } = require('_http_client');
5252
letdebug=require('internal/util/debuglog').debuglog('https',(fn)=>{
5353
debug=fn;
5454
});
55-
const{URL, urlToHttpOptions,searchParamsSymbol}=require('internal/url');
55+
const{URL, urlToHttpOptions,isURL}=require('internal/url');
5656

5757
functionServer(opts,requestListener){
5858
if(!(thisinstanceofServer))returnnewServer(opts,requestListener);
@@ -344,9 +344,7 @@ function request(...args) {
344344
if(typeofargs[0]==='string'){
345345
consturlStr=ArrayPrototypeShift(args);
346346
options=urlToHttpOptions(newURL(urlStr));
347-
}elseif(args[0]&&args[0][searchParamsSymbol]&&
348-
args[0][searchParamsSymbol][searchParamsSymbol]){
349-
// url.URL instance
347+
}elseif(isURL(args[0])){
350348
options=urlToHttpOptions(ArrayPrototypeShift(args));
351349
}
352350

‎lib/internal/url.js‎

Lines changed: 37 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ class URLSearchParams {
224224
}else{
225225
// USVString
226226
init=toUSVString(init);
227-
initSearchParams(this,init);
227+
this[searchParams]=init ? parseParams(init) : [];
228228
}
229229

230230
// "associated url object"
@@ -534,7 +534,7 @@ ObjectDefineProperties(URLSearchParams.prototype, {
534534
},
535535
});
536536

537-
functionisURLThis(self){
537+
functionisURL(self){
538538
returnself!=null&&ObjectPrototypeHasOwnProperty(self,context);
539539
}
540540

@@ -602,160 +602,161 @@ class URL {
602602
ctx.password=password;
603603
ctx.port=port;
604604
ctx.hash=hash;
605-
if(!this[searchParams]){// Invoked from URL constructor
606-
this[searchParams]=newURLSearchParams();
607-
this[searchParams][context]=this;
605+
if(this[searchParams]){
606+
this[searchParams][searchParams]=parseParams(search);
608607
}
609-
initSearchParams(this[searchParams],ctx.search);
610608
};
611609

612610
toString(){
613-
if(!isURLThis(this))
611+
if(!isURL(this))
614612
thrownewERR_INVALID_THIS('URL');
615613
returnthis[context].href;
616614
}
617615

618616
gethref(){
619-
if(!isURLThis(this))
617+
if(!isURL(this))
620618
thrownewERR_INVALID_THIS('URL');
621619
returnthis[context].href;
622620
}
623621

624622
sethref(value){
625-
if(!isURLThis(this))
623+
if(!isURL(this))
626624
thrownewERR_INVALID_THIS('URL');
627625
constvalid=updateUrl(this[context].href,updateActions.kHref,`${value}`,this.#onParseComplete);
628626
if(!valid){throwERR_INVALID_URL(`${value}`);}
629627
}
630628

631629
// readonly
632630
getorigin(){
633-
if(!isURLThis(this))
631+
if(!isURL(this))
634632
thrownewERR_INVALID_THIS('URL');
635633
returnthis[context].origin;
636634
}
637635

638636
getprotocol(){
639-
if(!isURLThis(this))
637+
if(!isURL(this))
640638
thrownewERR_INVALID_THIS('URL');
641639
returnthis[context].protocol;
642640
}
643641

644642
setprotocol(value){
645-
if(!isURLThis(this))
643+
if(!isURL(this))
646644
thrownewERR_INVALID_THIS('URL');
647645
updateUrl(this[context].href,updateActions.kProtocol,`${value}`,this.#onParseComplete);
648646
}
649647

650648
getusername(){
651-
if(!isURLThis(this))
649+
if(!isURL(this))
652650
thrownewERR_INVALID_THIS('URL');
653651
returnthis[context].username;
654652
}
655653

656654
setusername(value){
657-
if(!isURLThis(this))
655+
if(!isURL(this))
658656
thrownewERR_INVALID_THIS('URL');
659657
updateUrl(this[context].href,updateActions.kUsername,`${value}`,this.#onParseComplete);
660658
}
661659

662660
getpassword(){
663-
if(!isURLThis(this))
661+
if(!isURL(this))
664662
thrownewERR_INVALID_THIS('URL');
665663
returnthis[context].password;
666664
}
667665

668666
setpassword(value){
669-
if(!isURLThis(this))
667+
if(!isURL(this))
670668
thrownewERR_INVALID_THIS('URL');
671669
updateUrl(this[context].href,updateActions.kPassword,`${value}`,this.#onParseComplete);
672670
}
673671

674672
gethost(){
675-
if(!isURLThis(this))
673+
if(!isURL(this))
676674
thrownewERR_INVALID_THIS('URL');
677675
constport=this[context].port;
678676
constsuffix=port.length>0 ? `:${port}` : '';
679677
returnthis[context].hostname+suffix;
680678
}
681679

682680
sethost(value){
683-
if(!isURLThis(this))
681+
if(!isURL(this))
684682
thrownewERR_INVALID_THIS('URL');
685683
updateUrl(this[context].href,updateActions.kHost,`${value}`,this.#onParseComplete);
686684
}
687685

688686
gethostname(){
689-
if(!isURLThis(this))
687+
if(!isURL(this))
690688
thrownewERR_INVALID_THIS('URL');
691689
returnthis[context].hostname;
692690
}
693691

694692
sethostname(value){
695-
if(!isURLThis(this))
693+
if(!isURL(this))
696694
thrownewERR_INVALID_THIS('URL');
697695
updateUrl(this[context].href,updateActions.kHostname,`${value}`,this.#onParseComplete);
698696
}
699697

700698
getport(){
701-
if(!isURLThis(this))
699+
if(!isURL(this))
702700
thrownewERR_INVALID_THIS('URL');
703701
returnthis[context].port;
704702
}
705703

706704
setport(value){
707-
if(!isURLThis(this))
705+
if(!isURL(this))
708706
thrownewERR_INVALID_THIS('URL');
709707
updateUrl(this[context].href,updateActions.kPort,`${value}`,this.#onParseComplete);
710708
}
711709

712710
getpathname(){
713-
if(!isURLThis(this))
711+
if(!isURL(this))
714712
thrownewERR_INVALID_THIS('URL');
715713
returnthis[context].pathname;
716714
}
717715

718716
setpathname(value){
719-
if(!isURLThis(this))
717+
if(!isURL(this))
720718
thrownewERR_INVALID_THIS('URL');
721719
updateUrl(this[context].href,updateActions.kPathname,`${value}`,this.#onParseComplete);
722720
}
723721

724722
getsearch(){
725-
if(!isURLThis(this))
723+
if(!isURL(this))
726724
thrownewERR_INVALID_THIS('URL');
727725
returnthis[context].search;
728726
}
729727

730-
setsearch(search){
731-
if(!isURLThis(this))
728+
setsearch(value){
729+
if(!isURL(this))
732730
thrownewERR_INVALID_THIS('URL');
733-
search=toUSVString(search);
734-
updateUrl(this[context].href,updateActions.kSearch,search,this.#onParseComplete);
735-
initSearchParams(this[searchParams],this[context].search);
731+
updateUrl(this[context].href,updateActions.kSearch,toUSVString(value),this.#onParseComplete);
736732
}
737733

738734
// readonly
739735
getsearchParams(){
740-
if(!isURLThis(this))
736+
if(!isURL(this))
741737
thrownewERR_INVALID_THIS('URL');
738+
// Create URLSearchParams on demand to greatly improve the URL performance.
739+
if(this[searchParams]==null){
740+
this[searchParams]=newURLSearchParams(this[context].search);
741+
this[searchParams][context]=this;
742+
}
742743
returnthis[searchParams];
743744
}
744745

745746
gethash(){
746-
if(!isURLThis(this))
747+
if(!isURL(this))
747748
thrownewERR_INVALID_THIS('URL');
748749
returnthis[context].hash;
749750
}
750751

751752
sethash(value){
752-
if(!isURLThis(this))
753+
if(!isURL(this))
753754
thrownewERR_INVALID_THIS('URL');
754755
updateUrl(this[context].href,updateActions.kHash,`${value}`,this.#onParseComplete);
755756
}
756757

757758
toJSON(){
758-
if(!isURLThis(this))
759+
if(!isURL(this))
759760
thrownewERR_INVALID_THIS('URL');
760761
returnthis[context].href;
761762
}
@@ -813,14 +814,6 @@ ObjectDefineProperties(URL, {
813814
revokeObjectURL: kEnumerableProperty,
814815
});
815816

816-
functioninitSearchParams(url,init){
817-
if(!init){
818-
url[searchParams]=[];
819-
return;
820-
}
821-
url[searchParams]=parseParams(init);
822-
}
823-
824817
// application/x-www-form-urlencoded parser
825818
// Ref: https://url.spec.whatwg.org/#concept-urlencoded-parser
826819
functionparseParams(qs){
@@ -1139,8 +1132,7 @@ function domainToUnicode(domain) {
11391132
functionurlToHttpOptions(url){
11401133
constoptions={
11411134
protocol: url.protocol,
1142-
hostname: typeofurl.hostname==='string'&&
1143-
StringPrototypeStartsWith(url.hostname,'[') ?
1135+
hostname: url.hostname&&StringPrototypeStartsWith(url.hostname,'[') ?
11441136
StringPrototypeSlice(url.hostname,1,-1) :
11451137
url.hostname,
11461138
hash: url.hash,
@@ -1311,6 +1303,6 @@ module.exports = {
13111303
domainToASCII,
13121304
domainToUnicode,
13131305
urlToHttpOptions,
1314-
searchParamsSymbol: searchParams,
13151306
encodeStr,
1307+
isURL,
13161308
};

‎test/parallel/test-whatwg-url-properties.js‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,13 @@ const { URL, URLSearchParams, format } = require('url');
7373
assert.strictEqual(params.size,3);
7474
}
7575

76+
{
77+
constu=newURL('https://abc.com/?q=old');
78+
consts=u.searchParams;
79+
u.href='http://abc.com/?q=new';
80+
assert.strictEqual(s.get('q'),'new');
81+
}
82+
7683
functionstringifyName(name){
7784
if(typeofname==='symbol'){
7885
const{ description }=name;

0 commit comments

Comments
 (0)