豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit d74d95d

Browse files
ryuappyusukebe
andauthored
feat(serve-static): mimes option for serve-static (#2094)
* feat(serve-static): `mime` option for serve-static * undo getExtension() * add mime and serve-static tests * reaname mimes to baseMime * rename mime to mimes and add getMimeType() callback Co-Authored-By: Yusuke Wada <yusuke@kamawada.com> * update test description --------- Co-authored-by: Yusuke Wada <yusuke@kamawada.com>
1 parent b24f9e3 commit d74d95d

File tree

8 files changed

+67
-8
lines changed

8 files changed

+67
-8
lines changed

deno_dist/adapter/deno/serve-static.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const { open } = Deno
1010
export type ServeStaticOptions<E extends Env = Env> = {
1111
root?: string
1212
path?: string
13+
mimes?: Record<string, string>
1314
rewriteRequestPath?: (path: string) => string
1415
onNotFound?: (path: string, c: Context<E>) => void | Promise<void>
1516
}

deno_dist/utils/mime.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export const getMimeType = (filename: string): string | undefined => {
1+
export const getMimeType = (filename: string, mimes = baseMimes): string | undefined => {
22
const regexp = /\.([a-zA-Z0-9]+?)$/
33
const match = filename.match(regexp)
44
if (!match) {
@@ -12,10 +12,10 @@ export const getMimeType = (filename: string): string | undefined => {
1212
}
1313

1414
export const getExtension = (mimeType: string): string | undefined => {
15-
return Object.keys(mimes).find((ext) => mimes[ext] === mimeType)
15+
return Object.keys(baseMimes).find((ext) => baseMimes[ext] === mimeType)
1616
}
1717

18-
const mimes: Record<string, string> = {
18+
const baseMimes: Record<string, string> = {
1919
aac: 'audio/aac',
2020
abw: 'application/x-abiword',
2121
arc: 'application/x-freearc',

src/adapter/bun/serve-static.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const { file } = Bun
1212
export type ServeStaticOptions<E extends Env = Env> = {
1313
root?: string
1414
path?: string
15+
mimes?: Record<string, string>
1516
rewriteRequestPath?: (path: string) => string
1617
onNotFound?: (path: string, c: Context<E>) => void | Promise<void>
1718
}
@@ -45,7 +46,12 @@ export const serveStatic = <E extends Env = Env>(
4546
if (existsSync(path)) {
4647
const content = file(path)
4748
if (content) {
48-
const mimeType = getMimeType(path)
49+
let mimeType: string | undefined = undefined
50+
if (options.mimes) {
51+
mimeType = getMimeType(path, options.mimes) ?? getMimeType(path)
52+
} else {
53+
mimeType = getMimeType(path)
54+
}
4955
if (mimeType) {
5056
c.header('Content-Type', mimeType)
5157
}

src/adapter/cloudflare-workers/serve-static.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ const store: Record<string, string> = {
1111
'static-no-root/plain.abcdef.txt': 'That is plain.txt',
1212
'assets/static/options/foo.abcdef.txt': 'With options',
1313
'assets/.static/plain.abcdef.txt': 'In the dot',
14+
'assets/static/video/morning-routine.abcdef.m3u8': 'Good morning',
15+
'assets/static/video/morning-routine1.abcdef.ts': 'Good',
16+
'assets/static/video/introduction.abcdef.mp4': 'Let me introduce myself',
1417
}
1518
const manifest = JSON.stringify({
1619
'assets/static/plain.txt': 'assets/static/plain.abcdef.txt',
@@ -123,6 +126,37 @@ describe('With `file` options', () => {
123126
})
124127
})
125128

129+
describe('With `mimes` options', () => {
130+
const mimes = {
131+
m3u8: 'application/vnd.apple.mpegurl',
132+
ts: 'video/mp2t',
133+
}
134+
const manifest = {
135+
'assets/static/video/morning-routine.m3u8': 'assets/static/video/morning-routine.abcdef.m3u8',
136+
'assets/static/video/morning-routine1.ts': 'assets/static/video/morning-routine1.abcdef.ts',
137+
'assets/static/video/introduction.mp4': 'assets/static/video/introduction.abcdef.mp4',
138+
}
139+
140+
const app = new Hono()
141+
app.use('/static/*', serveStatic({ root: './assets', mimes, manifest }))
142+
143+
it('Should return content-type of m3u8', async () => {
144+
const res = await app.request('http://localhost/static/video/morning-routine.m3u8')
145+
expect(res.status).toBe(200)
146+
expect(res.headers.get('Content-Type')).toBe('application/vnd.apple.mpegurl')
147+
})
148+
it('Should return content-type of ts', async () => {
149+
const res = await app.request('http://localhost/static/video/morning-routine1.ts')
150+
expect(res.status).toBe(200)
151+
expect(res.headers.get('Content-Type')).toBe('video/mp2t')
152+
})
153+
it('Should return content-type of default on Hono', async () => {
154+
const res = await app.request('http://localhost/static/video/introduction.mp4')
155+
expect(res.status).toBe(200)
156+
expect(res.headers.get('Content-Type')).toBe('video/mp4')
157+
})
158+
})
159+
126160
describe('With middleware', () => {
127161
const app = new Hono()
128162
const md1 = async (c: Context, next: Next) => {

src/adapter/cloudflare-workers/serve-static.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { getContentFromKVAsset } from './utils'
99
export type ServeStaticOptions<E extends Env = Env> = {
1010
root?: string
1111
path?: string
12+
mimes?: Record<string, string>
1213
manifest: object | string
1314
namespace?: KVNamespace
1415
rewriteRequestPath?: (path: string) => string
@@ -48,7 +49,12 @@ export const serveStatic = <E extends Env = Env>(
4849
})
4950

5051
if (content) {
51-
const mimeType = getMimeType(path)
52+
let mimeType: string | undefined = undefined
53+
if (options.mimes) {
54+
mimeType = getMimeType(path, options.mimes) ?? getMimeType(path)
55+
} else {
56+
mimeType = getMimeType(path)
57+
}
5258
if (mimeType) {
5359
c.header('Content-Type', mimeType)
5460
}

src/adapter/deno/serve-static.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const { open } = Deno
1010
export type ServeStaticOptions<E extends Env = Env> = {
1111
root?: string
1212
path?: string
13+
mimes?: Record<string, string>
1314
rewriteRequestPath?: (path: string) => string
1415
onNotFound?: (path: string, c: Context<E>) => void | Promise<void>
1516
}

src/utils/mime.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import { getMimeType, getExtension } from './mime'
22

3+
const mime = {
4+
m3u8: 'application/vnd.apple.mpegurl',
5+
ts: 'video/mp2t',
6+
}
7+
38
describe('mime', () => {
49
it('getMimeType', () => {
510
expect(getMimeType('hello.txt')).toBe('text/plain; charset=utf-8')
@@ -11,6 +16,12 @@ describe('mime', () => {
1116
expect(getMimeType('indexjs.abcd')).toBeUndefined()
1217
})
1318

19+
it('getMimeType with custom mime', () => {
20+
expect(getMimeType('morning-routine.m3u8', mime)).toBe('application/vnd.apple.mpegurl')
21+
expect(getMimeType('morning-routine1.ts', mime)).toBe('video/mp2t')
22+
expect(getMimeType('readme.txt', mime)).toBeUndefined()
23+
})
24+
1425
it('getExtension', () => {
1526
expect(getExtension('audio/aac')).toBe('aac')
1627
expect(getExtension('application/x-abiword')).toBe('abw')

src/utils/mime.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export const getMimeType = (filename: string): string | undefined => {
1+
export const getMimeType = (filename: string, mimes = baseMimes): string | undefined => {
22
const regexp = /\.([a-zA-Z0-9]+?)$/
33
const match = filename.match(regexp)
44
if (!match) {
@@ -12,10 +12,10 @@ export const getMimeType = (filename: string): string | undefined => {
1212
}
1313

1414
export const getExtension = (mimeType: string): string | undefined => {
15-
return Object.keys(mimes).find((ext) => mimes[ext] === mimeType)
15+
return Object.keys(baseMimes).find((ext) => baseMimes[ext] === mimeType)
1616
}
1717

18-
const mimes: Record<string, string> = {
18+
const baseMimes: Record<string, string> = {
1919
aac: 'audio/aac',
2020
abw: 'application/x-abiword',
2121
arc: 'application/x-freearc',

0 commit comments

Comments
 (0)