summaryrefslogtreecommitdiff
path: root/axios/test/unit
diff options
context:
space:
mode:
Diffstat (limited to 'axios/test/unit')
-rw-r--r--axios/test/unit/adapters/cert.pem17
-rw-r--r--axios/test/unit/adapters/http.js883
-rw-r--r--axios/test/unit/adapters/key.pem27
-rw-r--r--axios/test/unit/regression/SNYK-JS-AXIOS-1038255.js61
4 files changed, 988 insertions, 0 deletions
diff --git a/axios/test/unit/adapters/cert.pem b/axios/test/unit/adapters/cert.pem
new file mode 100644
index 0000000..42dcc29
--- /dev/null
+++ b/axios/test/unit/adapters/cert.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICpDCCAYwCCQDbqELLwgbPdDANBgkqhkiG9w0BAQUFADAUMRIwEAYDVQQDDAls
+b2NhbGhvc3QwHhcNMjAwNjI2MjIxMTQ3WhcNNDcxMTExMjIxMTQ3WjAUMRIwEAYD
+VQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD6
+Ogt99/dZ0UgbCuVV1RZ9n28Ov3DzrJCkjperQoXomIq3Fr4RUI1a2rwe3mtl3UzE
+1IVZVvWPGdEsEQHwXfAsP/jFGTwI3HDyOhcqzFQSKsjvqJWYkOOb+2r3SBrFlRZW
+09k/3lC+hx2XtuuG68u4Xgn3AlUvm2vplgCN7eiYcGeNwVuf2eHdOqTRTqiYCZLi
+T8GtdYMDXOrwsGZs/jUKd9U0ar/lqwMhmw07yzlVDM2MWM2tyq/asQ7Sf7vuoMFu
+oAtDJ3E+bK1k/7SNhdyP4RonhyUCkWG+mzoKDS1qgXroTiQSDUksAvOCTcj8BNIT
+ee+Lcn9FaTKNJiKiU9q/AgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAFi5ZpaUj+mU
+dsgOka+j2/njgNXux3cOjhm7z/N7LeTuDENAOrYa5b+j5JX/YM7RKHrkbXHsQbfs
+GB3ufH6QhSiCd/AdsXp/TbCE/8gdq8ykkjwVP1bvBle9oPH7x1aO/WP/odsepYUv
+o9aOZW4iNQVmwamU62ezglf3QD7HPeE4LnZueaFtuzRoC+aWT9v0MIeUPJLe3WDQ
+FEySwUuthMDJEv92/TeK0YOiunmseCu2mvdiDj6E3C9xa5q2DWgl+msu7+bPgvYO
+GuWaoNeQQGk7ebBO3Hk3IyaGx6Cbd8ty+YaZW7dUT+m7KCs1VkxdcDMjZJVWiJy4
+4HcEcKboG4Y=
+-----END CERTIFICATE-----
diff --git a/axios/test/unit/adapters/http.js b/axios/test/unit/adapters/http.js
new file mode 100644
index 0000000..497eb28
--- /dev/null
+++ b/axios/test/unit/adapters/http.js
@@ -0,0 +1,883 @@
+var axios = require('../../../index');
+var http = require('http');
+var https = require('https');
+var net = require('net');
+var url = require('url');
+var zlib = require('zlib');
+var assert = require('assert');
+var fs = require('fs');
+var path = require('path');
+var server, proxy;
+
+describe('supports http with nodejs', function () {
+
+ afterEach(function () {
+ if (server) {
+ server.close();
+ server = null;
+ }
+ if (proxy) {
+ proxy.close()
+ proxy = null;
+ }
+ if (process.env.http_proxy) {
+ delete process.env.http_proxy;
+ }
+ if (process.env.no_proxy) {
+ delete process.env.no_proxy;
+ }
+ });
+
+ it('should respect the timeout property', function (done) {
+
+ server = http.createServer(function (req, res) {
+ setTimeout(function () {
+ res.end();
+ }, 1000);
+ }).listen(4444, function () {
+ var success = false, failure = false;
+ var error;
+
+ axios.get('http://localhost:4444/', {
+ timeout: 250
+ }).then(function (res) {
+ success = true;
+ }).catch(function (err) {
+ error = err;
+ failure = true;
+ });
+
+ setTimeout(function () {
+ assert.equal(success, false, 'request should not succeed');
+ assert.equal(failure, true, 'request should fail');
+ assert.equal(error.code, 'ECONNABORTED');
+ assert.equal(error.message, 'timeout of 250ms exceeded');
+ done();
+ }, 300);
+ });
+ });
+
+ it('should allow passing JSON', function (done) {
+ var data = {
+ firstName: 'Fred',
+ lastName: 'Flintstone',
+ emailAddr: 'fred@example.com'
+ };
+
+ server = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'application/json;charset=utf-8');
+ res.end(JSON.stringify(data));
+ }).listen(4444, function () {
+ axios.get('http://localhost:4444/').then(function (res) {
+ assert.deepEqual(res.data, data);
+ done();
+ });
+ });
+ });
+
+ it('should allow passing JSON with BOM', function (done) {
+ var data = {
+ firstName: 'Fred',
+ lastName: 'Flintstone',
+ emailAddr: 'fred@example.com'
+ };
+
+ server = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'application/json;charset=utf-8');
+ var bomBuffer = Buffer.from([0xEF, 0xBB, 0xBF])
+ var jsonBuffer = Buffer.from(JSON.stringify(data));
+ res.end(Buffer.concat([bomBuffer, jsonBuffer]));
+ }).listen(4444, function () {
+ axios.get('http://localhost:4444/').then(function (res) {
+ assert.deepEqual(res.data, data);
+ done();
+ });
+ });
+ });
+
+ it('should redirect', function (done) {
+ var str = 'test response';
+
+ server = http.createServer(function (req, res) {
+ var parsed = url.parse(req.url);
+
+ if (parsed.pathname === '/one') {
+ res.setHeader('Location', '/two');
+ res.statusCode = 302;
+ res.end();
+ } else {
+ res.end(str);
+ }
+ }).listen(4444, function () {
+ axios.get('http://localhost:4444/one').then(function (res) {
+ assert.equal(res.data, str);
+ assert.equal(res.request.path, '/two');
+ done();
+ });
+ });
+ });
+
+ it('should not redirect', function (done) {
+ server = http.createServer(function (req, res) {
+ res.setHeader('Location', '/foo');
+ res.statusCode = 302;
+ res.end();
+ }).listen(4444, function () {
+ axios.get('http://localhost:4444/', {
+ maxRedirects: 0,
+ validateStatus: function () {
+ return true;
+ }
+ }).then(function (res) {
+ assert.equal(res.status, 302);
+ assert.equal(res.headers['location'], '/foo');
+ done();
+ });
+ });
+ });
+
+ it('should support max redirects', function (done) {
+ var i = 1;
+ server = http.createServer(function (req, res) {
+ res.setHeader('Location', '/' + i);
+ res.statusCode = 302;
+ res.end();
+ i++;
+ }).listen(4444, function () {
+ axios.get('http://localhost:4444/', {
+ maxRedirects: 3
+ }).catch(function (error) {
+ done();
+ });
+ });
+ });
+
+ it('should preserve the HTTP verb on redirect', function (done) {
+ server = http.createServer(function (req, res) {
+ if (req.method.toLowerCase() !== "head") {
+ res.statusCode = 400;
+ res.end();
+ return;
+ }
+
+ var parsed = url.parse(req.url);
+ if (parsed.pathname === '/one') {
+ res.setHeader('Location', '/two');
+ res.statusCode = 302;
+ res.end();
+ } else {
+ res.end();
+ }
+ }).listen(4444, function () {
+ axios.head('http://localhost:4444/one').then(function (res) {
+ assert.equal(res.status, 200);
+ done();
+ }).catch(function (err) {
+ done(err);
+ });
+ });
+ });
+
+ it('should support transparent gunzip', function (done) {
+ var data = {
+ firstName: 'Fred',
+ lastName: 'Flintstone',
+ emailAddr: 'fred@example.com'
+ };
+
+ zlib.gzip(JSON.stringify(data), function (err, zipped) {
+
+ server = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'application/json;charset=utf-8');
+ res.setHeader('Content-Encoding', 'gzip');
+ res.end(zipped);
+ }).listen(4444, function () {
+ axios.get('http://localhost:4444/').then(function (res) {
+ assert.deepEqual(res.data, data);
+ done();
+ });
+ });
+
+ });
+ });
+
+ it('should support gunzip error handling', function (done) {
+ server = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'application/json;charset=utf-8');
+ res.setHeader('Content-Encoding', 'gzip');
+ res.end('invalid response');
+ }).listen(4444, function () {
+ axios.get('http://localhost:4444/').catch(function (error) {
+ done();
+ });
+ });
+ });
+
+ it('should support disabling automatic decompression of response data', function(done) {
+ var data = 'Test data';
+
+ zlib.gzip(data, function(err, zipped) {
+ server = http.createServer(function(req, res) {
+ res.setHeader('Content-Type', 'text/html;charset=utf-8');
+ res.setHeader('Content-Encoding', 'gzip');
+ res.end(zipped);
+ }).listen(4444, function() {
+ axios.get('http://localhost:4444/', {
+ decompress: false,
+ responseType: 'arraybuffer'
+
+ }).then(function(res) {
+ assert.equal(res.data.toString('base64'), zipped.toString('base64'));
+ done();
+ });
+ });
+ });
+ });
+
+ it('should support UTF8', function (done) {
+ var str = Array(100000).join('ж');
+
+ server = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/html; charset=UTF-8');
+ res.end(str);
+ }).listen(4444, function () {
+ axios.get('http://localhost:4444/').then(function (res) {
+ assert.equal(res.data, str);
+ done();
+ });
+ });
+ });
+
+ it('should support basic auth', function (done) {
+ server = http.createServer(function (req, res) {
+ res.end(req.headers.authorization);
+ }).listen(4444, function () {
+ var user = 'foo';
+ var headers = { Authorization: 'Bearer 1234' };
+ axios.get('http://' + user + '@localhost:4444/', { headers: headers }).then(function (res) {
+ var base64 = Buffer.from(user + ':', 'utf8').toString('base64');
+ assert.equal(res.data, 'Basic ' + base64);
+ done();
+ });
+ });
+ });
+
+ it('should support basic auth with a header', function (done) {
+ server = http.createServer(function (req, res) {
+ res.end(req.headers.authorization);
+ }).listen(4444, function () {
+ var auth = { username: 'foo', password: 'bar' };
+ var headers = { Authorization: 'Bearer 1234' };
+ axios.get('http://localhost:4444/', { auth: auth, headers: headers }).then(function (res) {
+ var base64 = Buffer.from('foo:bar', 'utf8').toString('base64');
+ assert.equal(res.data, 'Basic ' + base64);
+ done();
+ });
+ });
+ });
+
+ it('should support max content length', function (done) {
+ var str = Array(100000).join('ж');
+
+ server = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/html; charset=UTF-8');
+ res.end(str);
+ }).listen(4444, function () {
+ var success = false, failure = false, error;
+
+ axios.get('http://localhost:4444/', {
+ maxContentLength: 2000
+ }).then(function (res) {
+ success = true;
+ }).catch(function (err) {
+ error = err;
+ failure = true;
+ });
+
+ setTimeout(function () {
+ assert.equal(success, false, 'request should not succeed');
+ assert.equal(failure, true, 'request should fail');
+ assert.equal(error.message, 'maxContentLength size of 2000 exceeded');
+ done();
+ }, 100);
+ });
+ });
+
+ it('should support max content length for redirected', function (done) {
+ var str = Array(100000).join('ж');
+
+ server = http.createServer(function (req, res) {
+ var parsed = url.parse(req.url);
+
+ if (parsed.pathname === '/two') {
+ res.setHeader('Content-Type', 'text/html; charset=UTF-8');
+ res.end(str);
+ } else {
+ res.setHeader('Location', '/two');
+ res.statusCode = 302;
+ res.end();
+ }
+ }).listen(4444, function () {
+ var success = false, failure = false, error;
+
+ axios.get('http://localhost:4444/one', {
+ maxContentLength: 2000
+ }).then(function (res) {
+ success = true;
+ }).catch(function (err) {
+ error = err;
+ failure = true;
+ });
+
+ setTimeout(function () {
+ assert.equal(success, false, 'request should not succeed');
+ assert.equal(failure, true, 'request should fail');
+ assert.equal(error.message, 'maxContentLength size of 2000 exceeded');
+ done();
+ }, 100);
+ });
+ });
+
+ it('should support max body length', function (done) {
+ var data = Array(100000).join('ж');
+
+ server = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/html; charset=UTF-8');
+ res.end();
+ }).listen(4444, function () {
+ var success = false, failure = false, error;
+
+ axios.post('http://localhost:4444/', {
+ data: data
+ }, {
+ maxBodyLength: 2000
+ }).then(function (res) {
+ success = true;
+ }).catch(function (err) {
+ error = err;
+ failure = true;
+ });
+
+
+ setTimeout(function () {
+ assert.equal(success, false, 'request should not succeed');
+ assert.equal(failure, true, 'request should fail');
+ assert.equal(error.code, 'ERR_FR_MAX_BODY_LENGTH_EXCEEDED');
+ assert.equal(error.message, 'Request body larger than maxBodyLength limit');
+ done();
+ }, 100);
+ });
+ });
+
+ it('should support sockets', function (done) {
+ // Different sockets for win32 vs darwin/linux
+ var socketName = './test.sock';
+
+ if (process.platform === 'win32') {
+ socketName = '\\\\.\\pipe\\libuv-test';
+ }
+
+ server = net.createServer(function (socket) {
+ socket.on('data', function () {
+ socket.end('HTTP/1.1 200 OK\r\n\r\n');
+ });
+ }).listen(socketName, function () {
+ axios({
+ socketPath: socketName,
+ url: '/'
+ })
+ .then(function (resp) {
+ assert.equal(resp.status, 200);
+ assert.equal(resp.statusText, 'OK');
+ done();
+ })
+ .catch(function (error) {
+ assert.ifError(error);
+ done();
+ });
+ });
+ });
+
+ it('should support streams', function (done) {
+ server = http.createServer(function (req, res) {
+ req.pipe(res);
+ }).listen(4444, function () {
+ axios.post('http://localhost:4444/',
+ fs.createReadStream(__filename), {
+ responseType: 'stream'
+ }).then(function (res) {
+ var stream = res.data;
+ var string = '';
+ stream.on('data', function (chunk) {
+ string += chunk.toString('utf8');
+ });
+ stream.on('end', function () {
+ assert.equal(string, fs.readFileSync(__filename, 'utf8'));
+ done();
+ });
+ });
+ });
+ });
+
+ it('should pass errors for a failed stream', function (done) {
+ var notExitPath = path.join(__dirname, 'does_not_exist');
+
+ server = http.createServer(function (req, res) {
+ req.pipe(res);
+ }).listen(4444, function () {
+ axios.post('http://localhost:4444/',
+ fs.createReadStream(notExitPath)
+ ).then(function (res) {
+ assert.fail();
+ }).catch(function (err) {
+ assert.equal(err.message, `ENOENT: no such file or directory, open \'${notExitPath}\'`);
+ done();
+ });
+ });
+ });
+
+ it('should support buffers', function (done) {
+ var buf = Buffer.alloc(1024, 'x'); // Unsafe buffer < Buffer.poolSize (8192 bytes)
+ server = http.createServer(function (req, res) {
+ assert.equal(req.headers['content-length'], buf.length.toString());
+ req.pipe(res);
+ }).listen(4444, function () {
+ axios.post('http://localhost:4444/',
+ buf, {
+ responseType: 'stream'
+ }).then(function (res) {
+ var stream = res.data;
+ var string = '';
+ stream.on('data', function (chunk) {
+ string += chunk.toString('utf8');
+ });
+ stream.on('end', function () {
+ assert.equal(string, buf.toString());
+ done();
+ });
+ });
+ });
+ });
+
+ it('should support HTTP proxies', function (done) {
+ server = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/html; charset=UTF-8');
+ res.end('12345');
+ }).listen(4444, function () {
+ proxy = http.createServer(function (request, response) {
+ var parsed = url.parse(request.url);
+ var opts = {
+ host: parsed.hostname,
+ port: parsed.port,
+ path: parsed.path
+ };
+
+ http.get(opts, function (res) {
+ var body = '';
+ res.on('data', function (data) {
+ body += data;
+ });
+ res.on('end', function () {
+ response.setHeader('Content-Type', 'text/html; charset=UTF-8');
+ response.end(body + '6789');
+ });
+ });
+
+ }).listen(4000, function () {
+ axios.get('http://localhost:4444/', {
+ proxy: {
+ host: 'localhost',
+ port: 4000
+ }
+ }).then(function (res) {
+ assert.equal(res.data, '123456789', 'should pass through proxy');
+ done();
+ });
+ });
+ });
+ });
+
+ it('should support HTTPS proxies', function (done) {
+ var options = {
+ key: fs.readFileSync(path.join(__dirname, 'key.pem')),
+ cert: fs.readFileSync(path.join(__dirname, 'cert.pem'))
+ };
+
+ server = https.createServer(options, function (req, res) {
+ res.setHeader('Content-Type', 'text/html; charset=UTF-8');
+ res.end('12345');
+ }).listen(4444, function () {
+ proxy = https.createServer(options, function (request, response) {
+ var parsed = url.parse(request.url);
+ var opts = {
+ host: parsed.hostname,
+ port: parsed.port,
+ path: parsed.path,
+ protocol: parsed.protocol,
+ rejectUnauthorized: false
+ };
+
+ https.get(opts, function (res) {
+ var body = '';
+ res.on('data', function (data) {
+ body += data;
+ });
+ res.on('end', function () {
+ response.setHeader('Content-Type', 'text/html; charset=UTF-8');
+ response.end(body + '6789');
+ });
+ });
+ }).listen(4000, function () {
+ axios.get('https://localhost:4444/', {
+ proxy: {
+ host: 'localhost',
+ port: 4000,
+ protocol: 'https'
+ },
+ httpsAgent: new https.Agent({
+ rejectUnauthorized: false
+ })
+ }).then(function (res) {
+ assert.equal(res.data, '123456789', 'should pass through proxy');
+ done();
+ }).catch(function (err) {
+ assert.fail(err);
+ done()
+ });
+ });
+ });
+ });
+
+ it('should not pass through disabled proxy', function (done) {
+ // set the env variable
+ process.env.http_proxy = 'http://does-not-exists.example.com:4242/';
+
+ server = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/html; charset=UTF-8');
+ res.end('123456789');
+ }).listen(4444, function () {
+ axios.get('http://localhost:4444/', {
+ proxy: false
+ }).then(function (res) {
+ assert.equal(res.data, '123456789', 'should not pass through proxy');
+ done();
+ });
+ });
+ });
+
+ it('should support proxy set via env var', function (done) {
+ server = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/html; charset=UTF-8');
+ res.end('4567');
+ }).listen(4444, function () {
+ proxy = http.createServer(function (request, response) {
+ var parsed = url.parse(request.url);
+ var opts = {
+ host: parsed.hostname,
+ port: parsed.port,
+ path: parsed.path
+ };
+
+ http.get(opts, function (res) {
+ var body = '';
+ res.on('data', function (data) {
+ body += data;
+ });
+ res.on('end', function () {
+ response.setHeader('Content-Type', 'text/html; charset=UTF-8');
+ response.end(body + '1234');
+ });
+ });
+
+ }).listen(4000, function () {
+ // set the env variable
+ process.env.http_proxy = 'http://localhost:4000/';
+
+ axios.get('http://localhost:4444/').then(function (res) {
+ assert.equal(res.data, '45671234', 'should use proxy set by process.env.http_proxy');
+ done();
+ });
+ });
+ });
+ });
+
+ it('should support HTTPS proxy set via env var', function (done) {
+ var options = {
+ key: fs.readFileSync(path.join(__dirname, 'key.pem')),
+ cert: fs.readFileSync(path.join(__dirname, 'cert.pem'))
+ };
+
+ server = https.createServer(options, function (req, res) {
+ res.setHeader('Content-Type', 'text/html; charset=UTF-8');
+ res.end('12345');
+ }).listen(4444, function () {
+ proxy = https.createServer(options, function (request, response) {
+ var parsed = url.parse(request.url);
+ var opts = {
+ host: parsed.hostname,
+ port: parsed.port,
+ path: parsed.path,
+ protocol: parsed.protocol,
+ rejectUnauthorized: false
+ };
+
+ https.get(opts, function (res) {
+ var body = '';
+ res.on('data', function (data) {
+ body += data;
+ });
+ res.on('end', function () {
+ response.setHeader('Content-Type', 'text/html; charset=UTF-8');
+ response.end(body + '6789');
+ });
+ });
+ }).listen(4000, function () {
+ process.env.https_proxy = 'https://localhost:4000/';
+
+ axios.get('https://localhost:4444/', {
+ httpsAgent: new https.Agent({
+ rejectUnauthorized: false
+ })
+ }).then(function (res) {
+ assert.equal(res.data, '123456789', 'should pass through proxy');
+ done();
+ }).catch(function (err) {
+ assert.fail(err);
+ done()
+ }).finally(function () {
+ process.env.https_proxy = ''
+ });
+ });
+ });
+ });
+
+ it('should not use proxy for domains in no_proxy', function (done) {
+ server = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/html; charset=UTF-8');
+ res.end('4567');
+ }).listen(4444, function () {
+ proxy = http.createServer(function (request, response) {
+ var parsed = url.parse(request.url);
+ var opts = {
+ host: parsed.hostname,
+ port: parsed.port,
+ path: parsed.path
+ };
+
+ http.get(opts, function (res) {
+ var body = '';
+ res.on('data', function (data) {
+ body += data;
+ });
+ res.on('end', function () {
+ response.setHeader('Content-Type', 'text/html; charset=UTF-8');
+ response.end(body + '1234');
+ });
+ });
+
+ }).listen(4000, function () {
+ // set the env variable
+ process.env.http_proxy = 'http://localhost:4000/';
+ process.env.no_proxy = 'foo.com, localhost,bar.net , , quix.co';
+
+ axios.get('http://localhost:4444/').then(function (res) {
+ assert.equal(res.data, '4567', 'should not use proxy for domains in no_proxy');
+ done();
+ });
+ });
+ });
+ });
+
+ it('should use proxy for domains not in no_proxy', function (done) {
+ server = http.createServer(function (req, res) {
+ res.setHeader('Content-Type', 'text/html; charset=UTF-8');
+ res.end('4567');
+ }).listen(4444, function () {
+ proxy = http.createServer(function (request, response) {
+ var parsed = url.parse(request.url);
+ var opts = {
+ host: parsed.hostname,
+ port: parsed.port,
+ path: parsed.path
+ };
+
+ http.get(opts, function (res) {
+ var body = '';
+ res.on('data', function (data) {
+ body += data;
+ });
+ res.on('end', function () {
+ response.setHeader('Content-Type', 'text/html; charset=UTF-8');
+ response.end(body + '1234');
+ });
+ });
+
+ }).listen(4000, function () {
+ // set the env variable
+ process.env.http_proxy = 'http://localhost:4000/';
+ process.env.no_proxy = 'foo.com, ,bar.net , quix.co';
+
+ axios.get('http://localhost:4444/').then(function (res) {
+ assert.equal(res.data, '45671234', 'should use proxy for domains not in no_proxy');
+ done();
+ });
+ });
+ });
+ });
+
+ it('should support HTTP proxy auth', function (done) {
+ server = http.createServer(function (req, res) {
+ res.end();
+ }).listen(4444, function () {
+ proxy = http.createServer(function (request, response) {
+ var parsed = url.parse(request.url);
+ var opts = {
+ host: parsed.hostname,
+ port: parsed.port,
+ path: parsed.path
+ };
+ var proxyAuth = request.headers['proxy-authorization'];
+
+ http.get(opts, function (res) {
+ var body = '';
+ res.on('data', function (data) {
+ body += data;
+ });
+ res.on('end', function () {
+ response.setHeader('Content-Type', 'text/html; charset=UTF-8');
+ response.end(proxyAuth);
+ });
+ });
+
+ }).listen(4000, function () {
+ axios.get('http://localhost:4444/', {
+ proxy: {
+ host: 'localhost',
+ port: 4000,
+ auth: {
+ username: 'user',
+ password: 'pass'
+ }
+ }
+ }).then(function (res) {
+ var base64 = Buffer.from('user:pass', 'utf8').toString('base64');
+ assert.equal(res.data, 'Basic ' + base64, 'should authenticate to the proxy');
+ done();
+ });
+ });
+ });
+ });
+
+ it('should support proxy auth from env', function (done) {
+ server = http.createServer(function (req, res) {
+ res.end();
+ }).listen(4444, function () {
+ proxy = http.createServer(function (request, response) {
+ var parsed = url.parse(request.url);
+ var opts = {
+ host: parsed.hostname,
+ port: parsed.port,
+ path: parsed.path
+ };
+ var proxyAuth = request.headers['proxy-authorization'];
+
+ http.get(opts, function (res) {
+ var body = '';
+ res.on('data', function (data) {
+ body += data;
+ });
+ res.on('end', function () {
+ response.setHeader('Content-Type', 'text/html; charset=UTF-8');
+ response.end(proxyAuth);
+ });
+ });
+
+ }).listen(4000, function () {
+ process.env.http_proxy = 'http://user:pass@localhost:4000/';
+
+ axios.get('http://localhost:4444/').then(function (res) {
+ var base64 = Buffer.from('user:pass', 'utf8').toString('base64');
+ assert.equal(res.data, 'Basic ' + base64, 'should authenticate to the proxy set by process.env.http_proxy');
+ done();
+ });
+ });
+ });
+ });
+
+ it('should support proxy auth with header', function (done) {
+ server = http.createServer(function (req, res) {
+ res.end();
+ }).listen(4444, function () {
+ proxy = http.createServer(function (request, response) {
+ var parsed = url.parse(request.url);
+ var opts = {
+ host: parsed.hostname,
+ port: parsed.port,
+ path: parsed.path
+ };
+ var proxyAuth = request.headers['proxy-authorization'];
+
+ http.get(opts, function (res) {
+ var body = '';
+ res.on('data', function (data) {
+ body += data;
+ });
+ res.on('end', function () {
+ response.setHeader('Content-Type', 'text/html; charset=UTF-8');
+ response.end(proxyAuth);
+ });
+ });
+
+ }).listen(4000, function () {
+ axios.get('http://localhost:4444/', {
+ proxy: {
+ host: 'localhost',
+ port: 4000,
+ auth: {
+ username: 'user',
+ password: 'pass'
+ }
+ },
+ headers: {
+ 'Proxy-Authorization': 'Basic abc123'
+ }
+ }).then(function (res) {
+ var base64 = Buffer.from('user:pass', 'utf8').toString('base64');
+ assert.equal(res.data, 'Basic ' + base64, 'should authenticate to the proxy');
+ done();
+ });
+ });
+ });
+ });
+
+ it('should support cancel', function (done) {
+ var source = axios.CancelToken.source();
+ server = http.createServer(function (req, res) {
+ // call cancel() when the request has been sent, but a response has not been received
+ source.cancel('Operation has been canceled.');
+ }).listen(4444, function () {
+ axios.get('http://localhost:4444/', {
+ cancelToken: source.token
+ }).catch(function (thrown) {
+ assert.ok(thrown instanceof axios.Cancel, 'Promise must be rejected with a Cancel obejct');
+ assert.equal(thrown.message, 'Operation has been canceled.');
+ done();
+ });
+ });
+ });
+
+ it('should combine baseURL and url', function (done) {
+ server = http.createServer(function (req, res) {
+ res.end();
+ }).listen(4444, function () {
+ axios.get('/foo', {
+ baseURL: 'http://localhost:4444/',
+ }).then(function (res) {
+ assert.equal(res.config.baseURL, 'http://localhost:4444/');
+ assert.equal(res.config.url, '/foo');
+ done();
+ });
+ });
+ });
+});
+
diff --git a/axios/test/unit/adapters/key.pem b/axios/test/unit/adapters/key.pem
new file mode 100644
index 0000000..9ce05bf
--- /dev/null
+++ b/axios/test/unit/adapters/key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEA+joLfff3WdFIGwrlVdUWfZ9vDr9w86yQpI6Xq0KF6JiKtxa+
+EVCNWtq8Ht5rZd1MxNSFWVb1jxnRLBEB8F3wLD/4xRk8CNxw8joXKsxUEirI76iV
+mJDjm/tq90gaxZUWVtPZP95Qvocdl7brhuvLuF4J9wJVL5tr6ZYAje3omHBnjcFb
+n9nh3Tqk0U6omAmS4k/BrXWDA1zq8LBmbP41CnfVNGq/5asDIZsNO8s5VQzNjFjN
+rcqv2rEO0n+77qDBbqALQydxPmytZP+0jYXcj+EaJ4clApFhvps6Cg0taoF66E4k
+Eg1JLALzgk3I/ATSE3nvi3J/RWkyjSYiolPavwIDAQABAoIBAEbMi5ndwjfAlkVI
+hPEPNKjgpnymwB/CEL7utY04akkQeBcrsSWXBBfT0exuBDczMVhzxTMs/pe5t0xf
+l4vaGG18wDeMV0cukCqJMyrh21u0jVv5+DHNtQjaTz6eQSzsbQCuOkbu8SuncUEO
++X8YUnDc8rbYCyBIOnVCAvAlg201uW0G5G9NEwJOu6cAKMKkogdHqv+FRX96C5hm
+gtbGEzpGV2vVClgMwMcX49ucluZvqLvit/yehNVd0VOtW/kuLup4R6q0abHRapDd
+95rJAhPvar4mzP+UgJrGQ9hozqhizDthBjnsmGeMBUiBCkay7OXIZpvLoCpQkti1
+WIWuikkCgYEA/oZqq71RT1nPuI7rlcjx3AeWe2EUQtKhQMJBiPx5eLLP6gII8+v2
+pD1qlmJM2eyIK0lzuskLIulTAA5Z+ejORDbvmn/DdT0CSvdrUFrcvnrRQnt2M5M2
+9VDRp6nvPE0H4kRZJrtITyLn0dv5ABf2L32i4dPCMePjKjSUygJSHrsCgYEA+61A
+cIqch/lrQTk8hG7Y6p0EJzSInFVaKuZoMYpLhlDQcVvSDIQbGgRAN6BKTdxeQ+tK
+hSxBSm2mze11aHig8GBGgdBFLaJOZRo6G+2fl+s1t1FCHfsaFhHwheZJONHMpKKd
+Qm/7L/V35QV9YG0lPZ01TM6d5lXuKsmUNvBJTc0CgYASYajAgGqn3WeX/5JZ/eoh
+ptaiUG+DJ+0HXUAYYYtwQRGs57q3yvnEAL963tyH/IIVBjf6bFyGh+07ms26s6p5
+2LHTKZj3FZHd0iKI6hb5FquYLoxpyx7z9oM9pZMmerWwDJmXp3zgYjf1uvovnItm
+AJ/LyVxD+B5GxQdd028U0wKBgG4OllZglxDzJk7wa6FyI9N89Fr8oxzSSkrmVPwN
+APfskSpxP8qPXpai8z4gDz47NtG2q/DOqIKWrtHwnF4iGibjwxFzdTz+dA/MR0r9
+P8QcbHIMy7/2lbK/B5JWYQDC5h28qs5pz8tqKZLyMqCfOiDWhX9f/zbBrxPw8KqR
+q0ylAoGAL/0kemA/Tmxpwmp0S0oCqnA4gbCgS7qnApxB09xTewc/tuvraXc3Mzea
+EvqDXLXK0R7O4E3vo0Mr23SodRVlFPevsmUUJLPJMJcxdfnSJgX+qE/UC8Ux+UMi
+eYufYRDYSslfL2rt9D7abnnbqSfsHymJKukWpElIgJTklQUru4k=
+-----END RSA PRIVATE KEY-----
diff --git a/axios/test/unit/regression/SNYK-JS-AXIOS-1038255.js b/axios/test/unit/regression/SNYK-JS-AXIOS-1038255.js
new file mode 100644
index 0000000..52c7498
--- /dev/null
+++ b/axios/test/unit/regression/SNYK-JS-AXIOS-1038255.js
@@ -0,0 +1,61 @@
+// https://snyk.io/vuln/SNYK-JS-AXIOS-1038255
+// https://github.com/axios/axios/issues/3407
+// https://github.com/axios/axios/issues/3369
+
+const axios = require('../../../index');
+const http = require('http');
+const assert = require('assert');
+
+const PROXY_PORT = 4777;
+const EVIL_PORT = 4666;
+
+
+describe('Server-Side Request Forgery (SSRF)', () => {
+ let fail = false;
+ let proxy;
+ let server;
+ let location;
+ beforeEach(() => {
+ server = http.createServer(function (req, res) {
+ fail = true;
+ res.end('rm -rf /');
+ }).listen(EVIL_PORT);
+ proxy = http.createServer(function (req, res) {
+ if (req.url === 'http://localhost:' + EVIL_PORT + '/') {
+ return res.end(JSON.stringify({
+ msg: 'Protected',
+ headers: req.headers,
+ }));
+ }
+ res.writeHead(302, { location })
+ res.end()
+ }).listen(PROXY_PORT);
+ });
+ afterEach(() => {
+ server.close();
+ proxy.close();
+ });
+ it('obeys proxy settings when following redirects', async () => {
+ location = 'http://localhost:' + EVIL_PORT;
+ let response = await axios({
+ method: "get",
+ url: "http://www.google.com/",
+ proxy: {
+ host: "localhost",
+ port: PROXY_PORT,
+ auth: {
+ username: 'sam',
+ password: 'password',
+ }
+ },
+ });
+
+ assert.strictEqual(fail, false);
+ assert.strictEqual(response.data.msg, 'Protected');
+ assert.strictEqual(response.data.headers.host, 'localhost:' + EVIL_PORT);
+ assert.strictEqual(response.data.headers['proxy-authorization'], 'Basic ' + Buffer.from('sam:password').toString('base64'));
+
+ return response;
+
+ });
+}); \ No newline at end of file