Skip to content
Open
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
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,11 @@ app.use(staticCache(path.join(__dirname, 'public'), {
- `options.maxAge` (int) - cache control max age for the files, `0` by default.
- `options.cacheControl` (str) - optional cache control header. Overrides `options.maxAge`.
- `options.buffer` (bool) - store the files in memory instead of streaming from the filesystem on each request.
- `options.gzip` (bool) - when request's accept-encoding include gzip, files will compressed by gzip.
- `options.usePrecompiledGzip` (bool) - try use gzip files, loaded from disk, like nginx gzip_static
- `options.gzip` (bool) - when the request's Accept-Encoding includes gzip, files will be compressed using gzip.
- `options.charset` (str | function) - optional charset appended to `Content-Type`. If a function is supplied, it receives `(file, type)`, where `file` is the relative file path, and can return a charset per file.
- `options.usePrecompiledGzip` (bool) - try to use gzip files, loaded from disk, like nginx gzip_static
- `options.alias` (obj) - object map of aliases. See below.
- `options.prefix` (str) - the url prefix you wish to add, default to `''`.
- `options.prefix` (str) - the URL prefix you wish to add, defaults to `''`.
- `options.dynamic` (bool) - dynamic load file which not cached on initialization.
- `options.filter` (function | array) - filter files at init dir, for example - skip non build (source) files. If array set - allow only listed files
- `options.preload` (bool) - caches the assets on initialization or not, default to `true`. always work together with `options.dynamic`.
Expand Down
9 changes: 8 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,14 @@ function loadFile(name, dir, options, files) {

obj.cacheControl = options.cacheControl
obj.maxAge = (typeof obj.maxAge === 'number' ? obj.maxAge : options.maxAge) || 0
obj.type = obj.mime = mime.lookup(pathname) || 'application/octet-stream'
var type = mime.lookup(pathname) || 'application/octet-stream'
var charset = typeof options.charset === 'function'
? options.charset(name, type)
: options.charset
obj.mime = type
obj.type = charset
? type + '; charset=' + charset
: type
obj.mtime = stats.mtime
obj.length = stats.size
obj.md5 = crypto.createHash('md5').update(buffer).digest('base64')
Expand Down
70 changes: 70 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,76 @@ describe('Static Cache', function () {
})
})

it('should serve files with configured charset', function (done) {
var app = new Koa()
app.use(staticCache(path.join(__dirname, '..'), {
charset: 'iso-8859-1',
filter(file) {
return file === 'README.md'
}
}))
var server = app.listen()

Comment on lines +153 to +162

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Add a test to cover unknown MIME types with a configured charset to ensure the fallback MIME lookup behavior stays intact.

Specifically, please add a test where the served file has an unknown extension (e.g. foo.bin) and options.charset is set, and assert that the Content-Type is 'application/octet-stream; charset=iso-8859-1' (or equivalent). This will protect the fallback MIME type and charset concatenation behavior from regressions.

Suggested implementation:

    .expect('Content-Type', 'text/markdown; charset=iso-8859-1')
    .expect(200, done)
  })

  it('should serve files with configured charset for unknown mime types', function (done) {
    var app = new Koa()
    app.use(staticCache(path.join(__dirname, '..'), {
      charset: 'iso-8859-1',
      filter(file) {
        return file === 'foo.bin'
      }
    }))
    var server = app.listen()

    request(server)
    .get('/foo.bin')
    .expect('Content-Type', 'application/octet-stream; charset=iso-8859-1')
    .expect(200, done)
  })

For this test to pass, ensure there is a foo.bin file in the directory being served (based on your existing tests, likely the project root: path.join(__dirname, '..')). The file can be empty or contain arbitrary data; it only needs to exist so that the middleware can serve it and trigger the fallback MIME type logic.

request(server)
.get('/README.md')
.expect('Content-Type', 'text/markdown; charset=iso-8859-1')
.expect(200, done)
})

it('should serve files with configured charset for unknown mime types', function (done) {
var app = new Koa()
app.use(staticCache(path.join(__dirname, '..'), {
charset: 'iso-8859-1',
filter(file) {
return file === 'Makefile'
}
}))
var server = app.listen()

request(server)
.get('/Makefile')
.expect('Content-Type', 'application/octet-stream; charset=iso-8859-1')
.expect(200, done)
})

it('should serve files with function configured charset', function (done) {
var app = new Koa()
app.use(staticCache(path.join(__dirname, '..'), {
charset(file, type) {
return file === 'README.md' && type === 'text/markdown'
? 'windows-1252'
: undefined
},
filter(file) {
return file === 'README.md'
}
}))
var server = app.listen()

request(server)
.get('/README.md')
.expect('Content-Type', 'text/markdown; charset=windows-1252')
.expect(200, done)
})
Comment on lines +199 to +203

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Add coverage for the case where the charset function returns undefined to verify that no charset is appended.

The current test only covers when the charset function returns a string. Please also add a case where charset(file, type) returns undefined (or another falsy value) and assert that the Content-Type header omits ; charset=.... This documents the fallback behavior and guards against regressions like accidentally sending ; charset=undefined.

Suggested change
request(server)
.get('/README.md')
.expect('Content-Type', 'text/markdown; charset=windows-1252')
.expect(200, done)
})
request(server)
.get('/README.md')
.expect('Content-Type', 'text/markdown; charset=windows-1252')
.expect(200, done)
})
it('should not append charset when charset function returns undefined', function (done) {
var app = new Koa()
app.use(staticCache(path.join(__dirname, '..'), {
charset(file, type) {
// explicit undefined to exercise the "no charset" path
return undefined
},
filter(file) {
return file === 'README.md'
}
}))
var server = app.listen()
request(server)
.get('/README.md')
.expect('Content-Type', 'text/markdown')
.expect(200, done)
})


it('should not append charset when charset function returns undefined', function (done) {
var app = new Koa()
app.use(staticCache(path.join(__dirname, '..'), {
charset() {
return undefined
},
filter(file) {
return file === 'Makefile'
}
}))
var server = app.listen()

request(server)
.get('/Makefile')
.expect('Content-Type', 'application/octet-stream')
.expect(200, done)
})

it('should serve recursive files', function (done) {
request(server)
.get('/test/index.js')
Expand Down