Skip to content
Merged
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
2 changes: 1 addition & 1 deletion src/serve-static.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ export const serveStatic = <E extends Env = any>(
let result
const size = stats.size
const range = c.req.header('range') || ''
c.header('Last-Modified', stats.mtime.toUTCString())

if (c.req.method == 'HEAD' || c.req.method == 'OPTIONS') {
c.header('Content-Length', size.toString())
Expand All @@ -177,7 +178,6 @@ export const serveStatic = <E extends Env = any>(
result = c.body(createStreamBody(createReadStream(path)), 200)
} else {
c.header('Accept-Ranges', 'bytes')
c.header('Date', stats.birthtime.toUTCString())

const parts = range.replace(/bytes=/, '').split('-', 2)
const start = parseInt(parts[0], 10) || 0
Expand Down
12 changes: 12 additions & 0 deletions test/serve-static.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,10 @@ describe('Serve Static Middleware', () => {

it('Should return correct headers and data for text', async () => {
const res = await request(server).get('/static/plain.txt')
const stats = statSync(path.join(__dirname, 'assets', 'static', 'plain.txt'))
expect(res.status).toBe(200)
expect(res.headers['content-type']).toBe('text/plain; charset=utf-8')
expect(res.headers['last-modified']).toBe(stats.mtime.toUTCString())
expect(res.text).toBe('This is plain.txt')
})

Expand Down Expand Up @@ -136,18 +138,24 @@ describe('Serve Static Middleware', () => {

it('Should return 200 response to HEAD request', async () => {
const res = await request(server).head('/static/plain.txt')
const stats = statSync(path.join(__dirname, 'assets', 'static', 'plain.txt'))
expect(res.status).toBe(200)
expect(res.headers['content-type']).toBe('text/plain; charset=utf-8')
expect(res.headers['content-length']).toBe('17')
expect(res.headers['last-modified']).toBe(stats.mtime.toUTCString())
expect(res.text).toBe(undefined)
})

it('Should return correct headers and data with range headers', async () => {
let res = await request(server).get('/static/plain.txt').set('range', '0-9')
const stats = statSync(path.join(__dirname, 'assets', 'static', 'plain.txt'))
expect(res.status).toBe(206)
expect(res.headers['content-type']).toBe('text/plain; charset=utf-8')
expect(res.headers['content-length']).toBe('10')
expect(res.headers['content-range']).toBe('bytes 0-9/17')
expect(res.headers['last-modified']).toBe(stats.mtime.toUTCString())
expect(res.headers['date']).not.toBe(stats.mtime.toUTCString())
expect(res.headers['date']).not.toBe(stats.birthtime.toUTCString())
expect(res.text.length).toBe(10)
expect(res.text).toBe('This is pl')

Expand Down Expand Up @@ -230,16 +238,20 @@ describe('Serve Static Middleware', () => {
it('Should return a pre-compressed zstd response - /static-with-precompressed/hello.txt', async () => {
// Check if it returns a normal response
let res = await request(server).get('/static-with-precompressed/hello.txt')
let stats = statSync(path.join(__dirname, 'assets', 'static-with-precompressed', 'hello.txt'))
expect(res.status).toBe(200)
expect(res.headers['content-length']).toBe('20')
expect(res.headers['last-modified']).toBe(stats.mtime.toUTCString())
expect(res.text).toBe('Hello Not Compressed')

res = await request(server)
.get('/static-with-precompressed/hello.txt')
.set('Accept-Encoding', 'zstd')
stats = statSync(path.join(__dirname, 'assets', 'static-with-precompressed', 'hello.txt.zst'))
expect(res.status).toBe(200)
expect(res.headers['content-length']).toBe('21')
expect(res.headers['content-encoding']).toBe('zstd')
expect(res.headers['last-modified']).toBe(stats.mtime.toUTCString())
expect(res.headers['vary']).toBe('Accept-Encoding')
expect(res.text).toBe('Hello zstd Compressed')
})
Expand Down
Loading