[d24f17c] | 1 | # on-finished
|
---|
| 2 |
|
---|
| 3 | [![NPM Version][npm-version-image]][npm-url]
|
---|
| 4 | [![NPM Downloads][npm-downloads-image]][npm-url]
|
---|
| 5 | [![Node.js Version][node-image]][node-url]
|
---|
| 6 | [![Build Status][ci-image]][ci-url]
|
---|
| 7 | [![Coverage Status][coveralls-image]][coveralls-url]
|
---|
| 8 |
|
---|
| 9 | Execute a callback when a HTTP request closes, finishes, or errors.
|
---|
| 10 |
|
---|
| 11 | ## Install
|
---|
| 12 |
|
---|
| 13 | This is a [Node.js](https://nodejs.org/en/) module available through the
|
---|
| 14 | [npm registry](https://www.npmjs.com/). Installation is done using the
|
---|
| 15 | [`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
|
---|
| 16 |
|
---|
| 17 | ```sh
|
---|
| 18 | $ npm install on-finished
|
---|
| 19 | ```
|
---|
| 20 |
|
---|
| 21 | ## API
|
---|
| 22 |
|
---|
| 23 | ```js
|
---|
| 24 | var onFinished = require('on-finished')
|
---|
| 25 | ```
|
---|
| 26 |
|
---|
| 27 | ### onFinished(res, listener)
|
---|
| 28 |
|
---|
| 29 | Attach a listener to listen for the response to finish. The listener will
|
---|
| 30 | be invoked only once when the response finished. If the response finished
|
---|
| 31 | to an error, the first argument will contain the error. If the response
|
---|
| 32 | has already finished, the listener will be invoked.
|
---|
| 33 |
|
---|
| 34 | Listening to the end of a response would be used to close things associated
|
---|
| 35 | with the response, like open files.
|
---|
| 36 |
|
---|
| 37 | Listener is invoked as `listener(err, res)`.
|
---|
| 38 |
|
---|
| 39 | <!-- eslint-disable handle-callback-err -->
|
---|
| 40 |
|
---|
| 41 | ```js
|
---|
| 42 | onFinished(res, function (err, res) {
|
---|
| 43 | // clean up open fds, etc.
|
---|
| 44 | // err contains the error if request error'd
|
---|
| 45 | })
|
---|
| 46 | ```
|
---|
| 47 |
|
---|
| 48 | ### onFinished(req, listener)
|
---|
| 49 |
|
---|
| 50 | Attach a listener to listen for the request to finish. The listener will
|
---|
| 51 | be invoked only once when the request finished. If the request finished
|
---|
| 52 | to an error, the first argument will contain the error. If the request
|
---|
| 53 | has already finished, the listener will be invoked.
|
---|
| 54 |
|
---|
| 55 | Listening to the end of a request would be used to know when to continue
|
---|
| 56 | after reading the data.
|
---|
| 57 |
|
---|
| 58 | Listener is invoked as `listener(err, req)`.
|
---|
| 59 |
|
---|
| 60 | <!-- eslint-disable handle-callback-err -->
|
---|
| 61 |
|
---|
| 62 | ```js
|
---|
| 63 | var data = ''
|
---|
| 64 |
|
---|
| 65 | req.setEncoding('utf8')
|
---|
| 66 | req.on('data', function (str) {
|
---|
| 67 | data += str
|
---|
| 68 | })
|
---|
| 69 |
|
---|
| 70 | onFinished(req, function (err, req) {
|
---|
| 71 | // data is read unless there is err
|
---|
| 72 | })
|
---|
| 73 | ```
|
---|
| 74 |
|
---|
| 75 | ### onFinished.isFinished(res)
|
---|
| 76 |
|
---|
| 77 | Determine if `res` is already finished. This would be useful to check and
|
---|
| 78 | not even start certain operations if the response has already finished.
|
---|
| 79 |
|
---|
| 80 | ### onFinished.isFinished(req)
|
---|
| 81 |
|
---|
| 82 | Determine if `req` is already finished. This would be useful to check and
|
---|
| 83 | not even start certain operations if the request has already finished.
|
---|
| 84 |
|
---|
| 85 | ## Special Node.js requests
|
---|
| 86 |
|
---|
| 87 | ### HTTP CONNECT method
|
---|
| 88 |
|
---|
| 89 | The meaning of the `CONNECT` method from RFC 7231, section 4.3.6:
|
---|
| 90 |
|
---|
| 91 | > The CONNECT method requests that the recipient establish a tunnel to
|
---|
| 92 | > the destination origin server identified by the request-target and,
|
---|
| 93 | > if successful, thereafter restrict its behavior to blind forwarding
|
---|
| 94 | > of packets, in both directions, until the tunnel is closed. Tunnels
|
---|
| 95 | > are commonly used to create an end-to-end virtual connection, through
|
---|
| 96 | > one or more proxies, which can then be secured using TLS (Transport
|
---|
| 97 | > Layer Security, [RFC5246]).
|
---|
| 98 |
|
---|
| 99 | In Node.js, these request objects come from the `'connect'` event on
|
---|
| 100 | the HTTP server.
|
---|
| 101 |
|
---|
| 102 | When this module is used on a HTTP `CONNECT` request, the request is
|
---|
| 103 | considered "finished" immediately, **due to limitations in the Node.js
|
---|
| 104 | interface**. This means if the `CONNECT` request contains a request entity,
|
---|
| 105 | the request will be considered "finished" even before it has been read.
|
---|
| 106 |
|
---|
| 107 | There is no such thing as a response object to a `CONNECT` request in
|
---|
| 108 | Node.js, so there is no support for one.
|
---|
| 109 |
|
---|
| 110 | ### HTTP Upgrade request
|
---|
| 111 |
|
---|
| 112 | The meaning of the `Upgrade` header from RFC 7230, section 6.1:
|
---|
| 113 |
|
---|
| 114 | > The "Upgrade" header field is intended to provide a simple mechanism
|
---|
| 115 | > for transitioning from HTTP/1.1 to some other protocol on the same
|
---|
| 116 | > connection.
|
---|
| 117 |
|
---|
| 118 | In Node.js, these request objects come from the `'upgrade'` event on
|
---|
| 119 | the HTTP server.
|
---|
| 120 |
|
---|
| 121 | When this module is used on a HTTP request with an `Upgrade` header, the
|
---|
| 122 | request is considered "finished" immediately, **due to limitations in the
|
---|
| 123 | Node.js interface**. This means if the `Upgrade` request contains a request
|
---|
| 124 | entity, the request will be considered "finished" even before it has been
|
---|
| 125 | read.
|
---|
| 126 |
|
---|
| 127 | There is no such thing as a response object to a `Upgrade` request in
|
---|
| 128 | Node.js, so there is no support for one.
|
---|
| 129 |
|
---|
| 130 | ## Example
|
---|
| 131 |
|
---|
| 132 | The following code ensures that file descriptors are always closed
|
---|
| 133 | once the response finishes.
|
---|
| 134 |
|
---|
| 135 | ```js
|
---|
| 136 | var destroy = require('destroy')
|
---|
| 137 | var fs = require('fs')
|
---|
| 138 | var http = require('http')
|
---|
| 139 | var onFinished = require('on-finished')
|
---|
| 140 |
|
---|
| 141 | http.createServer(function onRequest (req, res) {
|
---|
| 142 | var stream = fs.createReadStream('package.json')
|
---|
| 143 | stream.pipe(res)
|
---|
| 144 | onFinished(res, function () {
|
---|
| 145 | destroy(stream)
|
---|
| 146 | })
|
---|
| 147 | })
|
---|
| 148 | ```
|
---|
| 149 |
|
---|
| 150 | ## License
|
---|
| 151 |
|
---|
| 152 | [MIT](LICENSE)
|
---|
| 153 |
|
---|
| 154 | [ci-image]: https://badgen.net/github/checks/jshttp/on-finished/master?label=ci
|
---|
| 155 | [ci-url]: https://github.com/jshttp/on-finished/actions/workflows/ci.yml
|
---|
| 156 | [coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/on-finished/master
|
---|
| 157 | [coveralls-url]: https://coveralls.io/r/jshttp/on-finished?branch=master
|
---|
| 158 | [node-image]: https://badgen.net/npm/node/on-finished
|
---|
| 159 | [node-url]: https://nodejs.org/en/download
|
---|
| 160 | [npm-downloads-image]: https://badgen.net/npm/dm/on-finished
|
---|
| 161 | [npm-url]: https://npmjs.org/package/on-finished
|
---|
| 162 | [npm-version-image]: https://badgen.net/npm/v/on-finished
|
---|