2
0
mirror of https://github.com/tenrok/axios.git synced 2026-05-15 11:59:42 +03:00
Files
axios/test/unit/adapters/http.js
T
Maxime Bargiel 495d5fb133 Resolving proxy from env on redirect (#4436)
* Fixing http adapter to recompute proxy on redirect

Redirections can target different hosts or change the protocol
from http to https or vice versa. When the proxy option is
inferred from the environment, it should be recomputed when
the protocol or host changes because the proxy host can differ
or even whether to proxy or not can differ.

* Fixing proxy protocol handling

1) setProxy now changes request options protocol when using a proxy with explicit protocol.
2) As a result, selection of the correct transport can be simplified.
3) Legacy agent selection needs to be moved done accordingly. (Is 'agent' option even still used?)

* Using proxy-from-env library to handle proxy env vars

The proxy-from-env library is a popular, lightweight library that is
very easy to use and covers a few more cases, not to mention it has
extensive test coverage.

* Fixing proxy auth handling

* Adding test proving env vars are re-resolved on redirect

* Revert unnecessary change

* Fixing proxy beforeRedirect regression

* Fixing lint errors

* Revert "Fixing lint errors"

This reverts commit 2de3cabc60db2444e63a699bae9ec45531218a84.

* Revert "Fixing proxy beforeRedirect regression"

This reverts commit 57befc3215980e47333fedc1e9028cc22297540b.
2022-05-11 19:24:14 +02:00

1288 lines
39 KiB
JavaScript

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 pkg = require('./../../../package.json');
var server, proxy;
var AxiosError = require('../../../lib/core/AxiosError');
var FormData = require('form-data');
var formidable = require('formidable');
describe('supports http with nodejs', function () {
afterEach(function () {
if (server) {
server.close();
server = null;
}
if (proxy) {
proxy.close();
proxy = null;
}
delete process.env.http_proxy;
delete process.env.https_proxy;
delete process.env.no_proxy;
});
it('should throw an error if the timeout property is not parsable as a number', 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: { strangeTimeout: 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, AxiosError.ERR_BAD_OPTION_VALUE);
assert.equal(error.message, 'error trying to parse `config.timeout` to int');
done();
}, 300);
});
});
it('should parse 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 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 respect the timeoutErrorMessage 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,
timeoutErrorMessage: 'oops, timeout',
}).then(function (res) {
success = true;
}).catch(function (err) {
error = err;
failure = true;
});
setTimeout(function () {
assert.strictEqual(success, false, 'request should not succeed');
assert.strictEqual(failure, true, 'request should fail');
assert.strictEqual(error.code, 'ECONNABORTED');
assert.strictEqual(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');
res.end(JSON.stringify(data));
}).listen(4444, function () {
axios.get('http://localhost:4444/').then(function (res) {
assert.deepEqual(res.data, data);
done();
}).catch(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');
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();
}).catch(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();
}).catch(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();
}).catch(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) {
assert.equal(error.code, AxiosError.ERR_FR_TOO_MANY_REDIRECTS);
assert.equal(error.message, 'Maximum number of redirects exceeded');
done();
});
});
});
it('should support beforeRedirect', 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: 3,
beforeRedirect: function (options) {
if (options.path === '/foo') {
throw new Error(
'Provided path is not allowed'
);
}
}
}).catch(function (error) {
assert.equal(error.message, 'Provided path is not allowed');
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(done);
});
});
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');
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();
}).catch(done);
});
});
});
it('should support gunzip error handling', function (done) {
server = http.createServer(function (req, res) {
res.setHeader('Content-Type', 'application/json');
res.setHeader('Content-Encoding', 'gzip');
res.end('invalid response');
}).listen(4444, function () {
axios.get('http://localhost:4444/').catch(function (error) {
done();
}).catch(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();
}).catch(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();
}).catch(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();
}).catch(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' }; // wonky casing to ensure caseless comparison
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();
}).catch(done);
});
});
it('should provides a default User-Agent header', function (done) {
server = http.createServer(function (req, res) {
res.end(req.headers['user-agent']);
}).listen(4444, function () {
axios.get('http://localhost:4444/').then(function (res) {
assert.ok(/^axios\/[\d.]+$/.test(res.data), `User-Agent header does not match: ${res.data}`);
done();
}).catch(done);
});
});
it('should allow the User-Agent header to be overridden', function (done) {
server = http.createServer(function (req, res) {
res.end(req.headers['user-agent']);
}).listen(4444, function () {
var headers = { 'UsEr-AgEnT': 'foo bar' }; // wonky casing to ensure caseless comparison
axios.get('http://localhost:4444/', { headers }).then(function (res) {
assert.equal(res.data, 'foo bar');
done();
}).catch(done);
});
});
it('should allow the Content-Length header to be overridden', function (done) {
server = http.createServer(function (req, res) {
assert.strictEqual(req.headers['content-length'], '42');
res.end();
}).listen(4444, function () {
var headers = { 'CoNtEnT-lEnGtH': '42' }; // wonky casing to ensure caseless comparison
axios.post('http://localhost:4444/', 'foo', { headers }).then(function () {
done();
}).catch(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.message, 'Request body larger than maxBodyLength limit');
done();
}, 100);
});
});
it('should display error while parsing params', function (done) {
server = http.createServer(function () {
}).listen(4444, function () {
axios.get('http://localhost:4444/', {
params: {
errorParam: new Date(undefined),
},
}).catch(function (err) {
assert.deepEqual(err.exists, true)
done();
}).catch(done);
});
});
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(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();
});
}).catch(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('expected ENOENT error');
}).catch(function (err) {
assert.equal(err.message, `ENOENT: no such file or directory, open \'${notExitPath}\'`);
done();
}).catch(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();
});
}).catch(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();
}).catch(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(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();
}).catch(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();
}).catch(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(done);
});
});
});
it('should re-evaluate proxy on redirect when proxy set via env var', function (done) {
process.env.http_proxy = 'http://localhost:4000'
process.env.no_proxy = 'localhost:4000'
var proxyUseCount = 0;
server = http.createServer(function (req, res) {
res.setHeader('Location', 'http://localhost:4000/redirected');
res.statusCode = 302;
res.end();
}).listen(4444, function () {
proxy = http.createServer(function (request, response) {
var parsed = url.parse(request.url);
if (parsed.pathname === '/redirected') {
response.statusCode = 200;
response.end();
return;
}
proxyUseCount += 1;
var opts = {
host: parsed.hostname,
port: parsed.port,
path: parsed.path,
protocol: parsed.protocol,
rejectUnauthorized: false
};
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.setHeader('Location', res.headers.location);
response.end(body);
});
});
}).listen(4000, function () {
axios.get('http://localhost:4444/').then(function(res) {
assert.equal(res.status, 200);
assert.equal(proxyUseCount, 1);
done();
}).catch(done);
});
});
});
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();
}).catch(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();
}).catch(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();
}).catch(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();
}).catch(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();
}).catch(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 CanceledError object');
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();
}).catch(done);
});
});
it('should support HTTP protocol', function (done) {
server = http.createServer(function (req, res) {
setTimeout(function () {
res.end();
}, 1000);
}).listen(4444, function () {
axios.get('http://localhost:4444')
.then(function (res) {
assert.equal(res.request.agent.protocol, 'http:');
done();
})
})
});
it('should support HTTPS protocol', function (done) {
server = http.createServer(function (req, res) {
setTimeout(function () {
res.end();
}, 1000);
}).listen(4444, function () {
axios.get('https://www.google.com')
.then(function (res) {
assert.equal(res.request.agent.protocol, 'https:');
done();
})
})
});
it('should return malformed URL', function (done) {
var success = false, failure = false;
var error;
server = http.createServer(function (req, res) {
setTimeout(function () {
res.end();
}, 1000);
}).listen(4444, function () {
axios.get('tel:484-695-3408')
.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, 'Unsupported protocol tel:');
done();
}, 300);
})
});
it('should return unsupported protocol', function (done) {
var success = false, failure = false;
var error;
server = http.createServer(function (req, res) {
setTimeout(function () {
res.end();
}, 1000);
}).listen(4444, function () {
axios.get('ftp:google.com')
.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, 'Unsupported protocol ftp:');
done();
}, 300);
})
});
it('should supply a user-agent if one is not specified', function (done) {
server = http.createServer(function (req, res) {
assert.equal(req.headers["user-agent"], 'axios/' + pkg.version);
res.end();
}).listen(4444, function () {
axios.get('http://localhost:4444/'
).then(function (res) {
done();
}).catch(done);
});
});
it('should omit a user-agent if one is explicitly disclaimed', function (done) {
server = http.createServer(function (req, res) {
assert.equal("user-agent" in req.headers, false);
assert.equal("User-Agent" in req.headers, false);
res.end();
}).listen(4444, function () {
axios.get('http://localhost:4444/', {
headers: {
"User-Agent": null
}
}).then(function (res) {
done();
}).catch(done);
});
});
it('should throw an error if http server that aborts a chunked request', function (done) {
server = http.createServer(function (req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.write('chunk 1');
setTimeout(function () {
res.write('chunk 2');
}, 100);
setTimeout(function() {
res.destroy();
}, 200);
}).listen(4444, function () {
var success = false, failure = false;
var error;
axios.get('http://localhost:4444/aborted', {
timeout: 500
}).then(function (res) {
success = true;
}).catch(function (err) {
error = err;
failure = true;
}).then(function () {
assert.strictEqual(success, false, 'request should not succeed');
assert.strictEqual(failure, true, 'request should fail');
assert.strictEqual(error.code, 'ERR_BAD_RESPONSE');
assert.strictEqual(error.message, 'maxContentLength size of -1 exceeded');
done();
}).catch(done);
});
});
it('should able to cancel multiple requests with CancelToken', function(done){
server = http.createServer(function (req, res) {
res.end('ok');
}).listen(4444, function () {
var CancelToken = axios.CancelToken;
var source = CancelToken.source();
var canceledStack = [];
var requests = [1, 2, 3, 4, 5].map(function(id){
return axios
.get('/foo/bar', { cancelToken: source.token })
.catch(function (e) {
if (!axios.isCancel(e)) {
throw e;
}
canceledStack.push(id);
});
});
source.cancel("Aborted by user");
Promise.all(requests).then(function () {
assert.deepStrictEqual(canceledStack.sort(), [1, 2, 3, 4, 5])
}).then(done, done);
});
});
it('should allow passing FormData', function (done) {
var form = new FormData();
var file1= Buffer.from('foo', 'utf8');
form.append('foo', "bar");
form.append('file1', file1, {
filename: 'bar.jpg',
filepath: 'temp/bar.jpg',
contentType: 'image/jpeg'
});
server = http.createServer(function (req, res) {
var receivedForm = new formidable.IncomingForm();
receivedForm.parse(req, function (err, fields, files) {
if (err) {
return done(err);
}
res.end(JSON.stringify({
fields: fields,
files: files
}));
});
}).listen(4444, function () {
axios.post('http://localhost:4444/', form, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(function (res) {
assert.deepStrictEqual(res.data.fields,{foo: 'bar'});
assert.strictEqual(res.data.files.file1.mimetype,'image/jpeg');
assert.strictEqual(res.data.files.file1.originalFilename,'temp/bar.jpg');
assert.strictEqual(res.data.files.file1.size,3);
done();
}).catch(done);
});
});
});