Skip to content

Commit 705b845

Browse files
authored
Make header case and order consistent (#10)
2 parents be4e8e4 + 8fbdcb6 commit 705b845

File tree

5 files changed

+57
-10
lines changed

5 files changed

+57
-10
lines changed

src/Request.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,12 @@ export class Request {
169169
public async text(): Promise<string> {
170170
return (await this.blob()).text();
171171
}
172+
173+
/**
174+
* Response headers that the Response to this request should include.
175+
* @internal
176+
*/
177+
public _responseHeaders = new Headers();
172178
}
173179

174180
export namespace Request {

src/Server.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,12 @@ class Server {
3636
this.server.listen(options.port);
3737
}
3838

39+
/** @internal **/
40+
public get _keepAliveTimeout() {
41+
return this.server.keepAliveTimeout;
42+
}
43+
3944
private async listener(req: http.IncomingMessage, res: http.ServerResponse) {
40-
res.setHeaders(this.globalHeaders);
4145
let apiRequest: Request;
4246
try {
4347
apiRequest = Request.incomingMessage(req);
@@ -52,11 +56,13 @@ class Server {
5256
throw e;
5357
}
5458

59+
for (const [key, value] of this.globalHeaders)
60+
apiRequest._responseHeaders.set(key, value);
61+
5562
if (this.copyOrigin) {
56-
res.appendHeader("Access-Control-Allow-Origin", apiRequest.headers.get("Origin") ?? "*");
57-
res.appendHeader("Vary", "Origin");
63+
apiRequest._responseHeaders.set("access-control-allow-origin", apiRequest.headers.get("Origin") ?? "*");
64+
apiRequest._responseHeaders.set("vary", "origin");
5865
}
59-
res.setHeaders(this.globalHeaders);
6066

6167
let response: Response;
6268
try {

src/response/BufferResponse.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import http from "node:http";
2+
import {Request} from "../Request.js";
3+
import {Server} from "../Server.js";
24
import {Response} from "./Response.js";
35

46
/**
@@ -10,9 +12,15 @@ export abstract class BufferResponse extends Response {
1012
*/
1113
protected abstract readBuffer(): Uint8Array | Promise<Uint8Array>;
1214

13-
protected override async send(res: http.ServerResponse): Promise<void> {
14-
this.writeHead(res);
15+
protected override async send(res: http.ServerResponse, server: Server, req?: Request): Promise<void> {
1516
const buffer = await this.readBuffer();
17+
if (req !== undefined) {
18+
if (res.chunkedEncoding)
19+
req._responseHeaders.set("transfer-encoding", "chunked");
20+
else
21+
req._responseHeaders.set("content-length", buffer.byteLength.toString());
22+
}
23+
this.writeHead(res, server, req);
1624
res.end(buffer);
1725
}
1826
}

src/response/EmptyResponse.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import http from "node:http";
2+
import {Request} from "../Request.js";
3+
import {Server} from "../Server.js";
24
import {Response} from "./Response.js";
35

46
/**
@@ -14,8 +16,15 @@ export class EmptyResponse extends Response {
1416
super(status, headers);
1517
}
1618

17-
protected override send(res: http.ServerResponse): void {
19+
/*protected override send(res: http.ServerResponse): void {
1820
this.writeHead(res);
1921
res.end();
22+
}*/
23+
24+
protected override send(res: http.ServerResponse, server: Server, req?: Request): void {
25+
if (req !== undefined)
26+
req._responseHeaders.set("content-length", "0");
27+
this.writeHead(res, server, req);
28+
res.end();
2029
}
2130
}

src/response/Response.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,27 @@ export abstract class Response {
3636
/**
3737
* Set the HTTP response status code and headers.
3838
*/
39-
protected writeHead(res: http.ServerResponse) {
40-
res.statusCode = this.statusCode;
41-
res.setHeaders(this.headers);
39+
protected writeHead(res: http.ServerResponse, server: Server, req?: Request) {
40+
const headers = new Headers(this.headers);
41+
if (req !== undefined)
42+
for (const [key, value] of req._responseHeaders)
43+
headers.set(key, value);
44+
if (!headers.has("date"))
45+
headers.set("date", new Date().toUTCString());
46+
if (
47+
req === undefined
48+
|| req.headers.get("connection") === "close"
49+
|| !res.shouldKeepAlive
50+
)
51+
headers.set("connection", "close");
52+
else {
53+
headers.set("connection", "keep-alive");
54+
headers.set("keep-alive", "timeout=" + server._keepAliveTimeout);
55+
}
56+
for (const [key, value] of Array.from(headers.entries())
57+
.sort((a, b) => a[0].localeCompare(b[0])))
58+
res.setHeader(key, value);
59+
res.writeHead(this.statusCode);
4260
}
4361

4462
/**

0 commit comments

Comments
 (0)