* Gets the information retrieved from the metadata service. * Invokes the callback with {proxyAddress, localDataCenter, contactPoints} as result * @param {CloudOptions} cloudOptions * @param {Function} callback
(cloudOptions, callback)
| 143 | * @param {Function} callback |
| 144 | */ |
| 145 | function getMetadataServiceInfo(cloudOptions, callback) { |
| 146 | const regex = /^(.+?):(\d+)(.*)$/; |
| 147 | const matches = regex.exec(cloudOptions.serviceUrl); |
| 148 | callback = utils.callbackOnce(callback); |
| 149 | |
| 150 | if (!matches || matches.length !== 4) { |
| 151 | throw new TypeError('url should be composed of host, port number and path, without scheme'); |
| 152 | } |
| 153 | |
| 154 | const requestOptions = Object.assign({ |
| 155 | hostname: matches[1], |
| 156 | port: matches[2], |
| 157 | path: matches[3] || undefined, |
| 158 | timeout: cloudOptions.clientOptions.socketOptions.connectTimeout |
| 159 | }, cloudOptions.clientOptions.sslOptions); |
| 160 | |
| 161 | const req = https.get(requestOptions, res => { |
| 162 | let data = ''; |
| 163 | |
| 164 | utils.log('verbose', `Connected to metadata service with SSL/TLS protocol ${res.socket.getProtocol()}`, {}, cloudOptions); |
| 165 | |
| 166 | res |
| 167 | .on('data', chunk => data += chunk.toString()) |
| 168 | .on('end', () => { |
| 169 | if (res.statusCode !== 200) { |
| 170 | return callback(getServiceRequestError(new Error(`Obtained http status ${res.statusCode}`), requestOptions)); |
| 171 | } |
| 172 | |
| 173 | let message; |
| 174 | |
| 175 | try { |
| 176 | message = JSON.parse(data); |
| 177 | |
| 178 | if (!message || !message['contact_info']) { |
| 179 | throw new TypeError('contact_info should be defined in response'); |
| 180 | } |
| 181 | |
| 182 | } catch (err) { |
| 183 | return callback(getServiceRequestError(err, requestOptions, true)); |
| 184 | } |
| 185 | |
| 186 | const contactInfo = message['contact_info']; |
| 187 | |
| 188 | // Set the connect options |
| 189 | cloudOptions.clientOptions.contactPoints = contactInfo['contact_points']; |
| 190 | cloudOptions.clientOptions.localDataCenter = contactInfo['local_dc']; |
| 191 | cloudOptions.clientOptions.sni = { address: contactInfo['sni_proxy_address'] }; |
| 192 | |
| 193 | callback(); |
| 194 | }); |
| 195 | }); |
| 196 | |
| 197 | req.on('error', err => callback(getServiceRequestError(err, requestOptions))); |
| 198 | |
| 199 | // We need to both set the timeout in the requestOptions and invoke ClientRequest#setTimeout() |
| 200 | // to handle all possible scenarios, for some reason... (tested with one OR the other and didn't fully work) |
| 201 | // Setting the also the timeout handler, aborting will emit 'error' and close |
| 202 | req.setTimeout(cloudOptions.clientOptions.socketOptions.connectTimeout, () => req.abort()); |
nothing calls this directly
no test coverage detected