mirror of
https://github.com/tenrok/axios.git
synced 2026-06-17 19:21:29 +03:00
163da7226f
* fix: update the implementation to rather parse out the values than throw * fix: polynomal regex issues * fix: harden the security of proxy loopback
517 lines
13 KiB
JavaScript
517 lines
13 KiB
JavaScript
import { describe, it } from 'vitest';
|
|
import assert from 'assert';
|
|
import AxiosHeaders from '../../lib/core/AxiosHeaders.js';
|
|
|
|
const [nodeMajorVersion] = process.versions.node.split('.').map((v) => parseInt(v, 10));
|
|
|
|
describe('AxiosHeaders', () => {
|
|
it('should support headers argument', () => {
|
|
const headers = new AxiosHeaders({
|
|
x: 1,
|
|
y: 2,
|
|
});
|
|
|
|
assert.strictEqual(headers.get('x'), '1');
|
|
assert.strictEqual(headers.get('y'), '2');
|
|
});
|
|
|
|
describe('set', () => {
|
|
it('should support adding a single header', () => {
|
|
const headers = new AxiosHeaders();
|
|
|
|
headers.set('foo', 'bar');
|
|
|
|
assert.strictEqual(headers.get('foo'), 'bar');
|
|
});
|
|
|
|
it('should support adding multiple headers', () => {
|
|
const headers = new AxiosHeaders();
|
|
|
|
headers.set({
|
|
foo: 'value1',
|
|
bar: 'value2',
|
|
});
|
|
|
|
assert.strictEqual(headers.get('foo'), 'value1');
|
|
assert.strictEqual(headers.get('bar'), 'value2');
|
|
});
|
|
|
|
it('should support adding multiple headers from raw headers string', () => {
|
|
const headers = new AxiosHeaders();
|
|
|
|
headers.set(`foo:value1\nbar:value2`);
|
|
|
|
assert.strictEqual(headers.get('foo'), 'value1');
|
|
assert.strictEqual(headers.get('bar'), 'value2');
|
|
});
|
|
|
|
it('should not rewrite header the header if the value is false', () => {
|
|
const headers = new AxiosHeaders();
|
|
|
|
headers.set('foo', 'value1');
|
|
|
|
headers.set('foo', 'value2', false);
|
|
|
|
assert.strictEqual(headers.get('foo'), 'value1');
|
|
|
|
headers.set('foo', 'value2');
|
|
|
|
assert.strictEqual(headers.get('foo'), 'value2');
|
|
|
|
headers.set('foo', 'value3', true);
|
|
|
|
assert.strictEqual(headers.get('foo'), 'value3');
|
|
});
|
|
|
|
it('should not rewrite the header if its value is false, unless rewrite options is set to true', () => {
|
|
const headers = new AxiosHeaders();
|
|
|
|
headers.set('foo', false);
|
|
headers.set('foo', 'value2');
|
|
|
|
assert.strictEqual(headers.get('foo'), false);
|
|
|
|
headers.set('foo', 'value2', true);
|
|
|
|
assert.strictEqual(headers.get('foo'), 'value2');
|
|
});
|
|
|
|
it('should support iterables as a key-value source object', () => {
|
|
const headers = new AxiosHeaders();
|
|
|
|
headers.set(new Map([['x', '123']]));
|
|
|
|
assert.strictEqual(headers.get('x'), '123');
|
|
});
|
|
|
|
const runIfNode18OrHigher = nodeMajorVersion >= 18 ? it : it.skip;
|
|
runIfNode18OrHigher(
|
|
'should support setting multiple header values from an iterable source',
|
|
() => {
|
|
const headers = new AxiosHeaders();
|
|
const nativeHeaders = new Headers();
|
|
|
|
nativeHeaders.append('set-cookie', 'foo');
|
|
nativeHeaders.append('set-cookie', 'bar');
|
|
nativeHeaders.append('set-cookie', 'baz');
|
|
nativeHeaders.append('y', 'qux');
|
|
|
|
headers.set(nativeHeaders);
|
|
|
|
assert.deepStrictEqual(headers.get('set-cookie'), ['foo', 'bar', 'baz']);
|
|
assert.strictEqual(headers.get('y'), 'qux');
|
|
}
|
|
);
|
|
|
|
it('should sanitize invalid characters in header value', () => {
|
|
const headers = new AxiosHeaders();
|
|
|
|
headers.set('x-test', '\t safe\r\nInjected: true \u0000');
|
|
|
|
assert.strictEqual(headers.get('x-test'), 'safeInjected: true');
|
|
});
|
|
|
|
it('should sanitize invalid characters in any array header value', () => {
|
|
const headers = new AxiosHeaders();
|
|
|
|
headers.set('set-cookie', ['safe=1', ' \tunsafe=1\nInjected: true\r\n ']);
|
|
|
|
assert.deepStrictEqual(headers.get('set-cookie'), ['safe=1', 'unsafe=1Injected: true']);
|
|
});
|
|
});
|
|
|
|
it('should support uppercase name mapping for names overlapped by class methods', () => {
|
|
const headers = new AxiosHeaders({
|
|
set: 'foo',
|
|
});
|
|
|
|
headers.set('get', 'bar');
|
|
|
|
assert.strictEqual(headers.get('Set'), 'foo');
|
|
assert.strictEqual(headers.get('Get'), 'bar');
|
|
});
|
|
|
|
describe('get', () => {
|
|
describe('filter', () => {
|
|
it('should support RegExp', () => {
|
|
const headers = new AxiosHeaders();
|
|
|
|
headers.set('foo', 'bar=value1');
|
|
|
|
assert.strictEqual(headers.get('foo', /^bar=(\w+)/)[1], 'value1');
|
|
assert.strictEqual(headers.get('foo', /^foo=/), null);
|
|
});
|
|
|
|
it('should support function', () => {
|
|
const headers = new AxiosHeaders();
|
|
|
|
headers.set('foo', 'bar=value1');
|
|
|
|
assert.strictEqual(
|
|
headers.get('foo', (value, header) => {
|
|
assert.strictEqual(value, 'bar=value1');
|
|
assert.strictEqual(header, 'foo');
|
|
return value;
|
|
}),
|
|
'bar=value1'
|
|
);
|
|
assert.strictEqual(
|
|
headers.get('foo', () => false),
|
|
false
|
|
);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('has', () => {
|
|
it('should return true if the header is defined, otherwise false', () => {
|
|
const headers = new AxiosHeaders();
|
|
|
|
headers.set('foo', 'bar=value1');
|
|
|
|
assert.strictEqual(headers.has('foo'), true);
|
|
assert.strictEqual(headers.has('bar'), false);
|
|
});
|
|
|
|
describe('filter', () => {
|
|
it('should support RegExp', () => {
|
|
const headers = new AxiosHeaders();
|
|
|
|
headers.set('foo', 'bar=value1');
|
|
|
|
assert.strictEqual(headers.has('foo', /^bar=(\w+)/), true);
|
|
assert.strictEqual(headers.has('foo', /^foo=/), false);
|
|
});
|
|
|
|
it('should support function', () => {
|
|
const headers = new AxiosHeaders();
|
|
|
|
headers.set('foo', 'bar=value1');
|
|
|
|
assert.strictEqual(
|
|
headers.has('foo', (value, header) => {
|
|
assert.strictEqual(value, 'bar=value1');
|
|
assert.strictEqual(header, 'foo');
|
|
return true;
|
|
}),
|
|
true
|
|
);
|
|
assert.strictEqual(
|
|
headers.has('foo', () => false),
|
|
false
|
|
);
|
|
});
|
|
|
|
it('should support string pattern', () => {
|
|
const headers = new AxiosHeaders();
|
|
|
|
headers.set('foo', 'bar=value1');
|
|
|
|
assert.strictEqual(headers.has('foo', 'value1'), true);
|
|
assert.strictEqual(headers.has('foo', 'value2'), false);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('delete', () => {
|
|
it('should delete the header', () => {
|
|
const headers = new AxiosHeaders();
|
|
|
|
headers.set('foo', 'bar=value1');
|
|
|
|
assert.strictEqual(headers.has('foo'), true);
|
|
|
|
headers.delete('foo');
|
|
|
|
assert.strictEqual(headers.has('foo'), false);
|
|
});
|
|
|
|
it('should return true if the header has been deleted, otherwise false', () => {
|
|
const headers = new AxiosHeaders();
|
|
|
|
headers.set('foo', 'bar=value1');
|
|
|
|
assert.strictEqual(headers.delete('bar'), false);
|
|
|
|
assert.strictEqual(headers.delete('foo'), true);
|
|
});
|
|
|
|
it('should support headers array', () => {
|
|
const headers = new AxiosHeaders();
|
|
|
|
headers.set('foo', 'x');
|
|
headers.set('bar', 'y');
|
|
headers.set('baz', 'z');
|
|
|
|
assert.strictEqual(headers.delete(['foo', 'baz']), true);
|
|
|
|
assert.strictEqual(headers.has('foo'), false);
|
|
assert.strictEqual(headers.has('bar'), true);
|
|
assert.strictEqual(headers.has('baa'), false);
|
|
});
|
|
|
|
describe('filter', () => {
|
|
it('should support RegExp', () => {
|
|
const headers = new AxiosHeaders();
|
|
|
|
headers.set('foo', 'bar=value1');
|
|
|
|
assert.strictEqual(headers.has('foo'), true);
|
|
|
|
headers.delete('foo', /baz=/);
|
|
|
|
assert.strictEqual(headers.has('foo'), true);
|
|
|
|
headers.delete('foo', /bar=/);
|
|
|
|
assert.strictEqual(headers.has('foo'), false);
|
|
});
|
|
|
|
it('should support function', () => {
|
|
const headers = new AxiosHeaders();
|
|
|
|
headers.set('foo', 'bar=value1');
|
|
|
|
headers.delete('foo', (value, header) => {
|
|
assert.strictEqual(value, 'bar=value1');
|
|
assert.strictEqual(header, 'foo');
|
|
return false;
|
|
});
|
|
|
|
assert.strictEqual(headers.has('foo'), true);
|
|
|
|
assert.strictEqual(
|
|
headers.delete('foo', () => true),
|
|
true
|
|
);
|
|
|
|
assert.strictEqual(headers.has('foo'), false);
|
|
});
|
|
|
|
it('should support string pattern', () => {
|
|
const headers = new AxiosHeaders();
|
|
|
|
headers.set('foo', 'bar=value1');
|
|
|
|
assert.strictEqual(headers.has('foo'), true);
|
|
|
|
headers.delete('foo', 'baz');
|
|
|
|
assert.strictEqual(headers.has('foo'), true);
|
|
|
|
headers.delete('foo', 'bar');
|
|
|
|
assert.strictEqual(headers.has('foo'), false);
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('clear', () => {
|
|
it('should clear all headers', () => {
|
|
const headers = new AxiosHeaders({ x: 1, y: 2 });
|
|
|
|
headers.clear();
|
|
|
|
assert.deepStrictEqual({ ...headers.toJSON() }, {});
|
|
});
|
|
|
|
it('should clear matching headers if a matcher was specified', () => {
|
|
const headers = new AxiosHeaders({ foo: 1, 'x-foo': 2, bar: 3 });
|
|
|
|
assert.deepStrictEqual({ ...headers.toJSON() }, { foo: '1', 'x-foo': '2', bar: '3' });
|
|
|
|
headers.clear(/^x-/);
|
|
|
|
assert.deepStrictEqual({ ...headers.toJSON() }, { foo: '1', bar: '3' });
|
|
});
|
|
});
|
|
|
|
describe('toJSON', () => {
|
|
it('should return headers object with original headers case', () => {
|
|
const headers = new AxiosHeaders({
|
|
Foo: 'x',
|
|
bAr: 'y',
|
|
});
|
|
|
|
assert.deepStrictEqual(
|
|
{ ...headers.toJSON() },
|
|
{
|
|
Foo: 'x',
|
|
bAr: 'y',
|
|
}
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('accessors', () => {
|
|
it('should support get accessor', () => {
|
|
const headers = new AxiosHeaders({
|
|
foo: 1,
|
|
});
|
|
|
|
headers.constructor.accessor('foo');
|
|
|
|
assert.strictEqual(typeof headers.getFoo, 'function');
|
|
assert.strictEqual(headers.getFoo(), '1');
|
|
});
|
|
|
|
it('should support set accessor', () => {
|
|
const headers = new AxiosHeaders({
|
|
foo: 1,
|
|
});
|
|
|
|
headers.constructor.accessor('foo');
|
|
|
|
assert.strictEqual(typeof headers.setFoo, 'function');
|
|
headers.setFoo(2);
|
|
assert.strictEqual(headers.getFoo(), '2');
|
|
});
|
|
|
|
it('should support has accessor', () => {
|
|
const headers = new AxiosHeaders({
|
|
foo: 1,
|
|
});
|
|
|
|
headers.constructor.accessor('foo');
|
|
|
|
assert.strictEqual(typeof headers.hasFoo, 'function');
|
|
assert.strictEqual(headers.hasFoo(), true);
|
|
});
|
|
});
|
|
|
|
it('should be caseless', () => {
|
|
const headers = new AxiosHeaders({
|
|
fOo: 1,
|
|
});
|
|
|
|
assert.strictEqual(headers.get('Foo'), '1');
|
|
assert.strictEqual(headers.get('foo'), '1');
|
|
|
|
headers.set('foo', 2);
|
|
|
|
assert.strictEqual(headers.get('foO'), '2');
|
|
assert.strictEqual(headers.get('fOo'), '2');
|
|
|
|
assert.strictEqual(headers.has('fOo'), true);
|
|
|
|
headers.delete('FOO');
|
|
|
|
assert.strictEqual(headers.has('fOo'), false);
|
|
});
|
|
|
|
describe('normalize()', () => {
|
|
it('should support auto-formatting', () => {
|
|
const headers = new AxiosHeaders({
|
|
fOo: 1,
|
|
'x-foo': 2,
|
|
'y-bar-bAz': 3,
|
|
});
|
|
|
|
assert.deepStrictEqual(
|
|
{ ...headers.normalize(true).toJSON() },
|
|
{
|
|
Foo: '1',
|
|
'X-Foo': '2',
|
|
'Y-Bar-Baz': '3',
|
|
}
|
|
);
|
|
});
|
|
|
|
it('should support external defined values', () => {
|
|
const headers = new AxiosHeaders({
|
|
foo: '1',
|
|
});
|
|
|
|
headers.Foo = 2;
|
|
headers.bar = 3;
|
|
|
|
assert.deepStrictEqual(
|
|
{ ...headers.normalize().toJSON() },
|
|
{
|
|
foo: '2',
|
|
bar: '3',
|
|
}
|
|
);
|
|
});
|
|
|
|
it('should support array values', () => {
|
|
const headers = new AxiosHeaders({
|
|
foo: [1, 2, 3],
|
|
});
|
|
|
|
assert.deepStrictEqual(
|
|
{ ...headers.normalize().toJSON() },
|
|
{
|
|
foo: ['1', '2', '3'],
|
|
}
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('AxiosHeaders.concat', () => {
|
|
it('should concatenate plain headers into an AxiosHeader instance', () => {
|
|
const a = { a: 1 };
|
|
const b = { b: 2 };
|
|
const c = { c: 3 };
|
|
const headers = AxiosHeaders.concat(a, b, c);
|
|
|
|
assert.deepStrictEqual(
|
|
{ ...headers.toJSON() },
|
|
{
|
|
a: '1',
|
|
b: '2',
|
|
c: '3',
|
|
}
|
|
);
|
|
});
|
|
|
|
it('should concatenate raw headers into an AxiosHeader instance', () => {
|
|
const a = 'a:1\nb:2';
|
|
const b = 'c:3\nx:4';
|
|
const headers = AxiosHeaders.concat(a, b);
|
|
|
|
assert.deepStrictEqual(
|
|
{ ...headers.toJSON() },
|
|
{
|
|
a: '1',
|
|
b: '2',
|
|
c: '3',
|
|
x: '4',
|
|
}
|
|
);
|
|
});
|
|
|
|
it('should concatenate Axios headers into a new AxiosHeader instance', () => {
|
|
const a = new AxiosHeaders({ x: 1 });
|
|
const b = new AxiosHeaders({ y: 2 });
|
|
const headers = AxiosHeaders.concat(a, b);
|
|
|
|
assert.deepStrictEqual(
|
|
{ ...headers.toJSON() },
|
|
{
|
|
x: '1',
|
|
y: '2',
|
|
}
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('toString', () => {
|
|
it('should serialize AxiosHeader instance to a raw headers string', () => {
|
|
assert.deepStrictEqual(new AxiosHeaders({ x: 1, y: 2 }).toString(), 'x: 1\ny: 2');
|
|
});
|
|
});
|
|
|
|
describe('getSetCookie', () => {
|
|
it('should return set-cookie', () => {
|
|
const headers = new AxiosHeaders('Set-Cookie: key=val;\n' + 'Set-Cookie: key2=val2;\n');
|
|
|
|
assert.deepStrictEqual(headers.getSetCookie(), ['key=val;', 'key2=val2;']);
|
|
});
|
|
|
|
it('should return empty set-cookie', () => {
|
|
assert.deepStrictEqual(new AxiosHeaders().getSetCookie(), []);
|
|
});
|
|
});
|
|
});
|