mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
151 lines
4.7 KiB
TypeScript
151 lines
4.7 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
const { HTTPParser, ConnectionsList } = process.binding("http_parser");
|
|
|
|
const kOnHeaders = HTTPParser.kOnHeaders;
|
|
const kOnHeadersComplete = HTTPParser.kOnHeadersComplete;
|
|
|
|
describe("HTTPParser.prototype.close", () => {
|
|
test("does not double free", () => {
|
|
const parser = new HTTPParser();
|
|
|
|
expect(parser.close()).toBeUndefined();
|
|
expect(parser.close()).toBeUndefined();
|
|
});
|
|
|
|
test("does not segfault calling other methods after close", () => {
|
|
const parser = new HTTPParser();
|
|
|
|
parser.close();
|
|
|
|
// implementation was freed, test each method
|
|
|
|
expect(parser.close()).toBeUndefined();
|
|
expect(parser.free()).toBeUndefined();
|
|
expect(parser.remove()).toBeUndefined();
|
|
expect(parser.execute()).toBeUndefined();
|
|
expect(parser.finish()).toBeUndefined();
|
|
expect(parser.initialize()).toBeUndefined();
|
|
expect(parser.pause()).toBeUndefined();
|
|
expect(parser.resume()).toBeUndefined();
|
|
expect(parser.consume()).toBeUndefined();
|
|
expect(parser.unconsume()).toBeUndefined();
|
|
expect(parser.getCurrentBuffer()).toBeUndefined();
|
|
expect(parser.duration()).toBeUndefined();
|
|
expect(parser.headersCompleted()).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe("HTTPParser.prototype.finish", () => {
|
|
test("returns error for invalid state", async () => {
|
|
const parser = new HTTPParser();
|
|
parser.initialize(HTTPParser.REQUEST, {});
|
|
const input = Buffer.from("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n");
|
|
const { promise, resolve } = Promise.withResolvers();
|
|
parser[kOnHeadersComplete] = function () {
|
|
expect(this.finish()).toMatchObject({
|
|
code: "HPE_INVALID_EOF_STATE",
|
|
reason: "Invalid EOF state",
|
|
bytesParsed: 0,
|
|
});
|
|
resolve();
|
|
};
|
|
parser.execute(input);
|
|
await promise;
|
|
expect(parser.finish()).toBeUndefined();
|
|
expect(parser.execute(Buffer.from("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"))).toBe(37);
|
|
});
|
|
|
|
test("basic", async () => {
|
|
const parser = new HTTPParser();
|
|
parser.initialize(HTTPParser.REQUEST, {});
|
|
expect(parser.finish()).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
test("HTTPParser.prototype.getCurrentBuffer", async () => {
|
|
const parser = new HTTPParser();
|
|
parser.initialize(HTTPParser.REQUEST, {});
|
|
|
|
const input = Buffer.from("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n");
|
|
|
|
const { promise, resolve } = Promise.withResolvers();
|
|
|
|
parser[kOnHeaders] = function () {
|
|
expect(this.getCurrentBuffer()).toEqual(input);
|
|
resolve();
|
|
};
|
|
|
|
expect(parser.getCurrentBuffer()).toEqual(Buffer.from(""));
|
|
parser.execute(input);
|
|
|
|
await promise;
|
|
});
|
|
|
|
test("HTTPParser.prototype.duration", async () => {
|
|
const parser = new HTTPParser();
|
|
parser.initialize(HTTPParser.REQUEST, {});
|
|
|
|
const input = Buffer.from("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n");
|
|
|
|
const { promise, resolve } = Promise.withResolvers();
|
|
|
|
parser[kOnHeadersComplete] = function () {
|
|
expect(this.duration()).toBeGreaterThan(0);
|
|
resolve();
|
|
};
|
|
parser.execute(input);
|
|
|
|
await promise;
|
|
});
|
|
|
|
test("HTTPParser.prototype.headersCompleted", () => {
|
|
const paresr = new HTTPParser();
|
|
paresr.initialize(HTTPParser.REQUEST, {});
|
|
expect(paresr.headersCompleted()).toBe(false);
|
|
paresr.execute(Buffer.from("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"));
|
|
expect(paresr.headersCompleted()).toBe(true);
|
|
});
|
|
|
|
describe("ConnectionsList", () => {
|
|
test("basic operations", () => {
|
|
const list = new ConnectionsList();
|
|
|
|
expect(list.all()).toEqual([]);
|
|
expect(list.idle()).toEqual([]);
|
|
expect(list.active()).toEqual([]);
|
|
expect(list.expired()).toEqual([]);
|
|
});
|
|
|
|
test("works with HTTPParser", () => {
|
|
const p1 = new HTTPParser();
|
|
p1.name = "parser1";
|
|
const p2 = new HTTPParser();
|
|
p2.name = "parser2";
|
|
const p3 = new HTTPParser();
|
|
p3.name = "parser3";
|
|
const p4 = new HTTPParser();
|
|
p4.name = "parser4";
|
|
const list = new ConnectionsList();
|
|
p1.initialize(HTTPParser.REQUEST, {}, 0, 0, list);
|
|
p2.initialize(HTTPParser.REQUEST, {}, 0, 0, list);
|
|
p3.initialize(HTTPParser.REQUEST, {}, 0, 0, list);
|
|
p4.initialize(HTTPParser.REQUEST, {}, 0, 0, list);
|
|
|
|
expect(list.all()).toEqual([p1, p2, p3, p4]);
|
|
expect(list.idle()).toEqual([]);
|
|
expect(list.active()).toEqual([p1, p2, p3, p4]);
|
|
expect(list.expired()).toEqual([]);
|
|
p2.remove();
|
|
expect(list.all()).toEqual([p1, p3, p4]);
|
|
p3.execute(Buffer.from("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n"));
|
|
expect(list.all()).toEqual([p1, p4, p3]);
|
|
|
|
p1.close();
|
|
p1.remove();
|
|
// p1 is still in the list after remove because close
|
|
// frees the implementation causing remove to not be able
|
|
// to remove it.
|
|
expect(list.all()).toEqual([p1, p4, p3]);
|
|
});
|
|
});
|