Skip to content

Commit

Permalink
Merge a9ecfc3 into 94feedb
Browse files Browse the repository at this point in the history
  • Loading branch information
licg9999 committed Mar 14, 2020
2 parents 94feedb + a9ecfc3 commit 6c010bd
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 25 deletions.
4 changes: 4 additions & 0 deletions README.md
Expand Up @@ -131,6 +131,10 @@ the arguments are:
- `path` the file path that is being sent
- `stat` the stat object of the file that is being sent

##### gzip

Send .gz file when it exists aside origin file, defaults to false.

## Examples

### Serve files with vanilla node.js http server
Expand Down
81 changes: 56 additions & 25 deletions index.js
Expand Up @@ -16,9 +16,11 @@
var encodeUrl = require('encodeurl')
var escapeHtml = require('escape-html')
var parseUrl = require('parseurl')
var resolve = require('path').resolve
var pathLib = require('path')
var send = require('send')
var url = require('url')
var mime = send.mime
var fs = require('fs')
var urlLib = require('url')

/**
* Module exports.
Expand Down Expand Up @@ -62,35 +64,15 @@ function serveStatic (root, options) {

// setup options for send
opts.maxage = opts.maxage || opts.maxAge || 0
opts.root = resolve(root)
opts.root = pathLib.resolve(root)

// construct directory listener
var onDirectory = redirect
? createRedirectDirectoryListener()
: createNotFoundDirectoryListener()

return function serveStatic (req, res, next) {
if (req.method !== 'GET' && req.method !== 'HEAD') {
if (fallthrough) {
return next()
}

// method not allowed
res.statusCode = 405
res.setHeader('Allow', 'GET, HEAD')
res.setHeader('Content-Length', '0')
res.end()
return
}

function pipeStatic (req, res, next, path) {
var forwardError = !fallthrough
var originalUrl = parseUrl.original(req)
var path = parseUrl(req).pathname

// make sure redirect occurs at mount
if (path === '/' && originalUrl.pathname.substr(-1) !== '/') {
path = ''
}

// create send stream
var stream = send(req, path, opts)
Expand Down Expand Up @@ -123,6 +105,55 @@ function serveStatic (root, options) {

// pipe
stream.pipe(res)

return stream
}

return function serveStatic (req, res, next) {
if (req.method !== 'GET' && req.method !== 'HEAD') {
if (fallthrough) {
return next()
}

// method not allowed
res.statusCode = 405
res.setHeader('Allow', 'GET, HEAD')
res.setHeader('Content-Length', '0')
res.end()
return
}

var originalUrl = parseUrl.original(req)
var path = parseUrl(req).pathname

// make sure redirect occurs at mount
if (path === '/' && originalUrl.pathname.substr(-1) !== '/') {
path = ''
}

// check and send a gzipped or plain file
var gzipAccept =
(req.headers['Accept-Encoding'.toLowerCase()] || '').indexOf('gzip') >= 0
if (gzipAccept && opts.gzip) {
var gzipPath = pathLib.normalize('.' + pathLib.sep + path + '.gz')

fs.access(pathLib.resolve(opts.root, gzipPath), err => {
if (err) {
pipeStatic(req, res, next, path)
} else {
var stream = pipeStatic(req, res, next, gzipPath)

stream.on('headers', () => {
res.setHeader('Content-Encoding', 'gzip')

var type = stream.type(path)
if (type) res.setHeader('Content-Type', type)
})
}
})
} else {
pipeStatic(req, res, next, path)
}
}
}

Expand Down Expand Up @@ -194,7 +225,7 @@ function createRedirectDirectoryListener () {
originalUrl.pathname = collapseLeadingSlashes(originalUrl.pathname + '/')

// reformat the URL
var loc = encodeUrl(url.format(originalUrl))
var loc = encodeUrl(urlLib.format(originalUrl))
var doc = createHtmlDocument('Redirecting', 'Redirecting to <a href="' + escapeHtml(loc) + '">' +
escapeHtml(loc) + '</a>')

Expand Down
Binary file added test/fixtures/todo.txt.gz
Binary file not shown.
36 changes: 36 additions & 0 deletions test/test.js
Expand Up @@ -2,6 +2,7 @@
var assert = require('assert')
var Buffer = require('safe-buffer').Buffer
var http = require('http')
var fs = require('fs')
var path = require('path')
var request = require('supertest')
var serveStatic = require('..')
Expand Down Expand Up @@ -820,6 +821,41 @@ describe('serveStatic()', function () {
.expect(301, done)
})
})

describe('gzip', function () {
var server
before(function () {
server = createServer(fixtures, { gzip: true })
})

it('should set Content-Encoding', function (done) {
request(server)
.get('/todo.txt')
.expect('Content-Encoding', 'gzip')
.expect(200, done)
})

it('should set Content-Type', function (done) {
request(server)
.get('/todo.txt')
.expect('Content-Type', 'text/plain; charset=UTF-8')
.expect(200, done)
})

it('should serve static files', function (done) {
request(server)
.get('/todo.txt')
.expect(200, '- groceries', done)
})

it('should set Content-Length', function (done) {
request(server)
.get('/todo.txt')
.expect('Content-Length',
fs.statSync(path.resolve(__dirname, 'fixtures/todo.txt.gz')).size + '')
.expect(200, done)
})
})
})

function createServer (dir, opts, fn) {
Expand Down

0 comments on commit 6c010bd

Please sign in to comment.