Skip to content

Commit

Permalink
fix: send data correctly when keepalive is enabled (#90)
Browse files Browse the repository at this point in the history
* chore(test): call req.end from test cases to send the payload

* chore(test): add test cases for sending post data when keepalive is enabled

* fix: send data correctly when keepalive is enabled

closed #65
  • Loading branch information
3846masa committed May 2, 2022
1 parent ea38a0f commit b245a77
Show file tree
Hide file tree
Showing 12 changed files with 330 additions and 21 deletions.
29 changes: 28 additions & 1 deletion src/__tests__/axios.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { CookieJar } from 'tough-cookie';
import axios from 'axios';

import { HttpCookieAgent } from '../';
import { createTestServer } from './helpers';
import { createTestServer, readStream } from './helpers';

test('should set cookies to CookieJar from Set-Cookie header', async (t) => {
const jar = new CookieJar();
Expand Down Expand Up @@ -181,3 +181,30 @@ test('should emit error when CookieJar#setCookie throws error.', async (t) => {

t.plan(1);
});

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 { port } = await createTestServer(
Array.from({ length: times }, (_, idx) => {
return async (req, res) => {
t.is(await readStream(req), `{ "index": "${idx}" }`);
t.is(req.headers['cookie'], 'key=expected');
res.end();
};
}),
);

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

for (let idx = 0; idx < times; idx++) {
await axios.post(`http://localhost:${port}`, `{ "index": "${idx}" }`, {
httpAgent: agent,
});
}

t.plan(times * 2);
});
32 changes: 31 additions & 1 deletion src/__tests__/got.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { CookieJar } from 'tough-cookie';
import got from 'got';

import { HttpCookieAgent } from '../';
import { createTestServer } from './helpers';
import { createTestServer, readStream } from './helpers';

test('should set cookies to CookieJar from Set-Cookie header', async (t) => {
const jar = new CookieJar();
Expand Down Expand Up @@ -183,3 +183,33 @@ test('should emit error when CookieJar#setCookie throws error.', async (t) => {

t.plan(1);
});

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 { port } = await createTestServer(
Array.from({ length: times }, (_, idx) => {
return async (req, res) => {
t.is(await readStream(req), `{ "index": "${idx}" }`);
t.is(req.headers['cookie'], 'key=expected');
res.end();
};
}),
);

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

for (let idx = 0; idx < times; idx++) {
await got(`http://localhost:${port}`, {
agent: { http: agent },
method: 'POST',
body: `{ "index": "${idx}" }`,
retry: 0,
});
}

t.plan(times * 2);
});
14 changes: 14 additions & 0 deletions src/__tests__/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import http from 'http';
import httpProxy from 'http-proxy';
import { promisify } from 'util';
import { URL } from 'url';
import { Readable } from 'stream';

export async function createTestServer(
stories: http.RequestListener[],
Expand All @@ -25,6 +26,11 @@ export async function createTestServer(
}
});

server.on('clientError', (err, socket) => {
console.error(err);
socket.end();
});

return {
server,
port: serverInfo.port,
Expand Down Expand Up @@ -67,3 +73,11 @@ export async function createTestServerWithProxy(
proxyPort: serverInfo.port,
};
}

export async function readStream(stream: Readable): Promise<string> {
let data = '';
for await (const chunk of stream) {
data += chunk;
}
return data;
}
63 changes: 51 additions & 12 deletions src/__tests__/http.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { CookieJar } from 'tough-cookie';
import http from 'http';

import { HttpCookieAgent } from '../';
import { createTestServer } from './helpers';
import { createTestServer, readStream } from './helpers';

export function request(url: string, options: http.RequestOptions) {
const req = http.request(url, options);
Expand All @@ -16,7 +16,6 @@ export function request(url: string, options: http.RequestOptions) {
});
req.on('error', (err) => reject(err));
});
req.end();

return { req, promise };
}
Expand All @@ -32,10 +31,11 @@ test('should set cookies to CookieJar from Set-Cookie header', async (t) => {
},
]);

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

const cookies = await jar.getCookies(`http://localhost:${port}`);
Expand All @@ -56,10 +56,11 @@ test('should set cookies to CookieJar from multiple Set-Cookie headers', async (
},
]);

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

const cookies = await jar.getCookies(`http://localhost:${port}`);
Expand All @@ -83,10 +84,11 @@ test('should send cookies from CookieJar', async (t) => {

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

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

t.plan(1);
Expand All @@ -105,10 +107,11 @@ test('should send cookies from CookieJar when value is url-encoded', async (t) =

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

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

t.plan(1);
Expand All @@ -127,11 +130,12 @@ 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}`, {
const { promise, req } = request(`http://localhost:${port}`, {
method: 'GET',
agent,
headers: { Cookie: 'key2=value2' },
});
req.end();
await promise;

t.plan(1);
Expand All @@ -150,11 +154,12 @@ 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}`, {
const { promise, req } = request(`http://localhost:${port}`, {
method: 'GET',
agent,
headers: { Cookie: 'key=expected' },
});
req.end();
await promise;

t.plan(1);
Expand All @@ -174,10 +179,11 @@ test('should emit error when CookieJar#getCookies throws error.', async (t) => {
},
]);

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

t.plan(1);
Expand All @@ -197,10 +203,11 @@ test('should emit error when CookieJar#setCookie throws error.', async (t) => {
},
]);

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

t.plan(1);
Expand All @@ -225,19 +232,51 @@ test('should send cookies even when target is same host but different port', asy
]);

{
const { promise } = request(`http://localhost:${firstServerPort}`, {
const { promise, req } = request(`http://localhost:${firstServerPort}`, {
method: 'GET',
agent,
});
req.end();
await promise;
}
{
const { promise } = request(`http://localhost:${secondServerPort}`, {
const { promise, req } = request(`http://localhost:${secondServerPort}`, {
method: 'GET',
agent,
});
req.end();
await promise;
}

t.plan(1);
});

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 { port } = await createTestServer(
Array.from({ length: times }, (_, idx) => {
return async (req, res) => {
t.is(await readStream(req), `{ "index": "${idx}" }`);
t.is(req.headers['cookie'], 'key=expected');
res.end();
};
}),
);

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

for (let idx = 0; idx < times; idx++) {
const { promise, req } = request(`http://localhost:${port}`, {
method: 'POST',
agent,
});
req.end(`{ "index": "${idx}" }`);
await promise;
}

t.plan(times * 2);
});
29 changes: 28 additions & 1 deletion src/__tests__/needle.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { CookieJar } from 'tough-cookie';
import needle from 'needle';

import { HttpCookieAgent } from '../';
import { createTestServer } from './helpers';
import { createTestServer, readStream } from './helpers';

test('should set cookies to CookieJar from Set-Cookie header', async (t) => {
const jar = new CookieJar();
Expand Down Expand Up @@ -182,3 +182,30 @@ test('should emit error when CookieJar#setCookie throws error.', async (t) => {

t.plan(1);
});

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 { port } = await createTestServer(
Array.from({ length: times }, (_, idx) => {
return async (req, res) => {
t.is(await readStream(req), `{ "index": "${idx}" }`);
t.is(req.headers['cookie'], 'key=expected');
res.end();
};
}),
);

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

for (let idx = 0; idx < times; idx++) {
await needle('post', `http://localhost:${port}`, `{ "index": "${idx}" }`, {
agent,
});
}

t.plan(times * 2);
});
31 changes: 30 additions & 1 deletion src/__tests__/node-fetch.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { CookieJar } from 'tough-cookie';
import fetch from 'node-fetch';

import { HttpCookieAgent } from '../';
import { createTestServer } from './helpers';
import { createTestServer, readStream } from './helpers';

test('should set cookies to CookieJar from Set-Cookie header', async (t) => {
const jar = new CookieJar();
Expand Down Expand Up @@ -181,3 +181,32 @@ test('should emit error when CookieJar#setCookie throws error.', async (t) => {

t.plan(1);
});

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 { port } = await createTestServer(
Array.from({ length: times }, (_, idx) => {
return async (req, res) => {
t.is(await readStream(req), `{ "index": "${idx}" }`);
t.is(req.headers['cookie'], 'key=expected');
res.end();
};
}),
);

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

for (let idx = 0; idx < times; idx++) {
await fetch(`http://localhost:${port}`, {
method: 'POST',
body: `{ "index": "${idx}" }`,
agent,
});
}

t.plan(times * 2);
});
Loading

0 comments on commit b245a77

Please sign in to comment.