master
Sven Slootweg 9 years ago
parent 83f40cbb8c
commit 6ab74cf093

3
.gitignore vendored

@ -1,3 +1,4 @@
# https://git-scm.com/docs/gitignore
# https://help.github.com/articles/ignoring-files
# Example .gitignore files: https://github.com/github/gitignore
# Example .gitignore files: https://github.com/github/gitignore
/node_modules/

@ -0,0 +1,89 @@
# stream-length
Attempts to determine the total content length of a Stream or Buffer.
Supports both Promises and nodebacks.
## License
[WTFPL](http://www.wtfpl.net/txt/copying/) or [CC0](https://creativecommons.org/publicdomain/zero/1.0/), whichever you prefer.
## Donate
My income consists entirely of donations for my projects. If this module is useful to you, consider [making a donation](http://cryto.net/~joepie91/donate.html)!
You can donate using Bitcoin, PayPal, Gratipay, Flattr, cash-in-mail, SEPA transfers, and pretty much anything else.
## Contributing
Pull requests welcome. Please make sure your modifications are in line with the overall code style, and ensure that you're editing the `.coffee` files, not the `.js` files.
Build tool of choice is `gulp`; simply run `gulp` while developing, and it will watch for changes.
Be aware that by making a pull request, you agree to release your modifications under the licenses stated above.
## Usage
Using Promises:
```javascript
var streamLength = require("stream-length");
Promise.try(function(){
return streamLength(fs.createReadStream("README.md"));
})
.then(function(result){
console.log("The length of README.md is " + result);
})
.catch(function(err){
console.log("Could not determine length. Error: " + err.toString());
});
```
Using nodebacks:
```javascript
var streamLength = require("stream-length");
streamLength(fs.createReadStream("README.md"), {}, function(err, result){
if(err)
{
console.log("Could not determine length. Error: " + err.toString());
}
else
{
console.log("The length of README.md is " + result);
}
});
```
Custom lengthRetrievers:
```javascript
Promise.try(function(){
return streamLength(fs.createReadStream("README.md"), [
function(stream, callback){
doSomethingWith(stream, function(err, len){
callback(err ? err : len);
})
}
]);
})
.then(function(result){
console.log("The length of README.md is " + result);
})
.catch(function(err){
console.log("Could not determine length. Error: " + err.toString());
});
```
## API
### streamLength(stream, [options, [callback]])
Determines the length of `stream`, which can be a supported type of Stream or a Buffer. Optionally you can specify `options`:
* __lengthRetrievers__: An array of (potentially asynchronous) functions for establishing stream lengths. You can specify one or more of these if you wish to extend `stream-length`s list of supported Stream types. Each retriever function is called with a signature of `(stream, callback)` where `stream` is the stream in question, and `callback` can be called with the result. If an Error occurs, simply pass the Error to the callback instead of the value.
If you define a `callback`, it will be treated as a nodeback and called when the function completes. If you don't, the function will return a Promise that resolves when the function completes.

@ -0,0 +1 @@
module.exports = require "./lib/stream-length"

@ -0,0 +1,75 @@
Promise = require "bluebird"
fs = Promise.promisifyAll(require "fs")
nodeifyWrapper = (callback, func) ->
func().nodeify(callback)
createRetrieverPromise = (stream, retriever) ->
new Promise (resolve, reject) ->
retriever stream, (result) ->
if result?
if result instanceof Error
console.log "REJECTING...", result
reject result
else
resolve result
else
reject new Error("Could not find a length using this lengthRetriever.")
retrieveBuffer = (stream, callback) ->
if stream instanceof Buffer
callback stream.length
else
callback null
retrieveFilesystemStream = (stream, callback) ->
if stream.hasOwnProperty "fd"
# FIXME: https://github.com/joyent/node/issues/7819
if stream.end != undefined and stream.end != Infinity and stream.start != undefined
# A stream start and end were defined, we can calculate the size just from that information.
callback(stream.end + 1 - (stream.start ? 0))
else
# We have the start offset at most, stat the file and work off the filesize.
Promise.try ->
fs.statAsync stream.path
.then (stat) ->
callback(stat.size - (stream.start ? 0))
.catch (err) ->
callback err
else
callback null
retrieveCoreHttpStream = (stream, callback) ->
if stream.hasOwnProperty("httpVersion") and stream.headers["content-length"]?
callback parseInt(stream.headers["content-length"])
else
callback null
retrieveRequestHttpStream = (stream, callback) ->
if stream.hasOwnProperty "httpModule"
stream.on "response", (response) ->
if response.headers["content-length"]?
callback parseInt(response.headers["content-length"])
else
callback null
else
callback null
module.exports = (stream, options = {}, callback) ->
nodeifyWrapper callback, ->
retrieverPromises = []
if options.lengthRetrievers?
# First, the custom length retrievers, if any.
for retriever in options.lengthRetrievers
retrieverPromises.push createRetrieverPromise(stream, retriever)
# Then, the standard ones.
for retriever in [retrieveBuffer, retrieveFilesystemStream, retrieveCoreHttpStream, retrieveRequestHttpStream]
retrieverPromises.push createRetrieverPromise(stream, retriever)
Promise.any retrieverPromises

@ -0,0 +1,26 @@
{
"name": "node-stream-length",
"version": "1.0.0",
"description": "For a given Buffer or Stream, this module will attempt to determine the total length of the stream contents. It currently supports Buffers, `fs` streams, `http` responses, and `request` objects, and allows for specifying custom stream types.",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git://github.com/joepie91/node-stream-length"
},
"keywords": [
"stream",
"length",
"content-length"
],
"author": "Sven Slootweg",
"license": "WTFPL",
"dependencies": {
"bluebird": "^2.6.2"
},
"devDependencies": {
"request": "^2.51.0"
}
}

@ -0,0 +1,59 @@
# This is a test case for petkaantonov/bluebird#432, encountered during development of this module.
Promise = require "bluebird"
successPromise = (val) ->
new Promise (resolve, reject) ->
process.nextTick -> resolve(val)
failurePromise = (val) ->
new Promise (resolve, reject) ->
process.nextTick -> reject(val)
successSyncPromise = (val) ->
new Promise (resolve, reject) ->
resolve(val)
failureSyncPromise = (val) ->
new Promise (resolve, reject) ->
reject(val)
failureSyncPromiseTwo = (val) ->
Promise.reject(val)
Promise.any [
successSyncPromise()
successPromise()
failureSyncPromise("fail a").catch (err) -> console.log err
]
.then -> console.log "success a"
Promise.any [
successSyncPromise()
successPromise()
failurePromise("fail b").catch (err) -> console.log err
]
.then -> console.log "success b"
Promise.any [
successPromise()
successPromise()
failurePromise("fail c").catch (err) -> console.log err
]
.then -> console.log "success c"
Promise.any [
successSyncPromise()
successSyncPromise()
failureSyncPromise("fail d").catch (err) -> console.log err
]
.then -> console.log "success d"
Promise.any [
successSyncPromise()
successSyncPromise()
failureSyncPromiseTwo("fail e").catch (err) -> console.log err
]
.then -> console.log "success e"

@ -0,0 +1,57 @@
streamLength = require "./"
fs = require "fs"
request = require "request"
http = require "http"
Promise = require "bluebird"
Promise.try ->
console.log "Length of fs:README.md..."
streamLength fs.createReadStream("README.md")
.then (length) ->
console.log "Length", length
.catch (err) ->
console.log "No-Length", err
.then ->
console.log "Length of Buffer..."
streamLength new Buffer("testing buffer content length retrieval...")
.then (length) ->
console.log "Length", length
.catch (err) ->
console.log "No-Length", err
.then ->
console.log "Length of http:Google"
new Promise (resolve, reject) ->
http.get "http://www.google.com/images/srpr/logo11w.png", (res) ->
resolve res
.on "error", (err) ->
reject err
.then (res) ->
res.resume() # Drain the stream
streamLength res
.then (length) ->
console.log "Length", length
.catch (err) ->
console.log "No-Length", err
.then ->
console.log "Length of request:Google..."
streamLength request "http://www.google.com/images/srpr/logo11w.png", (err, res, body) ->
# Ignore...
.then (length) ->
console.log "Length", length
.catch (err) ->
console.log "No-Length", err
.then ->
console.log "Length of request:Google:fail..."
streamLength request "http://www.google.com/", (err, res, body) ->
# Ignore...
.then (length) ->
console.log "Length", length
.catch (err) ->
console.log "No-Length", err
Loading…
Cancel
Save