Comparing version 1.4.6 to 1.5.0
@@ -82,2 +82,3 @@ ////////////////////////////////////////// | ||
follow_max : 0, | ||
stream_length : -1, | ||
@@ -133,2 +134,14 @@ // booleans | ||
function get_stream_length(stream, given_length, cb) { | ||
if (given_length > 0) | ||
return cb(given_length); | ||
if (stream.end !== void 0 && stream.end !== Infinity && stream.start !== void 0) | ||
return cb((stream.end + 1) - (stream.start || 0)); | ||
fs.stat(stream.path, function(err, stat) { | ||
cb(stat ? stat.size - (stream.start || 0) : null); | ||
}); | ||
} | ||
////////////////////////////////////////// | ||
@@ -272,3 +285,3 @@ // the main act | ||
var body, config = this.setup(uri, options); | ||
var self = this, body, waiting = false, config = this.setup(uri, options); | ||
@@ -281,22 +294,36 @@ // assume boss wants JSON either if json is true, or if content-type was set and JSON ain't false (weird). | ||
if (options.multipart) { // boss says we do multipart. so we do it. | ||
var boundary = options.boundary || defaults.boundary; | ||
var self = this, boundary = options.boundary || defaults.boundary; | ||
waiting = true; | ||
multipart.build(data, boundary, function(err, parts) { | ||
if (err) throw(err); | ||
config.headers['content-type'] = 'multipart/form-data; boundary=' + boundary; | ||
config.headers['content-length'] = parts.length; | ||
self.send_request(1, method, uri, config, parts, out, callback); | ||
config.headers['content-type'] = 'multipart/form-data; boundary=' + boundary; | ||
next(parts); | ||
}); | ||
return out; // stream | ||
} else if (is_stream(data)) { | ||
} else if (is_stream(data) || Buffer.isBuffer(data)) { | ||
if (is_stream(data) && method.toUpperCase() == 'GET') | ||
if (method.toUpperCase() == 'GET') | ||
throw new Error('Refusing to pipe() a stream via GET. Did you mean .post?'); | ||
body = data; // use the raw buffer or stream as request body. | ||
if (config.stream_length > 0 || (config.stream_length === 0 && data.path)) { | ||
// ok, let's get the stream's length and set it as the content-length header. | ||
// this prevents some servers from cutting us off before all the data is sent. | ||
waiting = true; | ||
get_stream_length(data, config.stream_length, function(length) { | ||
data.length = length; | ||
next(data); | ||
}) | ||
} else { | ||
// if the boss doesn't want us to get the stream's length, or if it doesn't | ||
// have a file descriptor for that purpose, then just head on. | ||
body = data; | ||
} | ||
} else if (Buffer.isBuffer(data)) { | ||
body = data; // use the raw buffer as request body. | ||
} else if (method.toUpperCase() == 'GET' && !json) { | ||
@@ -319,11 +346,12 @@ | ||
if (body) { | ||
// unless we have a stream or set a querystring, set the content length. | ||
if (body.length) config.headers['content-length'] = body.length; | ||
function next(body) { | ||
if (body) { | ||
if (body.length) config.headers['content-length'] = body.length; | ||
// if no content-type was passed, determine if json or not. | ||
if (!config.headers['content-type']) { | ||
config.headers['content-type'] = json | ||
? 'application/json; charset=utf-8' | ||
: 'application/x-www-form-urlencoded'; // no charset says W3 spec. | ||
// if no content-type was passed, determine if json or not. | ||
if (!config.headers['content-type']) { | ||
config.headers['content-type'] = json | ||
? 'application/json; charset=utf-8' | ||
: 'application/x-www-form-urlencoded'; // no charset says W3 spec. | ||
} | ||
} | ||
@@ -334,5 +362,8 @@ | ||
config.headers['accept'] = 'application/json'; | ||
self.send_request(1, method, uri, config, body, out, callback); | ||
} | ||
return this.send_request(1, method, uri, config, body, out, callback); | ||
if (!waiting) next(body); | ||
return out; | ||
} | ||
@@ -339,0 +370,0 @@ |
{ | ||
"name": "needle", | ||
"version": "1.4.6", | ||
"version": "1.5.0", | ||
"description": "The leanest and most handsome HTTP client in the Nodelands.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -71,3 +71,3 @@ Needle | ||
needle.get('https://google.com/images/logo.png').pipe(out).on('finish', function() { | ||
console.log('Pipe finished!'); | ||
console.log('Pipe finished!'); | ||
}); | ||
@@ -231,2 +231,3 @@ ``` | ||
- `json` : When `true`, sets content type to `application/json` and sends request body as JSON string, instead of a query string. | ||
- `stream_length`: When sending streams, this lets you manually set the Content-Length header --if the stream's bytecount is known beforehand--, preventing ECONNRESET (socket hang up) errors on some servers that misbehave when receiving payloads of unknown size. Set it to `0` and Needle will get and set the stream's length for you, or leave empty for the default behaviour, which is no Content-Length header for stream payloads. | ||
@@ -239,3 +240,3 @@ Response options | ||
- `output` : Dump response output to file. This occurs after parsing and charset decoding is done. | ||
- `parse_cookies` : Whether to parse response’s `Set-Cookie` header. Defaults to `true`. If parsed, cookies are set on `resp.cookies`. | ||
- `parse_cookies` : Whether to parse response’s `Set-Cookie` header. Defaults to `true`. If parsed, response cookies will be available at `resp.cookies`. | ||
@@ -303,3 +304,3 @@ Note: To stay light on dependencies, Needle doesn't include the `xml2js` module used for XML parsing. To enable it, simply do `npm install xml2js`. | ||
var tunnel = require('tunnel'); | ||
var myAgent = tunnel.httpOverHttp({ | ||
var myAgent = tunnel.httpOverHttp({ | ||
proxy: { host: 'localhost' } | ||
@@ -311,3 +312,3 @@ }); | ||
Regarding the 'Connection' header | ||
Regarding the 'Connection' header | ||
--------------------------------- | ||
@@ -314,0 +315,0 @@ |
@@ -6,3 +6,3 @@ var should = require('should'), | ||
stream = require('stream'), | ||
port = 11111, | ||
port = 11123, | ||
server; | ||
@@ -44,7 +44,9 @@ | ||
}).listen(port); | ||
}) | ||
server.listen(port); | ||
}); | ||
after(function(){ | ||
server.close(); | ||
after(function(done){ | ||
server.close(done); | ||
}) | ||
@@ -51,0 +53,0 @@ |
@@ -5,6 +5,8 @@ var http = require('http'), | ||
var port = 5432; | ||
describe('request headers', function() { | ||
var needle, | ||
server, | ||
server, | ||
existing_sockets, | ||
@@ -15,4 +17,4 @@ original_defaultMaxSockets; | ||
setTimeout(function() { | ||
existing_sockets = get_active_sockets().length; | ||
server = helpers.server({ port: 1234 }, done); | ||
existing_sockets = get_active_sockets().length; | ||
server = helpers.server({ port: port }, done); | ||
}, 100); | ||
@@ -26,3 +28,3 @@ }) | ||
function send_request(opts, cb) { | ||
needle.get('http://localhost:' + 1234, opts, cb); | ||
needle.get('http://localhost:' + port, opts, cb); | ||
} | ||
@@ -34,3 +36,3 @@ | ||
// only return the ones that have a .end() function (like a socket) | ||
return handles.filter(function(el) { | ||
return handles.filter(function(el) { | ||
if (el.constructor.name.toString() == 'Socket') { | ||
@@ -62,3 +64,3 @@ return el.destroyed !== true; | ||
done(); | ||
}) | ||
}) | ||
}) | ||
@@ -81,3 +83,3 @@ | ||
done(); | ||
}) | ||
}) | ||
}) | ||
@@ -100,3 +102,3 @@ | ||
done(); | ||
}) | ||
}) | ||
}) | ||
@@ -108,3 +110,3 @@ | ||
done(); | ||
}) | ||
}) | ||
}) | ||
@@ -139,3 +141,3 @@ | ||
// TODO: | ||
// TODO: | ||
// this is weird. by default, new node versions set a 'close' header | ||
@@ -148,3 +150,3 @@ // while older versions set a keep-alive header | ||
// done(); | ||
}) | ||
}) | ||
}) | ||
@@ -167,3 +169,3 @@ | ||
done(); | ||
}) | ||
}) | ||
}) | ||
@@ -186,3 +188,3 @@ | ||
done(); | ||
}) | ||
}) | ||
}) | ||
@@ -194,3 +196,3 @@ | ||
done(); | ||
}) | ||
}) | ||
}) | ||
@@ -197,0 +199,0 @@ |
@@ -27,3 +27,3 @@ var should = require('should'), | ||
describe('with default parse_response', function() { | ||
before(function() { | ||
@@ -40,3 +40,3 @@ needle.defaults().parse_response.should.eql('all') | ||
}) | ||
}) | ||
@@ -48,3 +48,3 @@ | ||
needle.defaults({ parse_response: false }) | ||
needle.get('localhost:' + port, function(err, response, body) { | ||
@@ -54,3 +54,3 @@ should.not.exist(err); | ||
body.toString().should.eql('{"foo":"bar"}'); | ||
needle.defaults({ parse_response: 'all' }); | ||
@@ -61,3 +61,3 @@ done(); | ||
}) | ||
@@ -64,0 +64,0 @@ |
@@ -7,2 +7,4 @@ var needle = require('../'), | ||
var port = 3456; | ||
describe('urls', function() { | ||
@@ -17,3 +19,3 @@ | ||
before(function(done){ | ||
server = helpers.server({ port: 3333 }, done); | ||
server = helpers.server({ port: port }, done); | ||
}) | ||
@@ -35,3 +37,2 @@ | ||
describe('invalid protocol', function(){ | ||
@@ -89,3 +90,3 @@ | ||
before(function() { | ||
url = 'http://localhost:3333/foo'; | ||
url = 'http://localhost:' + port + '/foo'; | ||
}) | ||
@@ -105,3 +106,3 @@ | ||
before(function() { | ||
url = '//localhost:3333/foo'; | ||
url = '//localhost:' + port + '/foo'; | ||
}) | ||
@@ -121,3 +122,3 @@ | ||
before(function() { | ||
url = 'localhost:3333/foo'; | ||
url = 'localhost:' + port + '/foo'; | ||
}) | ||
@@ -139,3 +140,3 @@ | ||
before(function() { | ||
url = 'localhost:3333' + path | ||
url = 'localhost:' + port + path | ||
}); | ||
@@ -142,0 +143,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
199697
45
4380
510
12
21