diff options
Diffstat (limited to '')
-rw-r--r-- | src/bun.js/api/server.zig | 75 | ||||
-rw-r--r-- | test/bun.js/serve.test.ts | 80 |
2 files changed, 153 insertions, 2 deletions
diff --git a/src/bun.js/api/server.zig b/src/bun.js/api/server.zig index 531d4830b..ebe27f6e1 100644 --- a/src/bun.js/api/server.zig +++ b/src/bun.js/api/server.zig @@ -470,6 +470,77 @@ pub const ServerConfig = struct { } }; +const HTTPStatusText = struct { + pub fn get(code: u16) ?[]const u8 { + return switch (code) { + 100 => "100 Continue", + 101 => "101 Switching protocols", + 102 => "102 Processing", + 103 => "103 Early Hints", + 200 => "200 OK", + 201 => "201 Created", + 202 => "202 Accepted", + 203 => "203 Non-Authoritative Information", + 204 => "204 No Content", + 205 => "205 Reset Content", + 206 => "206 Partial Content", + 207 => "207 Multi-Status", + 208 => "208 Already Reported", + 226 => "226 IM Used", + 300 => "300 Multiple Choices", + 301 => "301 Moved Permanently", + 302 => "302 Found", + 303 => "303 See Other", + 304 => "304 Not Modified", + 305 => "305 Use Proxy", + 306 => "306 Switch Proxy", + 307 => "307 Temporary Redirect", + 308 => "308 Permanent Redirect", + 400 => "400 Bad Request", + 401 => "401 Unauthorized", + 402 => "402 Payment Required", + 403 => "403 Forbidden", + 404 => "404 Not Found", + 405 => "405 Method Not Allowed", + 406 => "406 Not Acceptable", + 407 => "407 Proxy Authentication Required", + 408 => "408 Request Timeout", + 409 => "409 Conflict", + 410 => "410 Gone", + 411 => "411 Length Required", + 412 => "412 Precondition Failed", + 413 => "413 Payload Too Large", + 414 => "414 URI Too Long", + 415 => "415 Unsupported Media Type", + 416 => "416 Range Not Satisfiable", + 417 => "417 Expectation Failed", + 418 => "418 I'm a Teapot", + 421 => "421 Misdirected Request", + 422 => "422 Unprocessable Entity", + 423 => "423 Locked", + 424 => "424 Failed Dependency", + 425 => "425 Too Early", + 426 => "426 Upgrade Required", + 428 => "428 Precondition Required", + 429 => "429 Too Many Requests", + 431 => "431 Request Header Fields Too Large", + 451 => "451 Unavailable For Legal Reasons", + 500 => "500 Internal Server Error", + 501 => "501 Not Implemented", + 502 => "502 Bad Gateway", + 503 => "503 Service Unavailable", + 504 => "504 Gateway Timeout", + 505 => "505 HTTP Version Not Supported", + 506 => "506 Variant Also Negotiates", + 507 => "507 Insufficient Storage", + 508 => "508 Loop Detected", + 510 => "510 Not Extended", + 511 => "511 Network Authentication Required", + else => null, + }; + } +}; + pub fn NewRequestContextStackAllocator(comptime RequestContext: type, comptime count: usize) type { // Pre-allocate up to 2048 requests // use a bitset to track which ones are used @@ -1006,8 +1077,8 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp std.debug.assert(!this.has_written_status); this.has_written_status = true; - if (status == 302) { - this.resp.writeStatus("302 Found"); + if (HTTPStatusText.get(status)) |text| { + this.resp.writeStatus(text); } else { this.resp.writeStatus(std.fmt.bufPrint(&status_text_buf, "{d} HM", .{status}) catch unreachable); } diff --git a/test/bun.js/serve.test.ts b/test/bun.js/serve.test.ts index ea175dca5..91b57a738 100644 --- a/test/bun.js/serve.test.ts +++ b/test/bun.js/serve.test.ts @@ -598,3 +598,83 @@ it("should support reloading", async () => { expect(await response2.text()).toBe("second"); server.stop(); }); + +describe("status code text", () => { + const fixture = { + 200: "OK", + 201: "Created", + 202: "Accepted", + 203: "Non-Authoritative Information", + 204: "No Content", + 205: "Reset Content", + 206: "Partial Content", + 207: "Multi-Status", + 208: "Already Reported", + 226: "IM Used", + 300: "Multiple Choices", + 301: "Moved Permanently", + 302: "Found", + 303: "See Other", + 304: "Not Modified", + 305: "Use Proxy", + 306: "Switch Proxy", + 307: "Temporary Redirect", + 308: "Permanent Redirect", + 400: "Bad Request", + 401: "Unauthorized", + 402: "Payment Required", + 403: "Forbidden", + 404: "Not Found", + 405: "Method Not Allowed", + 406: "Not Acceptable", + 407: "Proxy Authentication Required", + 408: "Request Timeout", + 409: "Conflict", + 410: "Gone", + 411: "Length Required", + 412: "Precondition Failed", + 413: "Payload Too Large", + 414: "URI Too Long", + 415: "Unsupported Media Type", + 416: "Range Not Satisfiable", + 417: "Expectation Failed", + 418: "I'm a Teapot", + 421: "Misdirected Request", + 422: "Unprocessable Entity", + 423: "Locked", + 424: "Failed Dependency", + 425: "Too Early", + 426: "Upgrade Required", + 428: "Precondition Required", + 429: "Too Many Requests", + 431: "Request Header Fields Too Large", + 451: "Unavailable For Legal Reasons", + 500: "Internal Server Error", + 501: "Not Implemented", + 502: "Bad Gateway", + 503: "Service Unavailable", + 504: "Gateway Timeout", + 505: "HTTP Version Not Supported", + 506: "Variant Also Negotiates", + 507: "Insufficient Storage", + 508: "Loop Detected", + 510: "Not Extended", + 511: "Network Authentication Required", + }; + + for (let code in fixture) { + it(`should return ${code} ${fixture[code]}`, async () => { + const server = serve({ + port: port++, + fetch(req) { + return new Response("hey", { status: +code }); + }, + }); + + const response = await fetch(`http://${server.hostname}:${server.port}`); + expect(response.status).toBe(parseInt(code)); + expect(response.statusText).toBe(fixture[code]); + server.stop(); + }); + } +}); |