11'use strict' ;
22
3- const dns = require ( 'dns' ) ;
3+ const dns = require ( 'mz/ dns' ) ;
44const LRU = require ( 'ylru' ) ;
55const urlparse = require ( 'url' ) . parse ;
66const HttpClient = require ( './httpclient' ) ;
77const utility = require ( 'utility' ) ;
88
99const IP_REGEX = / ^ \d { 1 , 3 } \. \d { 1 , 3 } \. \d { 1 , 3 } \. \d { 1 , 3 } $ / ;
10+ const DNSLOOKUP = Symbol ( 'DNSCacheHttpClient#dnslookup' ) ;
11+ const UPDATE_DNS = Symbol ( 'DNSCacheHttpClient#updateDNS' ) ;
1012
1113class DNSCacheHttpClient extends HttpClient {
1214 constructor ( app ) {
@@ -24,20 +26,22 @@ class DNSCacheHttpClient extends HttpClient {
2426
2527 // the callback style
2628 if ( callback ) {
27- this . _dnsLookup ( url , args , ( err , result ) => {
28- if ( err ) return callback ( err ) ;
29- super . request ( result . url , result . args , callback ) ;
30- } ) ;
29+ this . app . deprecate ( '[dnscache_httpclient] Please don\'t use callback when `request()`' ) ;
30+
31+ this [ DNSLOOKUP ] ( url , args )
32+ . then ( result => {
33+ return super . request ( result . url , result . args ) ;
34+ } )
35+ . then ( result => process . nextTick ( ( ) => callback ( null , result . data , result . res ) ) )
36+ . catch ( err => process . nextTick ( ( ) => callback ( err ) ) ) ;
3137 return ;
3238 }
3339
3440 // the Promise style
35- return new Promise ( ( resolve , reject ) => {
36- this . _dnsLookup ( url , args , ( err , result ) => {
37- if ( err ) return reject ( err ) ;
38- resolve ( result ) ;
39- } ) ;
40- } ) . then ( result => super . request ( result . url , result . args ) ) ;
41+ return ( async ( ) => {
42+ const result = await this [ DNSLOOKUP ] ( url , args ) ;
43+ return super . request ( result . url , result . args ) ;
44+ } ) ( ) ;
4145 }
4246
4347 curl ( url , args , callback ) {
@@ -61,14 +65,14 @@ class DNSCacheHttpClient extends HttpClient {
6165 } ;
6266 }
6367
64- _dnsLookup ( url , args , callback ) {
68+ async [ DNSLOOKUP ] ( url , args ) {
6569 const parsed = typeof url === 'string' ? urlparse ( url ) : url ;
6670 // hostname must exists
6771 const hostname = parsed . hostname ;
6872
6973 // don't lookup when hostname is IP
7074 if ( hostname && IP_REGEX . test ( hostname ) ) {
71- return callback ( null , { url, args } ) ;
75+ return { url, args } ;
7276 }
7377
7478 args = args || { } ;
@@ -82,56 +86,45 @@ class DNSCacheHttpClient extends HttpClient {
8286 const record = this . dnsCache . get ( hostname ) ;
8387 const now = Date . now ( ) ;
8488 if ( record ) {
85- const needUpdate = now - record . timestamp >= this . dnsCacheLookupInterval ;
86- if ( needUpdate ) {
89+ if ( now - record . timestamp >= this . dnsCacheLookupInterval ) {
8790 // make sure next request don't refresh dns query
8891 record . timestamp = now ;
89- }
90- callback ( null , {
91- url : this . _formatDnsLookupUrl ( hostname , url , record . ip ) ,
92- args,
93- } ) ;
94- if ( ! needUpdate ) {
95- // no need to refresh dns record
96- return ;
97- }
98- // make sure not callback twice
99- callback = null ;
100- }
101-
102- dns . lookup ( hostname , { family : 4 } , ( err , address ) => {
103- const logger = args . ctx ? args . ctx . coreLogger : this . app . coreLogger ;
104- if ( err ) {
105- logger . warn ( '[dnscache_httpclient] dns lookup error: %s(%s) => %s' , hostname , url , err ) ;
106- // no cache, return error
107- return callback && callback ( err ) ;
92+ this . app . runInBackground ( async ( ) => {
93+ await this [ UPDATE_DNS ] ( hostname , args ) ;
94+ } ) ;
10895 }
10996
110- logger . info ( '[dnscache_httpclient] dns lookup success: %s(%s) => %s' , hostname , url , address ) ;
111- this . dnsCache . set ( hostname , {
112- timestamp : Date . now ( ) ,
113- ip : address ,
114- } ) ;
97+ return { url : formatDnsLookupUrl ( hostname , url , record . ip ) , args } ;
98+ }
11599
116- callback && callback ( null , {
117- url : this . _formatDnsLookupUrl ( hostname , url , address ) ,
118- args,
119- } ) ;
120- } ) ;
100+ const address = await this [ UPDATE_DNS ] ( hostname , args ) ;
101+ return { url : formatDnsLookupUrl ( hostname , url , address ) , args } ;
121102 }
122103
123- _formatDnsLookupUrl ( host , url , address ) {
124- if ( typeof url === 'string' ) {
125- url = url . replace ( host , address ) ;
126- } else {
127- url = utility . assign ( { } , url ) ;
128- url . hostname = url . hostname . replace ( host , address ) ;
129- if ( url . host ) {
130- url . host = url . host . replace ( host , address ) ;
131- }
104+ async [ UPDATE_DNS ] ( hostname , args ) {
105+ const logger = args . ctx ? args . ctx . coreLogger : this . app . coreLogger ;
106+ try {
107+ const [ address ] = await dns . lookup ( hostname , { family : 4 } ) ;
108+ logger . info ( '[dnscache_httpclient] dns lookup success: %s => %s' ,
109+ hostname , address ) ;
110+ this . dnsCache . set ( hostname , { timestamp : Date . now ( ) , ip : address } ) ;
111+ return address ;
112+ } catch ( err ) {
113+ err . message = `[dnscache_httpclient] dns lookup error: ${ hostname } => ${ err . message } ` ;
114+ throw err ;
132115 }
133- return url ;
134116 }
117+
135118}
136119
137120module . exports = DNSCacheHttpClient ;
121+
122+ function formatDnsLookupUrl ( host , url , address ) {
123+ if ( typeof url === 'string' ) return url . replace ( host , address ) ;
124+ const urlObj = utility . assign ( { } , url ) ;
125+ urlObj . hostname = urlObj . hostname . replace ( host , address ) ;
126+ if ( urlObj . host ) {
127+ urlObj . host = urlObj . host . replace ( host , address ) ;
128+ }
129+ return urlObj ;
130+ }
0 commit comments