mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
### What does this PR do? Fixes #24817 ### How did you verify your code works? Test --------- Co-authored-by: taylor.fish <contact@taylor.fish>
This commit is contained in:
@@ -29,9 +29,11 @@ pub const InitFromBytesOptions = struct {
|
||||
/// Ownership of `blob` is transferred to this function.
|
||||
pub fn initFromAnyBlob(blob: *const AnyBlob, options: InitFromBytesOptions) *StaticRoute {
|
||||
var headers = bun.handleOom(Headers.from(options.headers, bun.default_allocator, .{ .body = blob }));
|
||||
if (options.mime_type) |mime_type| {
|
||||
if (headers.getContentType() == null) {
|
||||
if (headers.getContentType() == null) {
|
||||
if (options.mime_type) |mime_type| {
|
||||
bun.handleOom(headers.append("Content-Type", mime_type.value));
|
||||
} else if (blob.hasContentTypeFromUser()) {
|
||||
bun.handleOom(headers.append("Content-Type", blob.contentType()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +94,7 @@ pub fn fromJS(globalThis: *jsc.JSGlobalObject, argument: jsc.JSValue) bun.JSErro
|
||||
// The user may want to pass in the same Response object multiple endpoints
|
||||
// Let's let them do that.
|
||||
const bodyValue = response.getBodyValue();
|
||||
const was_string = bodyValue.wasString();
|
||||
bodyValue.toBlobIfPossible();
|
||||
|
||||
const blob: AnyBlob = brk: {
|
||||
@@ -151,6 +154,10 @@ pub fn fromJS(globalThis: *jsc.JSGlobalObject, argument: jsc.JSValue) bun.JSErro
|
||||
.allocator = bun.default_allocator,
|
||||
};
|
||||
|
||||
if (was_string and headers.getContentType() == null) {
|
||||
bun.handleOom(headers.append("Content-Type", bun.http.MimeType.Table.@"text/plain; charset=utf-8".slice()));
|
||||
}
|
||||
|
||||
// Generate ETag if not already present
|
||||
if (headers.get("etag") == null) {
|
||||
if (blob.slice().len > 0) {
|
||||
|
||||
@@ -272,6 +272,14 @@ pub const Value = union(Tag) {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn wasString(this: *const Value) bool {
|
||||
return switch (this.*) {
|
||||
.InternalBlob => |*blob| blob.was_string,
|
||||
.WTFStringImpl => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
||||
pub const heap_breakdown_label = "BodyValue";
|
||||
pub const ValueError = union(enum) {
|
||||
AbortReason: jsc.CommonAbortReason,
|
||||
|
||||
@@ -246,7 +246,6 @@ pub const html = MimeType.initComptime("text/html;charset=utf-8", .html);
|
||||
pub const json = MimeType.initComptime("application/json;charset=utf-8", .json);
|
||||
pub const transpiled_json = javascript;
|
||||
pub const text = MimeType.initComptime("text/plain;charset=utf-8", .html);
|
||||
pub const text_plain = MimeType.initComptime("text/plain;charset=utf-8", .text);
|
||||
pub const wasm = MimeType.initComptime(
|
||||
"application/wasm",
|
||||
.wasm,
|
||||
|
||||
62
test/regression/issue/24817.test.ts
Normal file
62
test/regression/issue/24817.test.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
// https://github.com/oven-sh/bun/issues/24817
|
||||
// Unicode not working with static route
|
||||
import { expect, test } from "bun:test";
|
||||
|
||||
test("static routes should handle unicode correctly", async () => {
|
||||
using server = Bun.serve({
|
||||
port: 0,
|
||||
routes: {
|
||||
"/dynamic": () => new Response("▲"),
|
||||
"/static": new Response("▲"),
|
||||
"/unicode-string": new Response("こんにちは世界"),
|
||||
"/emoji": new Response("🎉🚀✨"),
|
||||
},
|
||||
});
|
||||
|
||||
const baseUrl = server.url.href;
|
||||
|
||||
// Test basic unicode character
|
||||
{
|
||||
const staticResp = await fetch(`${baseUrl}/static`);
|
||||
|
||||
const staticText = await staticResp.text();
|
||||
expect(staticText).toBe("▲");
|
||||
expect(staticResp.headers.get("content-type")).toBe("text/plain; charset=utf-8");
|
||||
}
|
||||
|
||||
// Test Japanese characters
|
||||
{
|
||||
const resp = await fetch(`${baseUrl}/unicode-string`);
|
||||
const text = await resp.text();
|
||||
|
||||
expect(text).toBe("こんにちは世界");
|
||||
expect(resp.headers.get("content-type")).toBe("text/plain; charset=utf-8");
|
||||
}
|
||||
|
||||
// Test emoji
|
||||
{
|
||||
const resp = await fetch(`${baseUrl}/emoji`);
|
||||
const text = await resp.text();
|
||||
|
||||
expect(text).toBe("🎉🚀✨");
|
||||
expect(resp.headers.get("content-type")).toBe("text/plain; charset=utf-8");
|
||||
}
|
||||
});
|
||||
|
||||
test("static routes with explicit content-type should not override", async () => {
|
||||
using server = Bun.serve({
|
||||
port: 0,
|
||||
routes: {
|
||||
"/custom": new Response("▲", { headers: { "content-type": "text/html" } }),
|
||||
},
|
||||
});
|
||||
|
||||
const baseUrl = server.url.href;
|
||||
|
||||
const resp = await fetch(`${baseUrl}/custom`);
|
||||
const text = await resp.text();
|
||||
|
||||
expect(text).toBe("▲");
|
||||
// Should respect the explicit content-type
|
||||
expect(resp.headers.get("content-type")).toBe("text/html");
|
||||
});
|
||||
Reference in New Issue
Block a user