Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions runtime_tests/bun/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,21 @@ import { basicAuth } from '../../src/middleware/basic-auth'
import { jwt } from '../../src/middleware/jwt'
import { HonoRequest } from '../../src/request'
import { stream, streamSSE } from '../..//src/helper/streaming'
import os from 'node:os'
import { unlink } from 'node:fs/promises'

// Test just only minimal patterns.
// Because others are tested well in Cloudflare Workers environment already.

Bun.env.NAME = 'Bun'

// BEGIN: for staticServe absolute path
const homedir = os.homedir()
const absolute_path_file = `${homedir}/test-serve-static-hono-bun.css`
// temporary creation, will be deleted
await Bun.write(absolute_path_file, 'body {background-color: blue;}')
// END

describe('Basic', () => {
const app = new Hono()
app.get('/a/:foo', (c) => {
Expand Down Expand Up @@ -88,6 +97,7 @@ describe('Serve Static Middleware', () => {
'/favicon-notfound.ico',
serveStatic({ path: './runtime_tests/bun/favicon-notfound.ico', onNotFound })
)
app.use('/test-serve-static-hono-bun.css', serveStatic({ path: absolute_path_file }))
app.use('/favicon-notfound.ico', async (c, next) => {
await next()
c.header('X-Custom', 'Bun')
Expand Down Expand Up @@ -116,6 +126,15 @@ describe('Serve Static Middleware', () => {
expect(res.headers.get('Content-Type')).toBe('image/x-icon')
})

it('Should return static file with absolute path correctly', async () => {
const res = await app.request(new Request('http://localhost/test-serve-static-hono-bun.css'))
await res.arrayBuffer()
expect(res.status).toBe(200)
expect(res.headers.get('Content-Type')).toBe('text/css; charset=utf-8')
// deleting 'test-serve-static-hono-bun.css'
await unlink(absolute_path_file)
})

it('Should return 404 response', async () => {
const res = await app.request(new Request('http://localhost/favicon-notfound.ico'))
expect(res.status).toBe(404)
Expand Down
6 changes: 4 additions & 2 deletions src/adapter/bun/serve-static.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ export const serveStatic = <E extends Env = Env>(
): MiddlewareHandler => {
return async function serveStatic(c, next) {
const getContent = async (path: string) => {
path = `./${path}`
// let absolute path be, otherwise add './'
path = path.startsWith('/') ? path : `./${path}`
// @ts-ignore
const file = Bun.file(path)
return (await file.exists()) ? file : null
}
const pathResolve = (path: string) => {
return `./${path}`
// let absolute path be, otherwise add './'
return path.startsWith('/') ? path : `./${path}`
}
const isDir = async (path: string) => {
let isDir
Expand Down
9 changes: 6 additions & 3 deletions src/utils/filepath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ export const getFilePathWithoutDefaultDocument = (
return
}

// /foo.html => foo.html
filename = filename.replace(/^\.?[\/\\]/, '')
// ./foo.html => foo.html
// ignore /foo.html as it's intentionally absolute path
filename = filename.replace(/^\.[\/\\]/, '')

// foo\bar.txt => foo/bar.txt
filename = filename.replace(/\\/, '/')
Expand All @@ -50,7 +51,9 @@ export const getFilePathWithoutDefaultDocument = (

// ./assets/foo.html => assets/foo.html
let path = root ? root + '/' + filename : filename
path = path.replace(/^\.?\//, '')

// ignore absolute path e.g. /assets/foo.css
path = path.replace(/^\.\//, '')

return path
}