-
Notifications
You must be signed in to change notification settings - Fork 194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mimetype #143
Mimetype #143
Changes from all commits
04eaa9f
e22dc92
285215b
5966dbb
140872f
81d1820
3a13400
303ea14
0db475f
71b4fa6
1d5de3e
1462c90
84ec0b5
80d315d
813ea25
65da86d
126a06e
e18ff2a
554ee19
20cf567
ee676d1
ffbeac3
617639b
6bcaf4c
7a23cef
8945400
a680345
b0ac06e
367152c
d03c691
51414b2
1b49d5d
4356c6e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
# Ecstatic [![build status](https://secure.travis-ci.org/jfhbrook/node-ecstatic.png)](http://travis-ci.org/jfhbrook/node-ecstatic) | ||
# Ecstatic [![build status](https://secure.travis-ci.org/jfhbrook/node-ecstatic.png)](http://travis-ci.org/jfhbrook/node-ecstatic) [![dependencies status](https://david-dm.org/jfhbrook/node-ecstatic.svg)](https://david-dm.org/jfhbrook/node-ecstatic) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A huge issue I had, was updating from tap 0.4 to 1.0. Since I spend a few hours doing that, I though a badge was in order :). It's a free service that tells us about the health of our dependencies. See here: https://david-dm.org/jfhbrook/node-ecstatic#info=devDependencies&view=table (and don't worry - it will look better when you merge this PR) |
||
|
||
![](http://imgur.com/vhub5.png) | ||
|
||
|
@@ -72,7 +72,9 @@ var opts = { | |
si : false, | ||
defaultExt : 'html', | ||
gzip : false, | ||
serverHeader : true | ||
serverHeader : true, | ||
contentType : 'application/octet-stream', | ||
mimeTypes : undefined | ||
} | ||
``` | ||
|
||
|
@@ -139,6 +141,13 @@ on all responses served by ecstatic. | |
Set `opts.contentType` in order to change default Content-Type header value. | ||
Defaults to **application/octet-stream**. | ||
|
||
### `opts.mimeTypes` | ||
|
||
Add new or override one or more mime-types. This affects the HTTP Content-Type header. | ||
Can either be a path to a [`.types`](http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types) file or an object hash of type(s). | ||
|
||
ecstatic({ mimeType: { 'mime-type': ['file_extension', 'file_extension'] } }) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jfhbrook, does this kind of doc make sense? An example would be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, I think that makes sense. |
||
|
||
### `opts.handleError` | ||
|
||
Turn **off** handleErrors to allow fall-through with `opts.handleError === false`, Defaults to **true**. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
#! /usr/bin/env node | ||
|
||
'use strict'; | ||
|
||
var path = require('path'), | ||
fs = require('fs'), | ||
url = require('url'), | ||
|
@@ -31,6 +33,17 @@ var ecstatic = module.exports = function (dir, options) { | |
opts.root = dir; | ||
if (defaultExt && /^\./.test(defaultExt)) defaultExt = defaultExt.replace(/^\./, ''); | ||
|
||
// Support hashes and .types files in mimeTypes @since 0.8 | ||
if (opts.mimeTypes) { | ||
if (typeof opts.mimeTypes === 'string') { | ||
//TODO: should handleError have any effect here? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jfhbrook what do you think about the handleError option? Should we not throw if it is true? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I think throwing is still appropriate. |
||
mime.load(opts.mimeTypes); // will throw if path is wrong as intended | ||
} else if (typeof opts.mimeTypes === 'object') { | ||
mime.define(opts.mimeTypes); | ||
} | ||
} | ||
|
||
|
||
return function middleware (req, res, next) { | ||
|
||
// Strip any null bytes from the url | ||
|
@@ -188,7 +201,7 @@ var ecstatic = module.exports = function (dir, options) { | |
status['500'](res, next, { error: err }); | ||
}); | ||
res.on('close', function () { | ||
fstream.destroy(); | ||
fstream.destroy(); | ||
}); | ||
res.writeHead(206, { | ||
'Content-Range': 'bytes ' + start + '-' + end + '/' + total, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,7 @@ | ||
// This is so you can have options aliasing and defaults in one place. | ||
|
||
'use strict'; | ||
|
||
module.exports = function (opts) { | ||
|
||
var autoIndex = true, | ||
|
@@ -10,15 +12,20 @@ module.exports = function (opts) { | |
gzip = false, | ||
defaultExt = '.html', | ||
handleError = true, | ||
serverHeader = true; | ||
contentType = 'application/octet-stream'; | ||
serverHeader = true, | ||
contentType = 'application/octet-stream', | ||
mimeTypes; | ||
|
||
function isDeclared(k) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pulling this out is probably a good idea. I approve. |
||
return typeof opts[k] !== 'undefined' && opts[k] !== null; | ||
} | ||
|
||
if (opts) { | ||
[ | ||
'autoIndex', | ||
'autoindex' | ||
].some(function (k) { | ||
if (typeof opts[k] !== 'undefined' && opts[k] !== null) { | ||
if (isDeclared(k)) { | ||
autoIndex = opts[k]; | ||
return true; | ||
} | ||
|
@@ -28,7 +35,7 @@ module.exports = function (opts) { | |
'showDir', | ||
'showdir' | ||
].some(function (k) { | ||
if (typeof opts[k] !== 'undefined' && opts[k] !== null) { | ||
if (isDeclared(k)) { | ||
showDir = opts[k]; | ||
return true; | ||
} | ||
|
@@ -39,7 +46,7 @@ module.exports = function (opts) { | |
'humanreadable', | ||
'human-readable' | ||
].some(function (k) { | ||
if (typeof opts[k] !== 'undefined' && opts[k] !== null) { | ||
if (isDeclared(k)) { | ||
humanReadable = opts[k]; | ||
return true; | ||
} | ||
|
@@ -49,7 +56,7 @@ module.exports = function (opts) { | |
'si', | ||
'index' | ||
].some(function (k) { | ||
if (typeof opts[k] !== 'undefined' && opts[k] !== null) { | ||
if (isDeclared(k)) { | ||
si = opts[k]; | ||
return true; | ||
} | ||
|
@@ -76,32 +83,48 @@ module.exports = function (opts) { | |
'handleError', | ||
'handleerror' | ||
].some(function (k) { | ||
if (typeof opts[k] !== 'undefined' && opts[k] !== null) { | ||
handleError = opts[k]; | ||
return true; | ||
} | ||
if (isDeclared(k)) { | ||
handleError = opts[k]; | ||
return true; | ||
} | ||
}); | ||
|
||
[ | ||
'serverHeader', | ||
'serverheader', | ||
'server-header' | ||
].some(function (k) { | ||
if (typeof opts[k] !== 'undefined' && opts[k] !== null) { | ||
serverHeader = opts[k]; | ||
return true; | ||
} | ||
if (isDeclared(k)) { | ||
serverHeader = opts[k]; | ||
return true; | ||
} | ||
}); | ||
|
||
[ | ||
'contentType', | ||
'contenttype', | ||
'content-type' | ||
].some(function (k) { | ||
if (typeof opts[k] !== 'undefined' && opts[k] !== null) { | ||
contentType = opts[k]; | ||
return true; | ||
} | ||
if (isDeclared(k)) { | ||
contentType = opts[k]; | ||
return true; | ||
} | ||
}); | ||
|
||
[ | ||
'mimetype', | ||
'mimetypes', | ||
'mimeType', | ||
'mimeTypes', | ||
'mime-type', | ||
'mime-types', | ||
'mime-Type', | ||
'mime-Types' | ||
].some(function (k) { | ||
if (isDeclared(k)) { | ||
mimeTypes = opts[k]; | ||
return true; | ||
} | ||
}); | ||
|
||
} | ||
|
@@ -117,6 +140,7 @@ module.exports = function (opts) { | |
gzip: gzip, | ||
handleError: handleError, | ||
serverHeader: serverHeader, | ||
contentType: contentType | ||
contentType: contentType, | ||
mimeTypes: mimeTypes | ||
}; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
'use strict'; | ||
|
||
var ecstatic = require('../ecstatic'), | ||
fs = require('fs'), | ||
path = require('path'), | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
'use strict'; | ||
|
||
// not modified | ||
exports['304'] = function (res, next) { | ||
res.statusCode = 304; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
"author": "Joshua Holbrook <[email protected]> (http://jesusabdullah.net)", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note to self: change email address There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah, it made me think that you guys sat together and made http-server and ecstatic. I even went to freenode.org#nodejitsu and asked around for you a few times. |
||
"name": "ecstatic", | ||
"description": "A simple static file server middleware that works with both Express and Flatiron", | ||
"version": "0.7.6", | ||
"version": "0.8.2", | ||
"homepage": "https://github.com/jfhbrook/node-ecstatic", | ||
"repository": { | ||
"type": "git", | ||
|
@@ -28,10 +28,11 @@ | |
"url-join": "0.0.1" | ||
}, | ||
"devDependencies": { | ||
"tap": "^0.4.13", | ||
"eol": "^0.2.0", | ||
"express": "^4.12.3", | ||
"mkdirp": "^0.5.0", | ||
"request": "^2.49.0", | ||
"express": "^3.0.6", | ||
"union": "^0.3.8", | ||
"mkdirp": "^0.5.0" | ||
"tap": "^1.0.3", | ||
"union": "^0.4.4" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,28 @@ | ||
var test = require('tap').test, | ||
ecstatic = require('../'), | ||
http = require('http'), | ||
request = require('request'); | ||
request = require('request'), | ||
ecstatic = require('../'); | ||
|
||
test('default default contentType', function(t) { | ||
var server = http.createServer(ecstatic({ | ||
root: __dirname + '/public/', | ||
contentType: 'text/plain' | ||
})); | ||
try { | ||
var server = http.createServer(ecstatic({ | ||
root: __dirname + '/public/', | ||
contentType: 'text/plain' | ||
})); | ||
} catch (e) { | ||
t.fail(e.message); | ||
t.end(); | ||
} | ||
|
||
t.plan(3); | ||
|
||
t.on('end', function() { server.close(); }); | ||
|
||
server.listen(0, function() { | ||
var port = server.address().port; | ||
request.get('http://localhost:' + port + '/f_f', function(err, res, body) { | ||
t.ifError(err); | ||
t.equal(res.statusCode, 200); | ||
t.equal(res.headers['content-type'], 'text/plain; charset=UTF-8'); | ||
t.end(); | ||
server.close(function() { t.end(); }); | ||
}); | ||
}); | ||
}); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
var test = require('tap').test, | ||
http = require('http'), | ||
request = require('request'), | ||
ecstatic = require('../'); | ||
|
||
test('custom contentType via .types file', function(t) { | ||
try { | ||
var server = http.createServer(ecstatic({ | ||
root: __dirname + '/public/', | ||
mimetypes: __dirname + '/secret/custom_mime_type.types' | ||
})); | ||
} catch (e) { | ||
t.fail(e.message); | ||
t.end(); | ||
} | ||
|
||
t.plan(3) | ||
|
||
server.listen(0, function() { | ||
var port = server.address().port; | ||
request.get('http://localhost:' + port + '/custom_mime_type.opml', function(err, res, body) { | ||
t.ifError(err); | ||
t.equal(res.statusCode, 200, 'custom_mime_type.opml should be found'); | ||
t.equal(res.headers['content-type'], 'application/secret; charset=utf-8'); | ||
server.close(function() { t.end(); }); | ||
}); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
var test = require('tap').test, | ||
http = require('http'), | ||
request = require('request'), | ||
ecstatic = require('../'); | ||
|
||
function setup(opts) { | ||
return http.createServer(ecstatic(opts)); | ||
} | ||
|
||
test('throws when custom contentType .types file does not exist', function(t) { | ||
t.plan(1); | ||
|
||
t.throws( | ||
setup.bind(null, { | ||
root: __dirname + '/public/', | ||
mimeTypes: 'this_file_does_not_exist.types' | ||
}) | ||
); | ||
|
||
}); | ||
|
||
test('custom contentType via .types file', function(t) { | ||
try { | ||
var server = setup({ | ||
root: __dirname + '/public', | ||
'mime-types': __dirname + '/public/custom_mime_type.types' | ||
}); | ||
} catch (e) { | ||
t.fail(e.message); | ||
t.end(); | ||
} | ||
|
||
t.plan(3) | ||
|
||
server.listen(0, function() { | ||
var port = server.address().port; | ||
|
||
request.get('http://localhost:' + port + '/custom_mime_type.opml', function(err, res, body) { | ||
t.ifError(err); | ||
t.equal(res.statusCode, 200, 'custom_mime_type.opml should be found'); | ||
t.equal(res.headers['content-type'], 'application/foo; charset=utf-8'); | ||
server.close(function() { t.end(); }); | ||
}); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should probably add something about the changelog in the contributing guidelines---I like to manage this myself while bumping and publishing releases. But the notes here are really helpful! I'll just end up munging this a bit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do as you like. I put them there for you