README.md (9442B)
1 # send 2 3 [![NPM Version][npm-version-image]][npm-url] 4 [![NPM Downloads][npm-downloads-image]][npm-url] 5 [![Linux Build][travis-image]][travis-url] 6 [![Windows Build][appveyor-image]][appveyor-url] 7 [![Test Coverage][coveralls-image]][coveralls-url] 8 9 Send is a library for streaming files from the file system as a http response 10 supporting partial responses (Ranges), conditional-GET negotiation (If-Match, 11 If-Unmodified-Since, If-None-Match, If-Modified-Since), high test coverage, 12 and granular events which may be leveraged to take appropriate actions in your 13 application or framework. 14 15 Looking to serve up entire folders mapped to URLs? Try [serve-static](https://www.npmjs.org/package/serve-static). 16 17 ## Installation 18 19 This is a [Node.js](https://nodejs.org/en/) module available through the 20 [npm registry](https://www.npmjs.com/). Installation is done using the 21 [`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): 22 23 ```bash 24 $ npm install send 25 ``` 26 27 ## API 28 29 <!-- eslint-disable no-unused-vars --> 30 31 ```js 32 var send = require('send') 33 ``` 34 35 ### send(req, path, [options]) 36 37 Create a new `SendStream` for the given path to send to a `res`. The `req` is 38 the Node.js HTTP request and the `path` is a urlencoded path to send (urlencoded, 39 not the actual file-system path). 40 41 #### Options 42 43 ##### acceptRanges 44 45 Enable or disable accepting ranged requests, defaults to true. 46 Disabling this will not send `Accept-Ranges` and ignore the contents 47 of the `Range` request header. 48 49 ##### cacheControl 50 51 Enable or disable setting `Cache-Control` response header, defaults to 52 true. Disabling this will ignore the `immutable` and `maxAge` options. 53 54 ##### dotfiles 55 56 Set how "dotfiles" are treated when encountered. A dotfile is a file 57 or directory that begins with a dot ("."). Note this check is done on 58 the path itself without checking if the path actually exists on the 59 disk. If `root` is specified, only the dotfiles above the root are 60 checked (i.e. the root itself can be within a dotfile when when set 61 to "deny"). 62 63 - `'allow'` No special treatment for dotfiles. 64 - `'deny'` Send a 403 for any request for a dotfile. 65 - `'ignore'` Pretend like the dotfile does not exist and 404. 66 67 The default value is _similar_ to `'ignore'`, with the exception that 68 this default will not ignore the files within a directory that begins 69 with a dot, for backward-compatibility. 70 71 ##### end 72 73 Byte offset at which the stream ends, defaults to the length of the file 74 minus 1. The end is inclusive in the stream, meaning `end: 3` will include 75 the 4th byte in the stream. 76 77 ##### etag 78 79 Enable or disable etag generation, defaults to true. 80 81 ##### extensions 82 83 If a given file doesn't exist, try appending one of the given extensions, 84 in the given order. By default, this is disabled (set to `false`). An 85 example value that will serve extension-less HTML files: `['html', 'htm']`. 86 This is skipped if the requested file already has an extension. 87 88 ##### immutable 89 90 Enable or diable the `immutable` directive in the `Cache-Control` response 91 header, defaults to `false`. If set to `true`, the `maxAge` option should 92 also be specified to enable caching. The `immutable` directive will prevent 93 supported clients from making conditional requests during the life of the 94 `maxAge` option to check if the file has changed. 95 96 ##### index 97 98 By default send supports "index.html" files, to disable this 99 set `false` or to supply a new index pass a string or an array 100 in preferred order. 101 102 ##### lastModified 103 104 Enable or disable `Last-Modified` header, defaults to true. Uses the file 105 system's last modified value. 106 107 ##### maxAge 108 109 Provide a max-age in milliseconds for http caching, defaults to 0. 110 This can also be a string accepted by the 111 [ms](https://www.npmjs.org/package/ms#readme) module. 112 113 ##### root 114 115 Serve files relative to `path`. 116 117 ##### start 118 119 Byte offset at which the stream starts, defaults to 0. The start is inclusive, 120 meaning `start: 2` will include the 3rd byte in the stream. 121 122 #### Events 123 124 The `SendStream` is an event emitter and will emit the following events: 125 126 - `error` an error occurred `(err)` 127 - `directory` a directory was requested `(res, path)` 128 - `file` a file was requested `(path, stat)` 129 - `headers` the headers are about to be set on a file `(res, path, stat)` 130 - `stream` file streaming has started `(stream)` 131 - `end` streaming has completed 132 133 #### .pipe 134 135 The `pipe` method is used to pipe the response into the Node.js HTTP response 136 object, typically `send(req, path, options).pipe(res)`. 137 138 ### .mime 139 140 The `mime` export is the global instance of of the 141 [`mime` npm module](https://www.npmjs.com/package/mime). 142 143 This is used to configure the MIME types that are associated with file extensions 144 as well as other options for how to resolve the MIME type of a file (like the 145 default type to use for an unknown file extension). 146 147 ## Error-handling 148 149 By default when no `error` listeners are present an automatic response will be 150 made, otherwise you have full control over the response, aka you may show a 5xx 151 page etc. 152 153 ## Caching 154 155 It does _not_ perform internal caching, you should use a reverse proxy cache 156 such as Varnish for this, or those fancy things called CDNs. If your 157 application is small enough that it would benefit from single-node memory 158 caching, it's small enough that it does not need caching at all ;). 159 160 ## Debugging 161 162 To enable `debug()` instrumentation output export __DEBUG__: 163 164 ``` 165 $ DEBUG=send node app 166 ``` 167 168 ## Running tests 169 170 ``` 171 $ npm install 172 $ npm test 173 ``` 174 175 ## Examples 176 177 ### Serve a specific file 178 179 This simple example will send a specific file to all requests. 180 181 ```js 182 var http = require('http') 183 var send = require('send') 184 185 var server = http.createServer(function onRequest (req, res) { 186 send(req, '/path/to/index.html') 187 .pipe(res) 188 }) 189 190 server.listen(3000) 191 ``` 192 193 ### Serve all files from a directory 194 195 This simple example will just serve up all the files in a 196 given directory as the top-level. For example, a request 197 `GET /foo.txt` will send back `/www/public/foo.txt`. 198 199 ```js 200 var http = require('http') 201 var parseUrl = require('parseurl') 202 var send = require('send') 203 204 var server = http.createServer(function onRequest (req, res) { 205 send(req, parseUrl(req).pathname, { root: '/www/public' }) 206 .pipe(res) 207 }) 208 209 server.listen(3000) 210 ``` 211 212 ### Custom file types 213 214 ```js 215 var http = require('http') 216 var parseUrl = require('parseurl') 217 var send = require('send') 218 219 // Default unknown types to text/plain 220 send.mime.default_type = 'text/plain' 221 222 // Add a custom type 223 send.mime.define({ 224 'application/x-my-type': ['x-mt', 'x-mtt'] 225 }) 226 227 var server = http.createServer(function onRequest (req, res) { 228 send(req, parseUrl(req).pathname, { root: '/www/public' }) 229 .pipe(res) 230 }) 231 232 server.listen(3000) 233 ``` 234 235 ### Custom directory index view 236 237 This is a example of serving up a structure of directories with a 238 custom function to render a listing of a directory. 239 240 ```js 241 var http = require('http') 242 var fs = require('fs') 243 var parseUrl = require('parseurl') 244 var send = require('send') 245 246 // Transfer arbitrary files from within /www/example.com/public/* 247 // with a custom handler for directory listing 248 var server = http.createServer(function onRequest (req, res) { 249 send(req, parseUrl(req).pathname, { index: false, root: '/www/public' }) 250 .once('directory', directory) 251 .pipe(res) 252 }) 253 254 server.listen(3000) 255 256 // Custom directory handler 257 function directory (res, path) { 258 var stream = this 259 260 // redirect to trailing slash for consistent url 261 if (!stream.hasTrailingSlash()) { 262 return stream.redirect(path) 263 } 264 265 // get directory list 266 fs.readdir(path, function onReaddir (err, list) { 267 if (err) return stream.error(err) 268 269 // render an index for the directory 270 res.setHeader('Content-Type', 'text/plain; charset=UTF-8') 271 res.end(list.join('\n') + '\n') 272 }) 273 } 274 ``` 275 276 ### Serving from a root directory with custom error-handling 277 278 ```js 279 var http = require('http') 280 var parseUrl = require('parseurl') 281 var send = require('send') 282 283 var server = http.createServer(function onRequest (req, res) { 284 // your custom error-handling logic: 285 function error (err) { 286 res.statusCode = err.status || 500 287 res.end(err.message) 288 } 289 290 // your custom headers 291 function headers (res, path, stat) { 292 // serve all files for download 293 res.setHeader('Content-Disposition', 'attachment') 294 } 295 296 // your custom directory handling logic: 297 function redirect () { 298 res.statusCode = 301 299 res.setHeader('Location', req.url + '/') 300 res.end('Redirecting to ' + req.url + '/') 301 } 302 303 // transfer arbitrary files from within 304 // /www/example.com/public/* 305 send(req, parseUrl(req).pathname, { root: '/www/public' }) 306 .on('error', error) 307 .on('directory', redirect) 308 .on('headers', headers) 309 .pipe(res) 310 }) 311 312 server.listen(3000) 313 ``` 314 315 ## License 316 317 [MIT](LICENSE) 318 319 [appveyor-image]: https://badgen.net/appveyor/ci/dougwilson/send/master?label=windows 320 [appveyor-url]: https://ci.appveyor.com/project/dougwilson/send 321 [coveralls-image]: https://badgen.net/coveralls/c/github/pillarjs/send/master 322 [coveralls-url]: https://coveralls.io/r/pillarjs/send?branch=master 323 [node-image]: https://badgen.net/npm/node/send 324 [node-url]: https://nodejs.org/en/download/ 325 [npm-downloads-image]: https://badgen.net/npm/dm/send 326 [npm-url]: https://npmjs.org/package/send 327 [npm-version-image]: https://badgen.net/npm/v/send 328 [travis-image]: https://badgen.net/travis/pillarjs/send/master?label=linux 329 [travis-url]: https://travis-ci.org/pillarjs/send