1'use strict' 2 3const test = require('tap').test 4const fs = require('fs') 5const path = require('path') 6const http = require('http') 7const https = require('https') 8const install = require('../lib/install') 9const semver = require('semver') 10const devDir = require('./common').devDir() 11const rimraf = require('rimraf') 12const gyp = require('../lib/node-gyp') 13const log = require('npmlog') 14 15log.level = 'warn' 16 17test('download over http', function (t) { 18 t.plan(2) 19 20 var server = http.createServer(function (req, res) { 21 t.strictEqual(req.headers['user-agent'], 22 'node-gyp v42 (node ' + process.version + ')') 23 res.end('ok') 24 server.close() 25 }) 26 27 var host = 'localhost' 28 server.listen(0, host, function () { 29 var port = this.address().port 30 var gyp = { 31 opts: {}, 32 version: '42' 33 } 34 var url = 'http://' + host + ':' + port 35 var req = install.test.download(gyp, {}, url) 36 req.on('response', function (res) { 37 var body = '' 38 res.setEncoding('utf8') 39 res.on('data', function (data) { 40 body += data 41 }) 42 res.on('end', function () { 43 t.strictEqual(body, 'ok') 44 }) 45 }) 46 }) 47}) 48 49test('download over https with custom ca', function (t) { 50 t.plan(3) 51 52 var cert = fs.readFileSync(path.join(__dirname, 'fixtures/server.crt'), 'utf8') 53 var key = fs.readFileSync(path.join(__dirname, 'fixtures/server.key'), 'utf8') 54 55 var cafile = path.join(__dirname, '/fixtures/ca.crt') 56 var ca = install.test.readCAFile(cafile) 57 t.strictEqual(ca.length, 1) 58 59 var options = { ca: ca, cert: cert, key: key } 60 var server = https.createServer(options, function (req, res) { 61 t.strictEqual(req.headers['user-agent'], 62 'node-gyp v42 (node ' + process.version + ')') 63 res.end('ok') 64 server.close() 65 }) 66 67 server.on('clientError', function (err) { 68 throw err 69 }) 70 71 var host = 'localhost' 72 server.listen(8000, host, function () { 73 var port = this.address().port 74 var gyp = { 75 opts: { cafile: cafile }, 76 version: '42' 77 } 78 var url = 'https://' + host + ':' + port 79 var req = install.test.download(gyp, {}, url) 80 req.on('response', function (res) { 81 var body = '' 82 res.setEncoding('utf8') 83 res.on('data', function (data) { 84 body += data 85 }) 86 res.on('end', function () { 87 t.strictEqual(body, 'ok') 88 }) 89 }) 90 }) 91}) 92 93test('download over http with proxy', function (t) { 94 t.plan(2) 95 96 var server = http.createServer(function (req, res) { 97 t.strictEqual(req.headers['user-agent'], 98 'node-gyp v42 (node ' + process.version + ')') 99 res.end('ok') 100 pserver.close(function () { 101 server.close() 102 }) 103 }) 104 105 var pserver = http.createServer(function (req, res) { 106 t.strictEqual(req.headers['user-agent'], 107 'node-gyp v42 (node ' + process.version + ')') 108 res.end('proxy ok') 109 server.close(function () { 110 pserver.close() 111 }) 112 }) 113 114 var host = 'localhost' 115 server.listen(0, host, function () { 116 var port = this.address().port 117 pserver.listen(port + 1, host, function () { 118 var gyp = { 119 opts: { 120 proxy: 'http://' + host + ':' + (port + 1) 121 }, 122 version: '42' 123 } 124 var url = 'http://' + host + ':' + port 125 var req = install.test.download(gyp, {}, url) 126 req.on('response', function (res) { 127 var body = '' 128 res.setEncoding('utf8') 129 res.on('data', function (data) { 130 body += data 131 }) 132 res.on('end', function () { 133 t.strictEqual(body, 'proxy ok') 134 }) 135 }) 136 }) 137 }) 138}) 139 140test('download over http with noproxy', function (t) { 141 t.plan(2) 142 143 var server = http.createServer(function (req, res) { 144 t.strictEqual(req.headers['user-agent'], 145 'node-gyp v42 (node ' + process.version + ')') 146 res.end('ok') 147 pserver.close(function () { 148 server.close() 149 }) 150 }) 151 152 var pserver = http.createServer(function (req, res) { 153 t.strictEqual(req.headers['user-agent'], 154 'node-gyp v42 (node ' + process.version + ')') 155 res.end('proxy ok') 156 server.close(function () { 157 pserver.close() 158 }) 159 }) 160 161 var host = 'localhost' 162 server.listen(0, host, function () { 163 var port = this.address().port 164 pserver.listen(port + 1, host, function () { 165 var gyp = { 166 opts: { 167 proxy: 'http://' + host + ':' + (port + 1), 168 noproxy: 'localhost' 169 }, 170 version: '42' 171 } 172 var url = 'http://' + host + ':' + port 173 var req = install.test.download(gyp, {}, url) 174 req.on('response', function (res) { 175 var body = '' 176 res.setEncoding('utf8') 177 res.on('data', function (data) { 178 body += data 179 }) 180 res.on('end', function () { 181 t.strictEqual(body, 'ok') 182 }) 183 }) 184 }) 185 }) 186}) 187 188test('download with missing cafile', function (t) { 189 t.plan(1) 190 var gyp = { 191 opts: { cafile: 'no.such.file' } 192 } 193 try { 194 install.test.download(gyp, {}, 'http://bad/') 195 } catch (e) { 196 t.ok(/no.such.file/.test(e.message)) 197 } 198}) 199 200test('check certificate splitting', function (t) { 201 var cas = install.test.readCAFile(path.join(__dirname, 'fixtures/ca-bundle.crt')) 202 t.plan(2) 203 t.strictEqual(cas.length, 2) 204 t.notStrictEqual(cas[0], cas[1]) 205}) 206 207// only run this test if we are running a version of Node with predictable version path behavior 208 209test('download headers (actual)', function (t) { 210 if (process.env.FAST_TEST || 211 process.release.name !== 'node' || 212 semver.prerelease(process.version) !== null || 213 semver.satisfies(process.version, '<10')) { 214 return t.skip('Skipping actual download of headers due to test environment configuration') 215 } 216 217 t.plan(17) 218 219 const expectedDir = path.join(devDir, process.version.replace(/^v/, '')) 220 rimraf(expectedDir, (err) => { 221 t.ifError(err) 222 223 const prog = gyp() 224 prog.parseArgv([]) 225 prog.devDir = devDir 226 log.level = 'warn' 227 install(prog, [], (err) => { 228 t.ifError(err) 229 230 fs.readFile(path.join(expectedDir, 'installVersion'), 'utf8', (err, data) => { 231 t.ifError(err) 232 t.strictEqual(data, '9\n', 'correct installVersion') 233 }) 234 235 fs.readdir(path.join(expectedDir, 'include/node'), (err, list) => { 236 t.ifError(err) 237 238 t.ok(list.includes('common.gypi')) 239 t.ok(list.includes('config.gypi')) 240 t.ok(list.includes('node.h')) 241 t.ok(list.includes('node_version.h')) 242 t.ok(list.includes('openssl')) 243 t.ok(list.includes('uv')) 244 t.ok(list.includes('uv.h')) 245 t.ok(list.includes('v8-platform.h')) 246 t.ok(list.includes('v8.h')) 247 t.ok(list.includes('zlib.h')) 248 }) 249 250 fs.readFile(path.join(expectedDir, 'include/node/node_version.h'), 'utf8', (err, contents) => { 251 t.ifError(err) 252 253 const lines = contents.split('\n') 254 255 // extract the 3 version parts from the defines to build a valid version string and 256 // and check them against our current env version 257 const version = ['major', 'minor', 'patch'].reduce((version, type) => { 258 const re = new RegExp(`^#define\\sNODE_${type.toUpperCase()}_VERSION`) 259 const line = lines.find((l) => re.test(l)) 260 const i = line ? parseInt(line.replace(/^[^0-9]+([0-9]+).*$/, '$1'), 10) : 'ERROR' 261 return `${version}${type !== 'major' ? '.' : 'v'}${i}` 262 }, '') 263 264 t.strictEqual(version, process.version) 265 }) 266 }) 267 }) 268}) 269