Skip to content

Commit

Permalink
feat: use cookiejar synchronous functions by default (#107)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: The property name for passing cookiejar to agent has been changed.

BREAKING CHANGE: Changed to use cookiejar synchronous functions by default. If you use an asynchronous cookiejar store, set cookies.async_UNSTABLE to true.
  • Loading branch information
3846masa committed May 7, 2022
1 parent 6260bdc commit 2bf68bb
Show file tree
Hide file tree
Showing 25 changed files with 682 additions and 417 deletions.
20 changes: 10 additions & 10 deletions node:http/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import http from 'node:http';
import https from 'node:https';
import type http from 'node:http';
import type https from 'node:https';

import { CookieJar } from 'tough-cookie';
import type { CookieJar } from 'tough-cookie';

type Primitive = string | number | bigint | boolean | symbol | null | undefined;
type Diff<T, U> = T extends U ? never : T;
export interface CookieOptions {
async_UNSTABLE?: true;
jar: CookieJar;
}

export type CookieAgentOptions = {
jar: CookieJar;
cookies?: CookieOptions | undefined;
};

type CookieAgent<BaseAgent extends http.Agent> = BaseAgent & {
jar: CookieJar;
};
type CookieAgent<BaseAgent extends http.Agent> = BaseAgent;

export function createCookieAgent<
BaseAgent extends http.Agent = http.Agent,
Expand All @@ -21,7 +21,7 @@ export function createCookieAgent<
>(
BaseAgent: new (options: BaseAgentOptions, ...rest: BaseAgentConstructorRestParams) => BaseAgent,
): new (
options: Diff<BaseAgentOptions, Primitive> & CookieAgentOptions,
options: BaseAgentOptions & CookieAgentOptions,
...rest: BaseAgentConstructorRestParams
) => CookieAgent<BaseAgent>;

Expand Down
File renamed without changes.
60 changes: 28 additions & 32 deletions src/node:http/__tests__/agentkeepalive.spec.mts
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,25 @@ import { createCookieAgent } from '../index.js';

const KeepAliveCookieAgent = createCookieAgent(KeepAliveAgent);

export function request(url: string, options: http.RequestOptions) {
const req = http.request(url, options);

export function request(url: string, options: http.RequestOptions, payload?: unknown) {
const promise = new Promise<http.IncomingMessage>((resolve, reject) => {
const req = http.request(url, options);
req.on('response', (res) => {
res.on('error', (err) => reject(err));
// eslint-disable-next-line @typescript-eslint/no-empty-function
res.on('data', () => {});
res.on('end', () => resolve(res));
});
req.on('error', (err) => reject(err));
req.end(payload);
});
req.end();

return { promise, req };
return promise;
}

test('should set cookies to CookieJar from Set-Cookie header', async (t) => {
const jar = new CookieJar();
const agent = new KeepAliveCookieAgent({ jar });
const agent = new KeepAliveCookieAgent({ cookies: { jar } });

const { port } = await createTestServer([
(_req, res) => {
Expand All @@ -37,11 +36,10 @@ test('should set cookies to CookieJar from Set-Cookie header', async (t) => {
},
]);

const { promise } = request(`http://localhost:${port}`, {
await request(`http://localhost:${port}`, {
agent,
method: 'GET',
});
await promise;

const cookies = await jar.getCookies(`http://localhost:${port}`);
t.is(cookies.length, 1);
Expand All @@ -52,7 +50,7 @@ test('should set cookies to CookieJar from Set-Cookie header', async (t) => {

test('should set cookies to CookieJar from multiple Set-Cookie headers', async (t) => {
const jar = new CookieJar();
const agent = new KeepAliveCookieAgent({ jar });
const agent = new KeepAliveCookieAgent({ cookies: { jar } });

const { port } = await createTestServer([
(_req, res) => {
Expand All @@ -61,11 +59,10 @@ test('should set cookies to CookieJar from multiple Set-Cookie headers', async (
},
]);

const { promise } = request(`http://localhost:${port}`, {
await request(`http://localhost:${port}`, {
agent,
method: 'GET',
});
await promise;

const cookies = await jar.getCookies(`http://localhost:${port}`);
t.is(cookies.length, 2);
Expand All @@ -77,7 +74,7 @@ test('should set cookies to CookieJar from multiple Set-Cookie headers', async (

test('should send cookies from CookieJar', async (t) => {
const jar = new CookieJar();
const agent = new KeepAliveCookieAgent({ jar });
const agent = new KeepAliveCookieAgent({ cookies: { jar } });

const { port } = await createTestServer([
(req, res) => {
Expand All @@ -88,18 +85,17 @@ test('should send cookies from CookieJar', async (t) => {

await jar.setCookie('key=value', `http://localhost:${port}`);

const { promise } = request(`http://localhost:${port}`, {
await request(`http://localhost:${port}`, {
agent,
method: 'GET',
});
await promise;

t.plan(1);
});

test('should send cookies from both a request options and CookieJar', async (t) => {
const jar = new CookieJar();
const agent = new KeepAliveCookieAgent({ jar });
const agent = new KeepAliveCookieAgent({ cookies: { jar } });

const { port } = await createTestServer([
(req, res) => {
Expand All @@ -110,19 +106,18 @@ test('should send cookies from both a request options and CookieJar', async (t)

await jar.setCookie('key1=value1', `http://localhost:${port}`);

const { promise } = request(`http://localhost:${port}`, {
await request(`http://localhost:${port}`, {
agent,
headers: { Cookie: 'key2=value2' },
method: 'GET',
});
await promise;

t.plan(1);
});

test('should send cookies from a request options when the key is duplicated in both a request options and CookieJar', async (t) => {
const jar = new CookieJar();
const agent = new KeepAliveCookieAgent({ jar });
const agent = new KeepAliveCookieAgent({ cookies: { jar } });

const { port } = await createTestServer([
(req, res) => {
Expand All @@ -133,22 +128,21 @@ test('should send cookies from a request options when the key is duplicated in b

await jar.setCookie('key=notexpected', `http://localhost:${port}`);

const { promise } = request(`http://localhost:${port}`, {
await request(`http://localhost:${port}`, {
agent,
headers: { Cookie: 'key=expected' },
method: 'GET',
});
await promise;

t.plan(1);
});

test('should emit error when CookieJar#getCookies throws error.', async (t) => {
const jar = new CookieJar();
jar.getCookies = async () => {
jar.getCookiesSync = () => {
throw new Error('Error');
};
const agent = new KeepAliveCookieAgent({ jar });
const agent = new KeepAliveCookieAgent({ cookies: { jar } });

const { port } = await createTestServer([
(_req, res) => {
Expand All @@ -157,21 +151,22 @@ test('should emit error when CookieJar#getCookies throws error.', async (t) => {
},
]);

const { promise } = request(`http://localhost:${port}`, {
agent,
method: 'GET',
await t.throwsAsync(() => {
return request(`http://localhost:${port}`, {
agent,
method: 'GET',
});
});
await t.throwsAsync(() => promise);

t.plan(1);
});

test('should emit error when CookieJar#setCookie throws error.', async (t) => {
const jar = new CookieJar();
jar.setCookie = async () => {
jar.setCookieSync = () => {
throw new Error('Error');
};
const agent = new KeepAliveCookieAgent({ jar });
const agent = new KeepAliveCookieAgent({ cookies: { jar } });

const { port } = await createTestServer([
(_req, res) => {
Expand All @@ -180,11 +175,12 @@ test('should emit error when CookieJar#setCookie throws error.', async (t) => {
},
]);

const { promise } = request(`http://localhost:${port}`, {
agent,
method: 'GET',
await t.throwsAsync(() => {
return request(`http://localhost:${port}`, {
agent,
method: 'GET',
});
});
await t.throwsAsync(() => promise);

t.plan(1);
});
22 changes: 11 additions & 11 deletions src/node:http/__tests__/axios.spec.mts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { HttpCookieAgent } from '../index.js';

test('should set cookies to CookieJar from Set-Cookie header', async (t) => {
const jar = new CookieJar();
const agent = new HttpCookieAgent({ jar });
const agent = new HttpCookieAgent({ cookies: { jar } });

const { port } = await createTestServer([
(_req, res) => {
Expand All @@ -29,7 +29,7 @@ test('should set cookies to CookieJar from Set-Cookie header', async (t) => {

test('should set cookies to CookieJar from multiple Set-Cookie headers', async (t) => {
const jar = new CookieJar();
const agent = new HttpCookieAgent({ jar });
const agent = new HttpCookieAgent({ cookies: { jar } });

const { port } = await createTestServer([
(_req, res) => {
Expand All @@ -52,7 +52,7 @@ test('should set cookies to CookieJar from multiple Set-Cookie headers', async (

test('should send cookies from CookieJar', async (t) => {
const jar = new CookieJar();
const agent = new HttpCookieAgent({ jar });
const agent = new HttpCookieAgent({ cookies: { jar } });

const { port } = await createTestServer([
(req, res) => {
Expand All @@ -72,7 +72,7 @@ test('should send cookies from CookieJar', async (t) => {

test('should send cookies from both a request options and CookieJar', async (t) => {
const jar = new CookieJar();
const agent = new HttpCookieAgent({ jar });
const agent = new HttpCookieAgent({ cookies: { jar } });

const { port } = await createTestServer([
(req, res) => {
Expand All @@ -93,7 +93,7 @@ test('should send cookies from both a request options and CookieJar', async (t)

test('should send cookies from a request options when the key is duplicated in both a request options and CookieJar', async (t) => {
const jar = new CookieJar();
const agent = new HttpCookieAgent({ jar });
const agent = new HttpCookieAgent({ cookies: { jar } });

const { port } = await createTestServer([
(req, res) => {
Expand All @@ -114,7 +114,7 @@ test('should send cookies from a request options when the key is duplicated in b

test('should send cookies from the first response when redirecting', async (t) => {
const jar = new CookieJar();
const agent = new HttpCookieAgent({ jar });
const agent = new HttpCookieAgent({ cookies: { jar } });

const { port } = await createTestServer([
(_req, res) => {
Expand All @@ -138,10 +138,10 @@ test('should send cookies from the first response when redirecting', async (t) =

test('should emit error when CookieJar#getCookies throws error.', async (t) => {
const jar = new CookieJar();
jar.getCookies = async () => {
jar.getCookiesSync = () => {
throw new Error('Error');
};
const agent = new HttpCookieAgent({ jar });
const agent = new HttpCookieAgent({ cookies: { jar } });

const { port } = await createTestServer([
(_req, res) => {
Expand All @@ -161,10 +161,10 @@ test('should emit error when CookieJar#getCookies throws error.', async (t) => {

test('should emit error when CookieJar#setCookie throws error.', async (t) => {
const jar = new CookieJar();
jar.setCookie = async () => {
jar.setCookieSync = () => {
throw new Error('Error');
};
const agent = new HttpCookieAgent({ jar });
const agent = new HttpCookieAgent({ cookies: { jar } });

const { port } = await createTestServer([
(_req, res) => {
Expand All @@ -186,7 +186,7 @@ test('should send post data when keepalive is enabled', async (t) => {
const times = 2;

const jar = new CookieJar();
const agent = new HttpCookieAgent({ jar, keepAlive: true });
const agent = new HttpCookieAgent({ cookies: { jar }, keepAlive: true });

const { port } = await createTestServer(
Array.from({ length: times }, (_, idx) => {
Expand Down
Loading

0 comments on commit 2bf68bb

Please sign in to comment.