pillarjs / send Goto Github PK
View Code? Open in Web Editor NEWStreaming static file server with Range and conditional-GET support
License: MIT License
Streaming static file server with Range and conditional-GET support
License: MIT License
instead of only thorugh methods
Add an option to show the symbolic links as 301 redirections to the file location instead of return the file content.
http.createServer(function(req, res){
//TODO : 这里少了个 req 参数.
send(req, req.url)
.from(__dirname + '/public')
.maxage(60000)
.pipe(res);
}).listen(3000);
hi there,
I found myself in situation where I wanted send
to generate an ETag header, for a given file, that was identical to the ETag header generated by Nginx (for the same file).
I am using an nodejs image generator in combination with Nginx try_files
directive (nodejs generates image files dynamically on request but subsequent requests are handled by directly Nginx if/when it find a pre-generated file on disk).
the actual function I ended up with to generate an Nginx-like ETag was this:
function etag(path, stat) {
return '"' + Math.ceil(+stat.mtime / 1000).toString(16) + '-' + Number(stat.size).toString(16) + '"';
}
AFAICT send
does not officially expose a way to control/override the generation of the ETag header value, in order to use my etag()
function I ended up doing the following:
require('imgr/node_modules/express/node_modules/connect/node_modules/serve-static/node_modules/send/lib/utils').etag = etag;
... and that works, but it seems wrong on so many levels and I was wondering if you could tell me whether there is a better (more correct) way of doing this?
node-static has a command line interface which is useful for using it as a simple server for client side packages (opening up simple web components with npm run serve
so you have local access to the node-static bin
in your package and you can load a package local index.html
file up in the server). Is this something that would be an acceptable feature to add to send?
I can't imagine it would be a large/complex change.
While you're publishing packages to npm, can you please push a repository URL too? This should probably get added to package.json if you're using that to push to npm:
"repository" :
{ "type" : "git"
, "url" : "git://github.com/visionmedia/send.git"
}
This is missing from a lot of other packages, too, including dependencies to this one:
https://github.com/visionmedia/send
https://github.com/visionmedia/bytes.js
https://github.com/visionmedia/node-pause
https://github.com/visionmedia/node-fresh
https://github.com/visionmedia/node-range-parser
https://github.com/visionmedia/debug
send
does not have a command line interface. Would a PR be accepted?
I just built a node-webkit based static web server (http://fenixwebserver.com) that leverages send to help fire up/kill static web servers on demand. I've actually been using it for about a month without issues, but in the last day or two, I've started noticing a very delayed close action.
Essentially, I can start a static server without issue. When I run close()
, it works, but the close
event is emitted as long as 5 minutes after calling the close method.
I suspect it has something to do with keepalive, but that would imply a client has connected to the server and is keeping the connection open until it times out (this happens even without a client connecting... i.e. starting the server and immediately closing it). It seems like calling close()
should be able to disconnect, or perhaps an option like close(force)
or something.
Am I missing something here or might this be an issue with the close method?
This is a very hard-to-replicate issue, but I figure I'll file a ticket anyway. We're using express in a commercial application to simplify our server development, and one of the deployments we have has been hitting an issue that I believe occurs within send, although I'm not positive about that. I'll start off with what is basically the error (it might be slightly different because I'm catching and then printing it now as a workaround, but most of it is still there):
Error: read ECONNRESET
at errnoException (net.js:901:11)
at TCP.onread (net.js:556:19)
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (http.js:691:11)
at ServerResponse.res.setHeader (/home/user/gitlocal/core/application/node_modules/express/node_modules/connect/lib
/patch.js:59:22)
at SendStream.setHeader (/home/user/gitlocal/core/application/node_modules/express/node_modules/send/lib/send.js:47
7:44)
at SendStream.send (/home/user/gitlocal/core/application/node_modules/express/node_modules/send/lib/send.js:353:8)
at /home/user/gitlocal/core/application/node_modules/express/node_modules/send/lib/send.js:323:14
at Object.oncomplete (fs.js:107:15)
The error is always preceded by a TCP connection reset, which I figure is likely relevant.
The code in use doesn't set any headers itself. Here's the express route:
app.get(/^\/(img|css|vendor|pubjs)\/.+$/,
function (req, res) {
res.sendfile(getPath(req));
}
);
getPath just prefixes the path with /public and optionally a path to a custom folder for each deployment, if the file exists. It does not send any headers, as evidenced by the fact that it doesn't take res as an argument. It actually only uses req.path in its operation.
I got around this temporarily by doing a try/catch in lib/send.js around self.send, but I wouldn't really consider that a permanent fix. It only has occurred around once a day when in production use, but I couldn't quote any numbers as to how many people have been using it. Anyone have an idea what's going on here? We're currently using send 0.1.0 which is what's specified by express 3.0.6 with node version 0.10.21.
Happy to submit a PR for this if you'd like!
I'm writing a piece of connect middleware similar to Apache's mod_negotiation
. Based on req.url
, the Accept-Language
and Accept
headers, a custom locale cookie, and which files are found on disc, it figures out which file to actually serve.
For example:
GET / HTTP/1.1
Cookie: language=fr
Accept: text/html
could get mapped to /index.fr.html
, and
GET /someDir/foo.html HTTP/1.1
Accept-Language: nl, da
could get mapped to /someDir/foo.da.html
-- unless a Dutch version of the file was also available.
I'd like to use send
for this, or maybe just require that my module sits right above connect.static
in the middleware stack.
Here's my problem -- since any given incoming url might map to different files on disc, which could very well have the same modification times and byte lengths, send
's current ETag scheme won't work. If a client does a conditional GET request for a page after switching to a different language (either changing the language cookie or Accept-Language
), it could lead to a "false positive" 304 response.
I know I can set the ETag header in my own code, and that's my current solution -- I use send
's algorithm and append -<localeId>
to the ETag. Unfortunately that means my server is doing 2 stat calls for each static file request, which I'm not a fan of.
So what I'd like instead is for send
's setHeader
to support adding to existing "ETag fragments", or alternatively an event being emitted after the headers have been set, but before the freshness check. This would be a nice spot: https://github.com/visionmedia/send/blob/master/lib/send.js#L348
What do you think? Is this use case too convoluted to warrant added complexity in send
?
Hey,
I'm experimenting with source maps and found the node-mime
dependency is outdated, it's probably a problem of the other project, but it's affecting send
and connect
.
For now I've applied manually broofa/mime@f52dfd4 and everything work as expected.
Thanks
Something isn't right here:
var http = require('http');
var send = require('send');
var app = http.createServer(function(req, res){
send(req, __filename).pipe(res);
}).listen(3000);
var net = require('net');
var headers = [
'GET / HTTP/1.1',
'Host: localhost:3000',
'',
''
].join('\r\n');
function sendCanceledRequest () {
var socket = new net.Socket();
socket.connect(3000, 'localhost', function() {
socket.write(headers, 'utf-8', function () {
socket.destroy();
});
});
}
setInterval(sendCanceledRequest, 1000);
$ lsof -p `pidof node`
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 6327 alex cwd DIR 0,20 358 276 /tmp
node 6327 alex rtd DIR 0,20 226 256 /
node 6327 alex txt REG 0,20 1462424 185784 /usr/bin/nodejs
[... tons of system stuff skipped ...]
node 6327 alex 9u 0000 0,9 0 7445 anon_inode
node 6327 alex 10r DIR 0,20 226 256 /
node 6327 alex 11u IPv4 83502 0t0 TCP *:3000 (LISTEN)
node 6327 alex 12r REG 0,20 540 1042412 /tmp/test1.js
node 6327 alex 13r REG 0,20 540 1042412 /tmp/test1.js
node 6327 alex 14r REG 0,20 540 1042412 /tmp/test1.js
node 6327 alex 15r REG 0,20 540 1042412 /tmp/test1.js
node 6327 alex 16r REG 0,20 540 1042412 /tmp/test1.js
node 6327 alex 17r REG 0,20 540 1042412 /tmp/test1.js
node 6327 alex 18r REG 0,20 540 1042412 /tmp/test1.js
node 6327 alex 19r REG 0,20 540 1042412 /tmp/test1.js
[... tons of leaking fds skipped ...]
node 6327 alex 43r REG 0,20 540 1042412 /tmp/test1.js
Copied from expressjs/serve-static#54
Unfortunately the RFC IETF or whoever decided it was a good idea to standardize on a directory that is, by default, hidden. Right?
So when I'm tearing my hair out wondering why my Let's Encrypt certs aren't getting validated....
https://example.com/.well-known/acme-challenge/xxxxxxxxxxxxxxx
It's the darn .well-known
givin' me all the troubles.
I'd like to suggest that .well-known
(and any other RFC / IETF spec'd dirs) not be ignored by default.
Perhaps the default should be the array ['.well-known']
and you can override that value with true
, false
, or []
(ignore)?
I'm pretty sure that this is noticeable but this may cause issues for some developers
Your Commit on Jul 18, 2014 "Refactor malicious path checks" is causing an issue for windows
The test on line 400
if (path.substr(0, root.length) !== root) {
...
is giving a false positive.
In my case it is comparing:
d:\WebProjects\expressBug\public
and
D:\WebProjects\expressBug\public
Note the case of the drive letter is the only difference
The call to normalize() lowercases the drive letter on the 'path' variable (line 397)
See my pull request #69. It would be nice to be able to modify the data from the file stream using transforms. This is helpful when the stored data in the file is a template, encrypted, compressed, etc
.... as it has the latest version of web fonts MIME types, being relevant for the latest update of Google Chrome. Thanks! (Also, tell Express to update as well :))
Since 3a90c00
This error is thrown on each static files express.js attempts to send.
Error: Connection closed
at [...]/node_modules/express/node_modules/send/lib/send.js:322:26
at Object.oncomplete (fs.js:107:15)
node -v
v0.10.12
Hello,
I have this error with express 3.3.8 and dependency send :
Requested Range Not Satisfiable
at SendStream.error (/opt/run/snapshot/package/node_modules/express/node_modules/send/lib/send.js:145:16)
at SendStream.send (/opt/run/snapshot/package/node_modules/express/node_modules/send/lib/send.js:371:19)
at /opt/run/snapshot/package/node_modules/express/node_modules/send/lib/send.js:323:10
at Object.oncomplete (fs.js:107:15)
Do you have any idea?
Thank you
This is an enhancement request for connect's static file module to accomodate files that have been pre-gzip'd. I'm guessing the best place to do this is in the send module.
Of course there are numerous ways to handle this... I'm not sure which is best but all I need/want is #1 below:
I realize connect has a dynamic compress capability but it seems inefficient to compress each time a fixed, static file is requested. It's easy to gzip when building but it doesn't seem like node has an efficient way to serve static gzip'd files at this time (unless I'm missing something which I realize is quite likely).
Thanks for listening!
Looks like trying to require express, which requires send, breaks jest mock generation:
> [email protected] test /Users/arkadiy/mine/mine-relay-server
> BABEL_JEST_STAGE=1 jest
Using Jest CLI v0.5.10
FAIL __tests__/jwt.js (1.496s)
● createToken › it encountered a declaration exception
- TypeError: /Users/arkadiy/mine/mine-relay-server/server/routers/jwt.js: /Users/arkadiy/mine/mine-relay-server/node_modules/express/index.js: /Users/arkadiy/mine/mine-relay-server/node_modules/express/lib/express.js: /Users/arkadiy/mine/mine-relay-server/node_modules/express/lib/application.js: /Users/arkadiy/mine/mine-relay-server/node_modules/express/lib/view.js: /Users/arkadiy/mine/mine-relay-server/node_modules/express/lib/utils.js: /Users/arkadiy/mine/mine-relay-server/node_modules/send/index.js: Cannot read property 'function' of undefined
at Object.<anonymous> (node_modules/send/index.js:156:38)
at Object.runContentWithLocalBindings (node_modules/jest-cli/src/lib/utils.js:527:17)
at Loader._execModule (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:239:9)
at Loader.requireModule (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:902:12)
at Loader._generateMock (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:270:30)
at Loader.requireMock (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:798:43)
at Loader.requireModuleOrMock (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:921:17)
at Object.<anonymous> (node_modules/express/lib/utils.js:19:12)
at Object.runContentWithLocalBindings (node_modules/jest-cli/src/lib/utils.js:527:17)
at Loader._execModule (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:239:9)
at Loader.requireModule (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:902:12)
at Loader._generateMock (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:270:30)
at Loader.requireMock (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:798:43)
at Loader.requireModuleOrMock (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:921:17)
at Object.<anonymous> (node_modules/express/lib/view.js:19:13)
at Object.runContentWithLocalBindings (node_modules/jest-cli/src/lib/utils.js:527:17)
at Loader._execModule (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:239:9)
at Loader.requireModule (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:902:12)
at Loader._generateMock (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:270:30)
at Loader.requireMock (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:798:43)
at Loader.requireModuleOrMock (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:921:17)
at Object.<anonymous> (node_modules/express/lib/application.js:22:12)
at Object.runContentWithLocalBindings (node_modules/jest-cli/src/lib/utils.js:527:17)
at Loader._execModule (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:239:9)
at Loader.requireModule (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:902:12)
at Loader._generateMock (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:270:30)
at Loader.requireMock (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:798:43)
at Loader.requireModuleOrMock (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:921:17)
at Object.<anonymous> (node_modules/express/lib/express.js:17:13)
at Object.runContentWithLocalBindings (node_modules/jest-cli/src/lib/utils.js:527:17)
at Loader._execModule (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:239:9)
at Loader.requireModule (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:902:12)
at Loader._generateMock (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:270:30)
at Loader.requireMock (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:798:43)
at Loader.requireModuleOrMock (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:921:17)
at Object.<anonymous> (node_modules/express/index.js:11:18)
at Object.runContentWithLocalBindings (node_modules/jest-cli/src/lib/utils.js:527:17)
at Loader._execModule (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:239:9)
at Loader.requireModule (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:902:12)
at Loader._generateMock (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:270:30)
at Loader.requireMock (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:798:43)
at Loader.requireModuleOrMock (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:921:17)
at Object.<anonymous> (server/routers/jwt.js:4:111)
at Object.runContentWithLocalBindings (node_modules/jest-cli/src/lib/utils.js:527:17)
at Loader._execModule (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:239:9)
at Loader.requireModule (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:902:12)
at Loader.requireModuleOrMock (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:923:17)
at Suite.<anonymous> (__tests__/jwt.js:4:3)
at env.describe_ (evalmachine.<anonymous>:40:25)
at env.describe (evalmachine.<anonymous>:27:19)
at Object.<anonymous> (__tests__/jwt.js:3:1)
at Object.runContentWithLocalBindings (node_modules/jest-cli/src/lib/utils.js:527:17)
at Loader._execModule (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:239:9)
at Loader.requireModule (node_modules/jest-cli/src/HasteModuleLoader/HasteModuleLoader.js:902:12)
at jasmineTestRunner (node_modules/jest-cli/src/jasmineTestRunner/jasmineTestRunner.js:284:16)
at node_modules/jest-cli/src/TestRunner.js:379:12
at process._tickCallback (node.js:356:9)
1 test failed, 0 tests passed (1 total)
Run time: 2.294s
npm ERR! Test failed. See above for more details.
I'm not entirely sure how to approach this.
until supported
This is stable code that is widely used in production which has been carefully preserved to not break backwards compat.
Doesn't it deserve the honor of a v1.0?
/cc @tj @jonathanong
moving from expressjs/express#1495
To quote Wikipedia:
Some earlier checksum functions, such as CRC32 and CRC64, are known to suffer from this hash collision problem. Because of this they are not good candidates for use in ETag generation.
Maybe we should be using something like checksum that has fewer collisions? Or perhaps there's something I don't understand about the decision to use CRC32. Or perhaps Wikipedia is wrong.
Add the remaining main HTTP methods (POST, PUT, PATCH and DELETE). I know these would need some special security considerations, so I'm not sure if they should (or could!) be implemented on an external module...
Node 0.11 and send
throws an error:
app/node_modules/browser-sync/node_modules/serve-static/node_modules/send/node_modules/etag/index.js:55
throw new TypeError('argument entity must be string, Buffer, or fs.Stats')
^
TypeError: argument entity must be string, Buffer, or fs.Stats
at etag (app/node_modules/browser-sync/node_modules/serve-static/node_modules/send/node_modules/etag/index.js:55:11)
at SendStream.setHeader (app/node_modules/browser-sync/node_modules/serve-static/node_modules/send/index.js:725:15)
at SendStream.send (app/node_modules/browser-sync/node_modules/serve-static/node_modules/send/index.js:500:8)
at app/node_modules/browser-sync/node_modules/serve-static/node_modules/send/index.js:631:12
at Object.oncomplete (fs.js:97:15)
The reason seems to be that fs.stat
doesn't return instanceof fs.Stats
as etag
expects.
I added a log to SendStream#sendIndex
:
SendStream.prototype.sendIndex = function sendIndex(path){
var i = -1;
var self = this;
function next(err){
if (++i >= self._index.length) {
if (err) return self.onStatError(err);
return self.error(404);
}
var p = join(path, self._index[i]);
debug('stat "%s"', p);
fs.stat(p, function(err, stat){
// LOG
console.log("STAT?", stat instanceof fs.Stats);
// END LOG
if (err) return next(err);
if (stat.isDirectory()) return next();
self.emit('file', p, stat);
self.send(p, stat);
});
}
next();
};
It outputs false.
etag
is expecting a Stats
instance:
https://github.com/jshttp/etag/blob/master/index.js#L44
Works on 0.10.
Currently you can only pipe send directly to res. I have a use case where I want to modify some of the html on the way out.
// if html, inject lr
if (path.extname(filePath).match(/\.htm(l)?$/)) {
stream
.pipe(rstream('</body>', getLivereloadTag(lrPort)+'</body>'))
.pipe(res);
} else {
// stream file to response
stream.pipe(res);
}
on html will yield
/Users/contra/Projects/lute/node_modules/send/lib/send.js:647
if (!res.getHeader('Accept-Ranges')) res.setHeader('Accept-Ranges', 'bytes')
^
TypeError: Object #<Stream> has no method 'getHeader'
at SendStream.setHeader (/Users/contra/Projects/lute/node_modules/send/lib/send.js:647:12)
at SendStream.send (/Users/contra/Projects/lute/node_modules/send/lib/send.js:468:8)
at /Users/contra/Projects/lute/node_modules/send/lib/send.js:439:10
at Object.oncomplete (fs.js:107:15)
hi tj
sometimes my visitors experience a, 'Requested Range Not Satisfiable' error (416) because they are accessing a video file which is currently being encoded.
i send them this video via express like that:
app.get('/stream/preview/:sid/type/:type', function(req, res, next) {
var previewVideo = paths.getPreviewVideo(
req.params.sid,
req.params.type
);
res.sendfile(
previewVideo,
function(err) {
if (err && err.code != 'ENOENT')
next(err);
}
);
});
i examined the express code and landed to the send module. in function send()
you enable ranges support by looking into req.headers.range
i wonder if i can disable ranges support somehow for the above case? maybe by modifying headers or by adding a new option in the sendfile()
function? i think i prefer the latter one.
what do you think?
In strict mode, Safari 8.0.8 on OS X 10.10.5 raises an exception if a named function's name is the same as one of the function's argument names.
For example: at index.js:L242
SendStream.prototype.error = function error(status, error) {
will cause an error on Safari ( but not on Chrome and Firefox ):
SyntaxError: Cannot declare a parameter named 'error' as it shadows the name of a strict mode function.
Any sugguestion?
Hello,
in another standalone HTTP server, there is a lack of Range partial content handling.
I found this implementation pretty neat and easy to extract.
Is it something acceptable for you (to extract the code+tests and submit as a PR the replacement as a module dependency)?
Or do you find that too risky/pointless?
Thanks :-)
The font/
supertype invalid according to the spec.
I can only assume it's originating from here somewhere because font/opentype
does not exist in the mime
module.
I'm running the latest express on node 0.10.x, and my opentype font is sending as font/opentype
for some reason.
It'll be easiest to find the font in the network inspector on this page of my site.
(It should send as either application/x-font-otf
since that is what mime
thinks it should be.)
i have an use case that need to know the SendStream
is end all the time. Might add this feature? i can push a pull request
Mr. Deathspike mentioned that GET /about used to 404 but now gets http://pastebin.com/c5vW0hus, look into it
Hi, what about option to clean Cache-control on 206 and 304 responses?
nginx cache they and will send 206 instead 200 on every requests for example.
or just 'post-header event', to clean it without setHeader overriding.
the 'hidden' options works fine in the hidden file which has basename start with dot,but when it comes to folders like this,it won't work
/.svn/wc.db
by change the hasLeadingDot function into this may fix it
SendStream.prototype.hasLeadingDot = function(){
return this.path.split('/').some(function (path) {return path[0] == '.'});
};
I have a gulp-connect task here and am looking for a middleware that enables me to send just one local HTML file, depending on the URL.
How would you do this with this module?
Hi,
I'm going to use send
for serving static files, node will be behind Varnish.
Usually, in web servers there are some rewrite rules, which analyze the path, environment and (if needed) change the filepath.
How should I implement it with send
?
My 1st attempt was to analyze path apply rewrites outside of send, so I have a new (rewritten) filepath at hands, but how can I pass it to send
?
P.S. Thank you for the module.
This is the actual treatment of docfiles, which differs slightly from the documentation
default:
ignore
:
allow
:
deny
:
Hi Guys,
im seeing the below error while using the static middleware on express. if i comment the static middleware app works fine. any clue on whats going on
app.use(express.static(__dirname));
Thank you,
-bala
error trace:
Error: Bad Request
at SendStream.error (/Users/balachandra/Desktop/thply/node_modules/express/node_modules/send/lib/send.js:145:16)
at SendStream.pipe (/Users/balachandra/Desktop/thply/node_modules/express/node_modules/send/lib/send.js:298:31)
at Object.staticMiddleware [as handle] (/Users/balachandra/Desktop/thply/node_modules/express/node_modules/connect/lib/middleware/static.js:84:8)
at next (/Users/balachandra/Desktop/thply/node_modules/express/node_modules/connect/lib/proto.js:190:15)
at multipart (/Users/balachandra/Desktop/thply/node_modules/express/node_modules/connect/lib/middleware/multipart.js:64:37)
at /Users/balachandra/Desktop/thply/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js:57:9
at urlencoded (/Users/balachandra/Desktop/thply/node_modules/express/node_modules/connect/lib/middleware/urlencoded.js:51:37)
at /Users/balachandra/Desktop/thply/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js:55:7
at json (/Users/balachandra/Desktop/thply/node_modules/express/node_modules/connect/lib/middleware/json.js:53:37)
at Object.bodyParser [as handle] (/Users/balachandra/Desktop/thply/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js:53:5)
at next (/Users/balachandra/Desktop/thply/node_modules/express/node_modules/connect/lib/proto.js:190:15)
at Object.expressInit [as handle] (/Users/balachandra/Desktop/thply/node_modules/express/lib/middleware.js:30:5)
at next (/Users/balachandra/Desktop/thply/node_modules/express/node_modules/connect/lib/proto.js:190:15)
at Object.query [as handle] (/Users/balachandra/Desktop/thply/node_modules/express/node_modules/connect/lib/middleware/query.js:44:5)
at next (/Users/balachandra/Desktop/thply/node_modules/express/node_modules/connect/lib/proto.js:190:15)
at Function.app.handle (/Users/balachandra/Desktop/thply/node_modules/express/node_modules/connect/lib/proto.js:198:3)
at Server.app (/Users/balachandra/Desktop/thply/node_modules/express/node_modules/connect/lib/connect.js:65:37)
at Server.EventEmitter.emit (events.js:98:17)
at HTTPParser.parser.onIncoming (http.js:2045:12)
at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:119:23)
at Socket.socket.ondata (http.js:1935:22)
at TCP.onread (net.js:524:27)
This issue was originally submitted by @zumoshi here: expressjs/express#1621 but was never followed up on.
the relative path; the "../" is considered malicious by res.sendfile() but it doesn't check for ../ or /.. , it only checks for ".."
so if i do res.sendfile('/a..txt') it throws
Error: Forbidden
at SendStream.error (C:\w\node_modules\express\node_modules\send\lib\send.js:145:16)
at SendStream.pipe (C:\w\node_modules\express\node_modules\send\lib\send.js:307:39)
at ServerResponse.res.sendfile (C:\w\node_modules\express\lib\response.js:339:8)
...
at callbacks (C:\w\node_modules\express\lib\router\index.js:161:37)
at param (C:\w\node_modules\express\lib\router\index.js:135:11)
i am currently using express send file in a production server to serve user files and some files have 2 dots in their name
I have the same issue, needing to send files with double dots (..
) in their names.
$ npm install send
npm WARN package.json [email protected] No description
npm WARN package.json [email protected] No repository field.
npm WARN package.json [email protected] No README data
npm WARN package.json [email protected] No repository field.
npm http GET https://registry.npmjs.org/send
npm http 304 https://registry.npmjs.org/send
npm ERR! Error: ENOENT, open '/mnt/raid/src/web/passport-remember-me/examples/login/node_modules/send/package.json'
npm ERR! If you need help, you may report this log at:
npm ERR! <http://github.com/isaacs/npm/issues>
npm ERR! or email it to:
npm ERR! <[email protected]>
npm ERR! System Linux 3.11.9-200.fc19.x86_64
npm ERR! command "/mnt/raid/local/bin/node" "/mnt/raid/local/bin/npm" "install" "send"
npm ERR! cwd /mnt/raid/src/web/passport-remember-me/examples/login
npm ERR! node -v v0.10.22
npm ERR! npm -v 1.3.14
npm ERR! path /mnt/raid/src/web/passport-remember-me/examples/login/node_modules/send/package.json
npm ERR! code ENOENT
npm ERR! errno 34
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /mnt/raid/src/web/passport-remember-me/examples/login/npm-debug.log
npm ERR! not ok code 0
$ node --version
v0.10.22
$ npm --version
1.3.14
$ uname -a
Linux fedora 3.11.9-200.fc19.x86_64 #1 SMP Wed Nov 20 21:22:24 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
note that CWD
is an nfs mount
. I have LINK=g++
in my environment.
$ cat /mnt/raid/src/web/passport-remember-me/examples/login/npm-debug.log
0 info it worked if it ends with ok
1 verbose cli [ '/mnt/raid/local/bin/node',
1 verbose cli '/mnt/raid/local/bin/npm',
1 verbose cli 'install',
1 verbose cli 'send' ]
2 info using [email protected]
3 info using [email protected]
4 verbose node symlink /mnt/raid/local/bin/node
5 warn package.json [email protected] No description
6 warn package.json [email protected] No repository field.
7 warn package.json [email protected] No README data
8 warn package.json [email protected] No repository field.
9 verbose readDependencies using package.json deps
10 verbose cache add [ 'send', null ]
11 verbose cache add name=undefined spec="send" args=["send",null]
12 verbose parsed url { protocol: null,
12 verbose parsed url slashes: null,
12 verbose parsed url auth: null,
12 verbose parsed url host: null,
12 verbose parsed url port: null,
12 verbose parsed url hostname: null,
12 verbose parsed url hash: null,
12 verbose parsed url search: null,
12 verbose parsed url query: null,
12 verbose parsed url pathname: 'send',
12 verbose parsed url path: 'send',
12 verbose parsed url href: 'send' }
13 silly lockFile 37ed539c-send send
14 verbose lock send /home/steve/.npm/37ed539c-send.lock
15 silly lockFile 37ed539c-send send
16 silly lockFile 37ed539c-send send
17 verbose addNamed [ 'send', '' ]
18 verbose addNamed [ null, '*' ]
19 silly lockFile 71c8a776-send send@
20 verbose lock send@ /home/steve/.npm/71c8a776-send.lock
21 silly addNameRange { name: 'send', range: '*', hasData: false }
22 verbose url raw send
23 verbose url resolving [ 'https://registry.npmjs.org/', './send' ]
24 verbose url resolved https://registry.npmjs.org/send
25 info trying registry request attempt 1 at 12:24:50
26 verbose etag "9C3B2FC8QK9V9PPYBFUXTMM5L"
27 http GET https://registry.npmjs.org/send
28 http 304 https://registry.npmjs.org/send
29 silly registry.get cb [ 304,
29 silly registry.get { server: 'CouchDB/1.5.0 (Erlang OTP/R15B03)',
29 silly registry.get etag: '"9C3B2FC8QK9V9PPYBFUXTMM5L"',
29 silly registry.get date: 'Thu, 19 Dec 2013 01:24:52 GMT',
29 silly registry.get 'content-length': '0' } ]
30 verbose etag send from cache
31 silly addNameRange number 2 { name: 'send', range: '*', hasData: true }
32 silly addNameRange versions [ 'send',
32 silly addNameRange [ '0.0.1',
32 silly addNameRange '0.0.2',
32 silly addNameRange '0.0.3',
32 silly addNameRange '0.0.4',
32 silly addNameRange '0.1.0',
32 silly addNameRange '0.1.1',
32 silly addNameRange '0.1.2',
32 silly addNameRange '0.1.3',
32 silly addNameRange '0.1.4' ] ]
33 verbose addNamed [ 'send', '0.1.4' ]
34 verbose addNamed [ '0.1.4', '0.1.4' ]
35 silly lockFile 555fd08a-send-0-1-4 [email protected]
36 verbose lock [email protected] /home/steve/.npm/555fd08a-send-0-1-4.lock
37 silly lockFile 555fd08a-send-0-1-4 [email protected]
38 silly lockFile 555fd08a-send-0-1-4 [email protected]
39 silly lockFile 71c8a776-send send@
40 silly lockFile 71c8a776-send send@
41 silly resolved [ { name: 'send',
41 silly resolved version: '0.1.4',
41 silly resolved description: 'Better streaming static file server with Range and conditional-GET support',
41 silly resolved keywords: [ 'static', 'file', 'server' ],
41 silly resolved author: { name: 'TJ Holowaychuk', email: '[email protected]' },
41 silly resolved dependencies:
41 silly resolved { debug: '*',
41 silly resolved mime: '~1.2.9',
41 silly resolved fresh: '0.2.0',
41 silly resolved 'range-parser': '0.0.4' },
41 silly resolved devDependencies: { mocha: '*', should: '*', supertest: '0.0.1', connect: '2.x' },
41 silly resolved scripts: { test: 'make test' },
41 silly resolved repository: { type: 'git', url: 'git://github.com/visionmedia/send.git' },
41 silly resolved main: 'index',
41 silly resolved readme: '# send\n\n Send is Connect\'s `static()` extracted for generalized use, a streaming static file\n server supporting partial responses (Ranges), conditional-GET negotiation, high test coverage, and granular events which may be leveraged to take appropriate actions in your application or framework.\n\n## Installation\n\n $ npm install send\n\n## Examples\n\n Small:\n\n```js\nvar http = require(\'http\');\nvar send = require(\'send\');\n\nvar app = http.createServer(function(req, res){\n send(req, req.url).pipe(res);\n}).listen(3000);\n```\n\n Serving from a root directory with custom error-handling:\n\n```js\nvar http = require(\'http\');\nvar send = require(\'send\');\nvar url = require(\'url\');\n\nvar app = http.createServer(function(req, res){\n // your custom error-handling logic:\n function error(err) {\n res.statusCode = err.status || 500;\n res.end(err.message);\n }\n\n // your custom directory handling logic:\n function redirect() {\n res.statusCode = 301;\n res.setHeader(\'Location\', req.url + \'/\');\n res.end(\'Redirecting to \' + req.url + \'/\');\n }\n\n // transfer arbitrary files from within\n // /www/example.com/public/*\n send(req, url.parse(req.url).pathname)\n .root(\'/www/example.com/public\')\n .on(\'error\', error)\n .on(\'directory\', redirect)\n .pipe(res);\n}).listen(3000);\n```\n\n## API\n\n### Events\n\n - `error` an error occurred `(err)`\n - `directory` a directory was requested\n - `file` a file was requested `(path, stat)`\n - `stream` file streaming has started `(stream)`\n - `end` streaming has completed\n\n### .root(dir)\n\n Serve files relative to `path`. Aliased as `.from(dir)`.\n\n### .index(path)\n\n By default send supports "index.html" files, to disable this\n invoke `.index(false)` or to supply a new index pass a string.\n\n### .maxage(ms)\n\n Provide a max-age in milliseconds for http caching, defaults to 0.\n\n### .hidden(bool)\n\n Enable or disable transfer of hidden files, defaults to false.\n\n## Error-handling\n\n By default when no `error` listeners are present an automatic response will be made, otherwise you have full control over the response, aka you may show a 5xx page etc.\n\n## Caching\n\n It does _not_ perform internal caching, you should use a reverse proxy cache such\n as Varnish for this, or those fancy things called CDNs. If your application is small enough that it would benefit from single-node memory caching, it\'s small enough that it does not need caching at all ;).\n\n## Debugging\n\n To enable `debug()` instrumentation output export __DEBUG__:\n\n```\n$ DEBUG=send node app\n```\n\n## Running tests\n\n```\n$ npm install\n$ make test\n```\n\n## License \n\n(The MIT License)\n\nCopyright (c) 2012 TJ Holowaychuk <[email protected]>\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\'Software\'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \'AS IS\', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n',
41 silly resolved readmeFilename: 'Readme.md',
41 silly resolved bugs: { url: 'https://github.com/visionmedia/send/issues' },
41 silly resolved homepage: 'https://github.com/visionmedia/send',
41 silly resolved _id: '[email protected]',
41 silly resolved _from: 'send@' } ]
42 info install [email protected] into /mnt/raid/src/web/passport-remember-me/examples/login
43 info installOne [email protected]
44 info /mnt/raid/src/web/passport-remember-me/examples/login/node_modules/send unbuild
45 verbose tar unpack /home/steve/.npm/send/0.1.4/package.tgz
46 silly lockFile 792ecb67-examples-login-node-modules-send tar:///mnt/raid/src/web/passport-remember-me/examples/login/node_modules/send
47 verbose lock tar:///mnt/raid/src/web/passport-remember-me/examples/login/node_modules/send /home/steve/.npm/792ecb67-examples-login-node-modules-send.lock
48 silly lockFile 2c5e1bd5-steve-npm-send-0-1-4-package-tgz tar:///home/steve/.npm/send/0.1.4/package.tgz
49 verbose lock tar:///home/steve/.npm/send/0.1.4/package.tgz /home/steve/.npm/2c5e1bd5-steve-npm-send-0-1-4-package-tgz.lock
50 silly gunzTarPerm modes [ '755', '644' ]
51 silly lockFile 792ecb67-examples-login-node-modules-send tar:///mnt/raid/src/web/passport-remember-me/examples/login/node_modules/send
52 silly lockFile 792ecb67-examples-login-node-modules-send tar:///mnt/raid/src/web/passport-remember-me/examples/login/node_modules/send
53 silly lockFile 2c5e1bd5-steve-npm-send-0-1-4-package-tgz tar:///home/steve/.npm/send/0.1.4/package.tgz
54 silly lockFile 2c5e1bd5-steve-npm-send-0-1-4-package-tgz tar:///home/steve/.npm/send/0.1.4/package.tgz
55 info /mnt/raid/src/web/passport-remember-me/examples/login/node_modules/send unbuild
56 error Error: ENOENT, open '/mnt/raid/src/web/passport-remember-me/examples/login/node_modules/send/package.json'
57 error If you need help, you may report this log at:
57 error <http://github.com/isaacs/npm/issues>
57 error or email it to:
57 error <[email protected]>
58 error System Linux 3.11.9-200.fc19.x86_64
59 error command "/mnt/raid/local/bin/node" "/mnt/raid/local/bin/npm" "install" "send"
60 error cwd /mnt/raid/src/web/passport-remember-me/examples/login
61 error node -v v0.10.22
62 error npm -v 1.3.14
63 error path /mnt/raid/src/web/passport-remember-me/examples/login/node_modules/send/package.json
64 error code ENOENT
65 error errno 34
66 verbose exit [ 34, true ]
I noticed that if you use multiple slashes in the url, it's treated as if there is only 1 slash. This happens because there is no check for extra slashes before the path is normalized. Shouldn't it either result in a 404 error or fix the slashes with a redirect? To demonstrate this I put a list of urls that all serve the same files below.
http://expressjs.com/starter/faq.html
http://expressjs.com//starter/faq.html
http://expressjs.com/starter//faq.html
http://expressjs.com//starter//faq.html
http://expressjs.com///////////////////////////////starter/////////////////////////////////////////////faq.html
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.