Comparing version 2.1.1 to 2.2.0
417
main.js
// Copyright 2010-2011 Mikeal Rogers | ||
// | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
@@ -54,3 +54,3 @@ // distributed under the License is distributed on an "AS IS" BASIS, | ||
if (rs.readable && rs.path && rs.mode) { | ||
return true | ||
return true | ||
} | ||
@@ -61,3 +61,3 @@ } | ||
var o = {} | ||
for (i in obj) o[i] = obj[i] | ||
for (var i in obj) o[i] = obj[i] | ||
return o | ||
@@ -74,8 +74,8 @@ } | ||
this.writable = true | ||
if (typeof options === 'string') { | ||
options = {uri:options} | ||
} | ||
for (i in options) { | ||
for (var i in options) { | ||
this[i] = options[i] | ||
@@ -94,32 +94,45 @@ } | ||
} | ||
Request.prototype.request = function () { | ||
var options = this | ||
if (options.url) { | ||
Request.prototype.request = function () { | ||
var self = this | ||
// Protect against double callback | ||
if (!self._callback && self.callback) { | ||
self._callback = self.callback | ||
self.callback = function () { | ||
if (self._callbackCalled) return // Print a warning maybe? | ||
self._callback.apply(self, arguments) | ||
self._callbackCalled = true | ||
} | ||
} | ||
if (self.url) { | ||
// People use this property instead all the time so why not just support it. | ||
options.uri = options.url | ||
delete options.url | ||
self.uri = self.url | ||
delete self.url | ||
} | ||
if (!options.uri) { | ||
if (!self.uri) { | ||
throw new Error("options.uri is a required argument") | ||
} else { | ||
if (typeof options.uri == "string") options.uri = url.parse(options.uri) | ||
if (typeof self.uri == "string") self.uri = url.parse(self.uri) | ||
} | ||
if (options.proxy) { | ||
if (typeof options.proxy == 'string') options.proxy = url.parse(options.proxy) | ||
if (self.proxy) { | ||
if (typeof self.proxy == 'string') self.proxy = url.parse(self.proxy) | ||
} | ||
options._redirectsFollowed = options._redirectsFollowed || 0 | ||
options.maxRedirects = (options.maxRedirects !== undefined) ? options.maxRedirects : 10 | ||
options.followRedirect = (options.followRedirect !== undefined) ? options.followRedirect : true | ||
options.headers = options.headers ? copy(options.headers) : {} | ||
self._redirectsFollowed = self._redirectsFollowed || 0 | ||
self.maxRedirects = (self.maxRedirects !== undefined) ? self.maxRedirects : 10 | ||
self.followRedirect = (self.followRedirect !== undefined) ? self.followRedirect : true | ||
if (self.followRedirect) | ||
self.redirects = self.redirects || [] | ||
self.headers = self.headers ? copy(self.headers) : {} | ||
var setHost = false | ||
if (!options.headers.host) { | ||
options.headers.host = options.uri.hostname | ||
if (options.uri.port) { | ||
if ( !(options.uri.port === 80 && options.uri.protocol === 'http:') && | ||
!(options.uri.port === 443 && options.uri.protocol === 'https:') ) | ||
options.headers.host += (':'+options.uri.port) | ||
if (!self.headers.host) { | ||
self.headers.host = self.uri.hostname | ||
if (self.uri.port) { | ||
if ( !(self.uri.port === 80 && self.uri.protocol === 'http:') && | ||
!(self.uri.port === 443 && self.uri.protocol === 'https:') ) | ||
self.headers.host += (':'+self.uri.port) | ||
} | ||
@@ -129,78 +142,79 @@ setHost = true | ||
if (!options.uri.pathname) {options.uri.pathname = '/'} | ||
if (!options.uri.port) { | ||
if (options.uri.protocol == 'http:') {options.uri.port = 80} | ||
else if (options.uri.protocol == 'https:') {options.uri.port = 443} | ||
if (!self.uri.pathname) {self.uri.pathname = '/'} | ||
if (!self.uri.port) { | ||
if (self.uri.protocol == 'http:') {self.uri.port = 80} | ||
else if (self.uri.protocol == 'https:') {self.uri.port = 443} | ||
} | ||
if (options.bodyStream || options.responseBodyStream) { | ||
console.error('options.bodyStream and options.responseBodyStream is deprecated. You should now send the request object to stream.pipe()') | ||
this.pipe(options.responseBodyStream || options.bodyStream) | ||
} | ||
if (options.proxy) { | ||
options.port = options.proxy.port | ||
options.host = options.proxy.hostname | ||
if (self.proxy) { | ||
self.port = self.proxy.port | ||
self.host = self.proxy.hostname | ||
} else { | ||
options.port = options.uri.port | ||
options.host = options.uri.hostname | ||
self.port = self.uri.port | ||
self.host = self.uri.hostname | ||
} | ||
if (options.onResponse === true) { | ||
options.onResponse = options.callback | ||
delete options.callback | ||
if (self.onResponse === true) { | ||
self.onResponse = self.callback | ||
delete self.callback | ||
} | ||
var clientErrorHandler = function (error) { | ||
if (setHost) delete options.headers.host | ||
options.emit('error', error) | ||
if (setHost) delete self.headers.host | ||
if (self.timeout && self.timeoutTimer) clearTimeout(self.timeoutTimer) | ||
self.emit('error', error) | ||
} | ||
if (options.onResponse) options.on('error', function (e) {options.onResponse(e)}) | ||
if (options.callback) options.on('error', function (e) {options.callback(e)}) | ||
if (self.onResponse) self.on('error', function (e) {self.onResponse(e)}) | ||
if (self.callback) self.on('error', function (e) {self.callback(e)}) | ||
if (options.uri.auth && !options.headers.authorization) { | ||
options.headers.authorization = "Basic " + toBase64(options.uri.auth.split(':').map(function(item){ return qs.unescape(item)}).join(':')) | ||
if (self.uri.auth && !self.headers.authorization) { | ||
self.headers.authorization = "Basic " + toBase64(self.uri.auth.split(':').map(function(item){ return qs.unescape(item)}).join(':')) | ||
} | ||
if (options.proxy && options.proxy.auth && !options.headers['proxy-authorization']) { | ||
options.headers.authorization = "Basic " + toBase64(options.uri.auth.split(':').map(function(item){ return qs.unescape(item)}).join(':')) | ||
if (self.proxy && self.proxy.auth && !self.headers['proxy-authorization']) { | ||
self.headers['proxy-authorization'] = "Basic " + toBase64(self.proxy.auth.split(':').map(function(item){ return qs.unescape(item)}).join(':')) | ||
} | ||
options.path = options.uri.href.replace(options.uri.protocol + '//' + options.uri.host, '') | ||
if (options.path.length === 0) options.path = '/' | ||
if (self.uri.path) { | ||
self.path = self.uri.path | ||
} else { | ||
self.path = self.uri.pathname + (self.uri.search || "") | ||
} | ||
if (options.proxy) options.path = (options.uri.protocol + '//' + options.uri.host + options.path) | ||
if (self.path.length === 0) self.path = '/' | ||
if (options.json) { | ||
options.headers['content-type'] = 'application/json' | ||
if (typeof options.json === 'boolean') { | ||
if (typeof options.body === 'object') options.body = JSON.stringify(options.body) | ||
if (self.proxy) self.path = (self.uri.protocol + '//' + self.uri.host + self.path) | ||
if (self.json) { | ||
self.headers['content-type'] = 'application/json' | ||
if (typeof self.json === 'boolean') { | ||
if (typeof self.body === 'object') self.body = JSON.stringify(self.body) | ||
} else { | ||
options.body = JSON.stringify(options.json) | ||
self.body = JSON.stringify(self.json) | ||
} | ||
} else if (options.multipart) { | ||
options.body = '' | ||
options.headers['content-type'] = 'multipart/related;boundary="frontier"' | ||
if (!options.multipart.forEach) throw new Error('Argument error, options.multipart.') | ||
options.multipart.forEach(function (part) { | ||
} else if (self.multipart) { | ||
self.body = '' | ||
self.headers['content-type'] = 'multipart/related;boundary="frontier"' | ||
if (!self.multipart.forEach) throw new Error('Argument error, options.multipart.') | ||
self.multipart.forEach(function (part) { | ||
var body = part.body | ||
if(!body) throw Error('Body attribute missing in multipart.') | ||
delete part.body | ||
options.body += '--frontier\r\n' | ||
self.body += '--frontier\r\n' | ||
Object.keys(part).forEach(function(key){ | ||
options.body += key + ': ' + part[key] + '\r\n' | ||
self.body += key + ': ' + part[key] + '\r\n' | ||
}) | ||
options.body += '\r\n' + body + '\r\n' | ||
self.body += '\r\n' + body + '\r\n' | ||
}) | ||
options.body += '--frontier--' | ||
self.body += '--frontier--' | ||
} | ||
if (options.body) { | ||
if (!Buffer.isBuffer(options.body)) { | ||
options.body = new Buffer(options.body) | ||
if (self.body) { | ||
if (!Buffer.isBuffer(self.body)) { | ||
self.body = new Buffer(self.body) | ||
} | ||
if (options.body.length) { | ||
options.headers['content-length'] = options.body.length | ||
if (self.body.length) { | ||
self.headers['content-length'] = self.body.length | ||
} else { | ||
@@ -210,74 +224,85 @@ throw new Error('Argument error, options.body.') | ||
} | ||
options.httpModule = | ||
{"http:":http, "https:":https}[options.proxy ? options.proxy.protocol : options.uri.protocol] | ||
if (!options.httpModule) throw new Error("Invalid protocol") | ||
if (options.pool === false) { | ||
options.agent = false | ||
self.httpModule = | ||
{"http:":http, "https:":https}[self.proxy ? self.proxy.protocol : self.uri.protocol] | ||
if (!self.httpModule) throw new Error("Invalid protocol") | ||
if (self.pool === false) { | ||
self.agent = false | ||
} else { | ||
if (options.maxSockets) { | ||
if (self.maxSockets) { | ||
// Don't use our pooling if node has the refactored client | ||
options.agent = options.httpModule.globalAgent || options.getAgent(options.host, options.port) | ||
options.agent.maxSockets = options.maxSockets | ||
self.agent = self.httpModule.globalAgent || self.getAgent(self.host, self.port) | ||
self.agent.maxSockets = self.maxSockets | ||
} | ||
if (options.pool.maxSockets) { | ||
if (self.pool.maxSockets) { | ||
// Don't use our pooling if node has the refactored client | ||
options.agent = options.httpModule.globalAgent || options.getAgent(options.host, options.port) | ||
options.agent.maxSockets = options.pool.maxSockets | ||
self.agent = self.httpModule.globalAgent || self.getAgent(self.host, self.port) | ||
self.agent.maxSockets = self.pool.maxSockets | ||
} | ||
} | ||
options.start = function () { | ||
options._started = true | ||
options.method = options.method || 'GET' | ||
options.req = options.httpModule.request(options, function (response) { | ||
options.response = response | ||
response.request = options | ||
if (setHost) delete options.headers.host | ||
if (options.timeout && options.timeoutTimer) clearTimeout(options.timeoutTimer) | ||
if (response.statusCode >= 300 && | ||
response.statusCode < 400 && | ||
options.followRedirect && | ||
options.method !== 'PUT' && | ||
options.method !== 'POST' && | ||
self.start = function () { | ||
self._started = true | ||
self.method = self.method || 'GET' | ||
self.req = self.httpModule.request(self, function (response) { | ||
self.response = response | ||
response.request = self | ||
if (self.httpModule === https && | ||
self.strictSSL && | ||
!response.client.authorized) { | ||
var sslErr = response.client.authorizationError | ||
self.emit('error', new Error('SSL Error: '+ sslErr)) | ||
return | ||
} | ||
if (setHost) delete self.headers.host | ||
if (self.timeout && self.timeoutTimer) clearTimeout(self.timeoutTimer) | ||
if (response.statusCode >= 300 && | ||
response.statusCode < 400 && | ||
self.followRedirect && | ||
self.method !== 'PUT' && | ||
self.method !== 'POST' && | ||
response.headers.location) { | ||
if (options._redirectsFollowed >= options.maxRedirects) { | ||
options.emit('error', new Error("Exceeded maxRedirects. Probably stuck in a redirect loop.")) | ||
if (self._redirectsFollowed >= self.maxRedirects) { | ||
self.emit('error', new Error("Exceeded maxRedirects. Probably stuck in a redirect loop.")) | ||
return | ||
} | ||
options._redirectsFollowed += 1 | ||
self._redirectsFollowed += 1 | ||
if (!isUrl.test(response.headers.location)) { | ||
response.headers.location = url.resolve(options.uri.href, response.headers.location) | ||
response.headers.location = url.resolve(self.uri.href, response.headers.location) | ||
} | ||
options.uri = response.headers.location | ||
delete options.req | ||
delete options.agent | ||
delete options._started | ||
if (options.headers) { | ||
delete options.headers.host | ||
self.uri = response.headers.location | ||
self.redirects.push( { statusCode : response.statusCode, | ||
redirectUri: response.headers.location }) | ||
delete self.req | ||
delete self.agent | ||
delete self._started | ||
if (self.headers) { | ||
delete self.headers.host | ||
} | ||
request(options, options.callback) | ||
request(self, self.callback) | ||
return // Ignore the rest of the response | ||
} else { | ||
options._redirectsFollowed = 0 | ||
self._redirectsFollowed = self._redirectsFollowed || 0 | ||
// Be a good stream and emit end when the response is finished. | ||
// Hack to emit end on close because of a core bug that never fires end | ||
response.on('close', function () { | ||
if (!options._ended) options.response.emit('end') | ||
if (!self._ended) self.response.emit('end') | ||
}) | ||
if (options.encoding) { | ||
if (options.dests.length !== 0) { | ||
if (self.encoding) { | ||
if (self.dests.length !== 0) { | ||
console.error("Ingoring encoding parameter as this stream is being piped to another stream which makes the encoding option invalid.") | ||
} else { | ||
response.setEncoding(options.encoding) | ||
response.setEncoding(self.encoding) | ||
} | ||
} | ||
options.dests.forEach(function (dest) { | ||
self.pipeDest = function (dest) { | ||
if (dest.headers) { | ||
@@ -288,5 +313,5 @@ dest.headers['content-type'] = response.headers['content-type'] | ||
} | ||
} | ||
} | ||
if (dest.setHeader) { | ||
for (i in response.headers) { | ||
for (var i in response.headers) { | ||
dest.setHeader(i, response.headers[i]) | ||
@@ -296,23 +321,45 @@ } | ||
} | ||
if (options.pipefilter) options.pipefilter(response, dest) | ||
if (self.pipefilter) self.pipefilter(response, dest) | ||
} | ||
self.dests.forEach(function (dest) { | ||
self.pipeDest(dest) | ||
}) | ||
response.on("data", function (chunk) {options.emit("data", chunk)}) | ||
response.on("data", function (chunk) { | ||
self._destdata = true | ||
self.emit("data", chunk) | ||
}) | ||
response.on("end", function (chunk) { | ||
options._ended = true | ||
options.emit("end", chunk) | ||
self._ended = true | ||
self.emit("end", chunk) | ||
}) | ||
response.on("close", function () {options.emit("close")}) | ||
response.on("close", function () {self.emit("close")}) | ||
if (options.onResponse) { | ||
options.onResponse(null, response) | ||
self.emit('response', response) | ||
if (self.onResponse) { | ||
self.onResponse(null, response) | ||
} | ||
if (options.callback) { | ||
var buffer = '' | ||
options.on("data", function (chunk) { | ||
buffer += chunk | ||
if (self.callback) { | ||
var buffer = [] | ||
var bodyLen = 0 | ||
self.on("data", function (chunk) { | ||
buffer.push(chunk) | ||
bodyLen += chunk.length | ||
}) | ||
options.on("end", function () { | ||
response.body = buffer | ||
if (options.json) { | ||
self.on("end", function () { | ||
if (buffer.length && Buffer.isBuffer(buffer[0])) { | ||
var body = new Buffer(bodyLen) | ||
var i = 0 | ||
buffer.forEach(function (chunk) { | ||
chunk.copy(body, i, 0, chunk.length) | ||
i += chunk.length | ||
}) | ||
response.body = body.toString() | ||
} else if (buffer.length) { | ||
response.body = buffer.join('') | ||
} | ||
if (self.json) { | ||
try { | ||
@@ -322,4 +369,4 @@ response.body = JSON.parse(response.body) | ||
} | ||
options.callback(null, response, response.body) | ||
}) | ||
self.callback(null, response, response.body) | ||
}) | ||
} | ||
@@ -329,56 +376,68 @@ } | ||
if (options.timeout) { | ||
options.timeoutTimer = setTimeout(function() { | ||
options.req.abort() | ||
if (self.timeout) { | ||
self.timeoutTimer = setTimeout(function() { | ||
self.req.abort() | ||
var e = new Error("ETIMEDOUT") | ||
e.code = "ETIMEDOUT" | ||
options.emit("error", e) | ||
}, options.timeout) | ||
self.emit("error", e) | ||
}, self.timeout) | ||
} | ||
options.req.on('error', clientErrorHandler) | ||
} | ||
options.once('pipe', function (src) { | ||
if (options.ntick) throw new Error("You cannot pipe to this stream after the first nextTick() after creation of the request stream.") | ||
options.src = src | ||
self.req.on('error', clientErrorHandler) | ||
} | ||
self.once('pipe', function (src) { | ||
if (self.ntick) throw new Error("You cannot pipe to this stream after the first nextTick() after creation of the request stream.") | ||
self.src = src | ||
if (isReadStream(src)) { | ||
if (!options.headers['content-type'] && !options.headers['Content-Type']) | ||
options.headers['content-type'] = mimetypes.lookup(src.path.slice(src.path.lastIndexOf('.')+1)) | ||
if (!self.headers['content-type'] && !self.headers['Content-Type']) | ||
self.headers['content-type'] = mimetypes.lookup(src.path.slice(src.path.lastIndexOf('.')+1)) | ||
} else { | ||
if (src.headers) { | ||
for (i in src.headers) { | ||
if (!options.headers[i]) { | ||
options.headers[i] = src.headers[i] | ||
for (var i in src.headers) { | ||
if (!self.headers[i]) { | ||
self.headers[i] = src.headers[i] | ||
} | ||
} | ||
} | ||
if (src.method && !options.method) { | ||
options.method = src.method | ||
if (src.method && !self.method) { | ||
self.method = src.method | ||
} | ||
} | ||
options.on('pipe', function () { | ||
self.on('pipe', function () { | ||
console.error("You have already piped to this stream. Pipeing twice is likely to break the request.") | ||
}) | ||
}) | ||
process.nextTick(function () { | ||
if (options.body) { | ||
options.write(options.body) | ||
options.end() | ||
} else if (options.requestBodyStream) { | ||
if (self.body) { | ||
self.write(self.body) | ||
self.end() | ||
} else if (self.requestBodyStream) { | ||
console.warn("options.requestBodyStream is deprecated, please pass the request object to stream.pipe.") | ||
options.requestBodyStream.pipe(options) | ||
} else if (!options.src) { | ||
options.end() | ||
self.requestBodyStream.pipe(self) | ||
} else if (!self.src) { | ||
self.headers['content-length'] = 0 | ||
self.end() | ||
} | ||
options.ntick = true | ||
self.ntick = true | ||
}) | ||
} | ||
Request.prototype.pipe = function (dest) { | ||
if (this.response) throw new Error("You cannot pipe after the response event.") | ||
this.dests.push(dest) | ||
stream.Stream.prototype.pipe.call(this, dest) | ||
return dest | ||
if (this.response) { | ||
if (this._destdata) { | ||
throw new Error("You cannot pipe after data has been emitted from the response.") | ||
} else if (this._ended) { | ||
throw new Error("You cannot pipe after the response has been ended.") | ||
} else { | ||
stream.Stream.prototype.pipe.call(this, dest) | ||
this.pipeDest(dest) | ||
return dest | ||
} | ||
} else { | ||
this.dests.push(dest) | ||
stream.Stream.prototype.pipe.call(this, dest) | ||
return dest | ||
} | ||
} | ||
@@ -418,3 +477,3 @@ Request.prototype.write = function () { | ||
if (typeof opts === 'string') opts = {uri:opts} | ||
for (i in options) { | ||
for (var i in options) { | ||
if (opts[i] === undefined) opts[i] = options[i] | ||
@@ -426,3 +485,3 @@ } | ||
} | ||
de = def(request) | ||
var de = def(request) | ||
de.get = def(request.get) | ||
@@ -429,0 +488,0 @@ de.post = def(request.post) |
{ "name" : "request" | ||
, "description" : "Simplified HTTP request client." | ||
, "tags" : ["http", "simple", "util", "utility"] | ||
, "version" : "2.1.1" | ||
, "version" : "2.2.0" | ||
, "author" : "Mikeal Rogers <mikeal.rogers@gmail.com>" | ||
@@ -11,5 +11,6 @@ , "repository" : | ||
, "bugs" : | ||
{ "web" : "http://github.com/mikeal/request/issues" } | ||
{ "url" : "http://github.com/mikeal/request/issues" } | ||
, "engines" : ["node >= 0.3.6"] | ||
, "main" : "./main" | ||
, "scripts": { "test": "bash tests/run.sh" } | ||
} |
@@ -25,3 +25,3 @@ # Request -- Simplified HTTP request method | ||
if (!error && response.statusCode == 200) { | ||
sys.puts(body) // Print the google web page. | ||
console.log(body) // Print the google web page. | ||
} | ||
@@ -115,3 +115,5 @@ }) | ||
* `proxy` - An HTTP proxy to be used. Support proxy Auth with Basic Auth the same way it's supported with the `url` parameter by embedding the auth info in the uri. | ||
* `strictSSL` - Set to `true` to require that SSL certificates be valid. Note: to use your own certificate authority, you need to specify an agent that was created with that ca as an option. | ||
The callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second in an http.ClientResponse object. The third is the response body buffer. | ||
@@ -118,0 +120,0 @@ |
@@ -12,3 +12,3 @@ var http = require('http') | ||
}) | ||
s.listen(port) | ||
s.port = port | ||
s.url = 'http://localhost:'+port | ||
@@ -48,1 +48,12 @@ return s; | ||
} | ||
exports.createChunkResponse = function (chunks, contentType) { | ||
var l = function (req, resp) { | ||
contentType = contentType || 'text/plain' | ||
resp.writeHead(200, {'content-type':contentType}) | ||
chunks.forEach(function (chunk) { | ||
resp.write(chunk) | ||
}) | ||
resp.end() | ||
} | ||
return l; | ||
} |
@@ -10,8 +10,21 @@ var server = require('./server') | ||
var tests = | ||
{ testGet : | ||
{ resp : server.createGetResponse("TESTING!") | ||
var tests = | ||
{ testGet : | ||
{ resp : server.createGetResponse("TESTING!") | ||
, expectBody: "TESTING!" | ||
} | ||
, testGetJSON : | ||
, testGetChunkBreak : | ||
{ resp : server.createChunkResponse( | ||
[ new Buffer([239]) | ||
, new Buffer([163]) | ||
, new Buffer([191]) | ||
, new Buffer([206]) | ||
, new Buffer([169]) | ||
, new Buffer([226]) | ||
, new Buffer([152]) | ||
, new Buffer([131]) | ||
]) | ||
, expectBody: "Ω☃" | ||
} | ||
, testGetJSON : | ||
{ resp : server.createGetResponse('{"test":true}', 'application/json') | ||
@@ -21,3 +34,3 @@ , json : true | ||
} | ||
, testPutString : | ||
, testPutString : | ||
{ resp : server.createPostValidator("PUTTINGDATA") | ||
@@ -32,13 +45,8 @@ , method : "PUT" | ||
} | ||
, testPutStream : | ||
{ resp : server.createPostValidator("PUTTINGDATA") | ||
, method : "PUT" | ||
, requestBodyStream : server.createPostStream("PUTTINGDATA") | ||
} | ||
, testPutJSON : | ||
, testPutJSON : | ||
{ resp : server.createPostValidator(JSON.stringify({foo: 'bar'})) | ||
, method: "PUT" | ||
, json: {foo: 'bar'} | ||
, json: {foo: 'bar'} | ||
} | ||
, testPutMultipart : | ||
, testPutMultipart : | ||
{ resp: server.createPostValidator( | ||
@@ -54,29 +62,33 @@ '--frontier\r\n' + | ||
, method: "PUT" | ||
, multipart: | ||
, multipart: | ||
[ {'content-type': 'text/html', 'body': '<html><body>Oh hi.</body></html>'} | ||
, {'body': 'Oh hi.'} | ||
] | ||
} | ||
} | ||
} | ||
var counter = 0; | ||
s.listen(s.port, function () { | ||
for (i in tests) { | ||
(function () { | ||
var test = tests[i]; | ||
s.on('/'+i, test.resp); | ||
test.uri = s.url + '/' + i; | ||
request(test, function (err, resp, body) { | ||
if (err) throw err; | ||
if (test.expectBody) { | ||
assert.deepEqual(test.expectBody, body) | ||
} | ||
counter = counter - 1; | ||
if (counter === 0) { | ||
console.log(Object.keys(tests).length+" tests passed.") | ||
s.close(); | ||
} | ||
}) | ||
counter++; | ||
})() | ||
} | ||
var counter = 0 | ||
for (i in tests) { | ||
(function () { | ||
var test = tests[i] | ||
s.on('/'+i, test.resp) | ||
test.uri = s.url + '/' + i | ||
request(test, function (err, resp, body) { | ||
if (err) throw err | ||
if (test.expectBody) { | ||
assert.deepEqual(test.expectBody, body) | ||
} | ||
counter = counter - 1; | ||
if (counter === 0) { | ||
console.log(Object.keys(tests).length+" tests passed.") | ||
s.close() | ||
} | ||
}) | ||
counter++ | ||
})() | ||
} | ||
}) | ||
@@ -8,2 +8,3 @@ var server = require('./server') | ||
, path = require('path') | ||
, util = require('util') | ||
; | ||
@@ -13,126 +14,156 @@ | ||
passes = 0; | ||
var check = function () { | ||
if (passes === 7) { | ||
console.log('All tests passed.') | ||
setTimeout(function () { | ||
process.exit(); | ||
}, 500) | ||
} | ||
if (passes > 7) throw new Error('Need to update for more failures') | ||
function ValidationStream(str) { | ||
this.str = str | ||
this.buf = '' | ||
this.on('data', function (data) { | ||
this.buf += data | ||
}) | ||
this.on('end', function () { | ||
assert.equal(this.str, this.buf) | ||
}) | ||
this.writable = true | ||
} | ||
util.inherits(ValidationStream, stream.Stream) | ||
ValidationStream.prototype.write = function (chunk) { | ||
this.emit('data', chunk) | ||
} | ||
ValidationStream.prototype.end = function (chunk) { | ||
if (chunk) emit('data', chunk) | ||
this.emit('end') | ||
} | ||
// Test pipeing to a request object | ||
s.once('/push', server.createPostValidator("mydata")); | ||
s.listen(s.port, function () { | ||
counter = 0; | ||
var mydata = new stream.Stream(); | ||
mydata.readable = true | ||
var check = function () { | ||
counter = counter - 1 | ||
if (counter === 0) { | ||
console.log('All tests passed.') | ||
setTimeout(function () { | ||
process.exit(); | ||
}, 500) | ||
} | ||
} | ||
var r1 = request.put({url:'http://localhost:3453/push'}, function () { | ||
passes += 1; | ||
check(); | ||
}) | ||
mydata.pipe(r1) | ||
// Test pipeing to a request object | ||
s.once('/push', server.createPostValidator("mydata")); | ||
mydata.emit('data', 'mydata'); | ||
mydata.emit('end'); | ||
var mydata = new stream.Stream(); | ||
mydata.readable = true | ||
counter++ | ||
var r1 = request.put({url:'http://localhost:3453/push'}, function () { | ||
check(); | ||
}) | ||
mydata.pipe(r1) | ||
// Test pipeing from a request object. | ||
s.once('/pull', server.createGetResponse("mypulldata")); | ||
mydata.emit('data', 'mydata'); | ||
mydata.emit('end'); | ||
var mypulldata = new stream.Stream(); | ||
mypulldata.writable = true | ||
request({url:'http://localhost:3453/pull'}).pipe(mypulldata) | ||
// Test pipeing from a request object. | ||
s.once('/pull', server.createGetResponse("mypulldata")); | ||
var d = ''; | ||
var mypulldata = new stream.Stream(); | ||
mypulldata.writable = true | ||
mypulldata.write = function (chunk) { | ||
d += chunk; | ||
} | ||
mypulldata.end = function () { | ||
assert.equal(d, 'mypulldata'); | ||
passes += 1 | ||
check(); | ||
}; | ||
counter++ | ||
request({url:'http://localhost:3453/pull'}).pipe(mypulldata) | ||
var d = ''; | ||
s.on('/cat', function (req, resp) { | ||
if (req.method === "GET") { | ||
resp.writeHead(200, {'content-type':'text/plain-test', 'content-length':4}); | ||
resp.end('asdf') | ||
} else if (req.method === "PUT") { | ||
assert.equal(req.headers['content-type'], 'text/plain-test'); | ||
assert.equal(req.headers['content-length'], 4) | ||
var validate = ''; | ||
req.on('data', function (chunk) {validate += chunk}) | ||
req.on('end', function () { | ||
resp.writeHead(201); | ||
resp.end(); | ||
assert.equal(validate, 'asdf'); | ||
passes += 1; | ||
check(); | ||
}) | ||
mypulldata.write = function (chunk) { | ||
d += chunk; | ||
} | ||
}) | ||
s.on('/pushjs', function (req, resp) { | ||
if (req.method === "PUT") { | ||
assert.equal(req.headers['content-type'], 'text/javascript'); | ||
passes += 1; | ||
mypulldata.end = function () { | ||
assert.equal(d, 'mypulldata'); | ||
check(); | ||
} | ||
}) | ||
s.on('/catresp', function (req, resp) { | ||
request.get('http://localhost:3453/cat').pipe(resp) | ||
}) | ||
s.on('/doodle', function (req, resp) { | ||
if (req.headers['x-oneline-proxy']) { | ||
resp.setHeader('x-oneline-proxy', 'yup') | ||
} | ||
resp.writeHead('200', {'content-type':'image/png'}) | ||
fs.createReadStream(path.join(__dirname, 'googledoodle.png')).pipe(resp) | ||
}) | ||
s.on('/onelineproxy', function (req, resp) { | ||
var x = request('http://localhost:3453/doodle') | ||
req.pipe(x) | ||
x.pipe(resp) | ||
}) | ||
}; | ||
fs.createReadStream(__filename).pipe(request.put('http://localhost:3453/pushjs')) | ||
s.on('/cat', function (req, resp) { | ||
if (req.method === "GET") { | ||
resp.writeHead(200, {'content-type':'text/plain-test', 'content-length':4}); | ||
resp.end('asdf') | ||
} else if (req.method === "PUT") { | ||
assert.equal(req.headers['content-type'], 'text/plain-test'); | ||
assert.equal(req.headers['content-length'], 4) | ||
var validate = ''; | ||
request.get('http://localhost:3453/cat').pipe(request.put('http://localhost:3453/cat')) | ||
req.on('data', function (chunk) {validate += chunk}) | ||
req.on('end', function () { | ||
resp.writeHead(201); | ||
resp.end(); | ||
assert.equal(validate, 'asdf'); | ||
check(); | ||
}) | ||
} | ||
}) | ||
s.on('/pushjs', function (req, resp) { | ||
if (req.method === "PUT") { | ||
assert.equal(req.headers['content-type'], 'text/javascript'); | ||
check(); | ||
} | ||
}) | ||
s.on('/catresp', function (req, resp) { | ||
request.get('http://localhost:3453/cat').pipe(resp) | ||
}) | ||
s.on('/doodle', function (req, resp) { | ||
if (req.headers['x-oneline-proxy']) { | ||
resp.setHeader('x-oneline-proxy', 'yup') | ||
} | ||
resp.writeHead('200', {'content-type':'image/png'}) | ||
fs.createReadStream(path.join(__dirname, 'googledoodle.png')).pipe(resp) | ||
}) | ||
s.on('/onelineproxy', function (req, resp) { | ||
var x = request('http://localhost:3453/doodle') | ||
req.pipe(x) | ||
x.pipe(resp) | ||
}) | ||
request.get('http://localhost:3453/catresp', function (e, resp, body) { | ||
assert.equal(resp.headers['content-type'], 'text/plain-test'); | ||
assert.equal(resp.headers['content-length'], 4) | ||
passes += 1 | ||
check(); | ||
}) | ||
counter++ | ||
fs.createReadStream(__filename).pipe(request.put('http://localhost:3453/pushjs')) | ||
var doodleWrite = fs.createWriteStream(path.join(__dirname, 'test.png')) | ||
counter++ | ||
request.get('http://localhost:3453/cat').pipe(request.put('http://localhost:3453/cat')) | ||
request.get('http://localhost:3453/doodle').pipe(doodleWrite) | ||
counter++ | ||
request.get('http://localhost:3453/catresp', function (e, resp, body) { | ||
assert.equal(resp.headers['content-type'], 'text/plain-test'); | ||
assert.equal(resp.headers['content-length'], 4) | ||
check(); | ||
}) | ||
doodleWrite.on('close', function () { | ||
assert.deepEqual(fs.readFileSync(path.join(__dirname, 'googledoodle.png')), fs.readFileSync(path.join(__dirname, 'test.png'))) | ||
passes += 1 | ||
check() | ||
}) | ||
var doodleWrite = fs.createWriteStream(path.join(__dirname, 'test.png')) | ||
process.on('exit', function () { | ||
fs.unlinkSync(path.join(__dirname, 'test.png')) | ||
}) | ||
counter++ | ||
request.get('http://localhost:3453/doodle').pipe(doodleWrite) | ||
request.get({uri:'http://localhost:3453/onelineproxy', headers:{'x-oneline-proxy':'nope'}}, function (err, resp, body) { | ||
assert.equal(resp.headers['x-oneline-proxy'], 'yup') | ||
passes += 1 | ||
check() | ||
}) | ||
doodleWrite.on('close', function () { | ||
assert.deepEqual(fs.readFileSync(path.join(__dirname, 'googledoodle.png')), fs.readFileSync(path.join(__dirname, 'test.png'))) | ||
check() | ||
}) | ||
process.on('exit', function () { | ||
fs.unlinkSync(path.join(__dirname, 'test.png')) | ||
}) | ||
counter++ | ||
request.get({uri:'http://localhost:3453/onelineproxy', headers:{'x-oneline-proxy':'nope'}}, function (err, resp, body) { | ||
assert.equal(resp.headers['x-oneline-proxy'], 'yup') | ||
check() | ||
}) | ||
s.on('/afterresponse', function (req, resp) { | ||
resp.write('d') | ||
resp.end() | ||
}) | ||
counter++ | ||
var afterresp = request.post('http://localhost:3453/afterresponse').on('response', function () { | ||
var v = new ValidationStream('d') | ||
afterresp.pipe(v) | ||
v.on('end', check) | ||
}) | ||
}) |
@@ -12,74 +12,77 @@ var server = require('./server') | ||
// Request that waits for 200ms | ||
s.on('/timeout', function (req, resp) { | ||
setTimeout(function(){ | ||
resp.writeHead(200, {'content-type':'text/plain'}) | ||
resp.write(expectedBody) | ||
resp.end() | ||
}, 200); | ||
}); | ||
s.listen(s.port, function () { | ||
// Request that waits for 200ms | ||
s.on('/timeout', function (req, resp) { | ||
setTimeout(function(){ | ||
resp.writeHead(200, {'content-type':'text/plain'}) | ||
resp.write(expectedBody) | ||
resp.end() | ||
}, 200); | ||
}); | ||
// Scenario that should timeout | ||
var shouldTimeout = { | ||
url: s.url + "/timeout", | ||
timeout:100 | ||
} | ||
// Scenario that should timeout | ||
var shouldTimeout = { | ||
url: s.url + "/timeout", | ||
timeout:100 | ||
} | ||
request(shouldTimeout, function (err, resp, body) { | ||
assert.equal(err, "ETIMEDOUT"); | ||
checkDone(); | ||
}) | ||
request(shouldTimeout, function (err, resp, body) { | ||
assert.equal(err.code, "ETIMEDOUT"); | ||
checkDone(); | ||
}) | ||
// Scenario that shouldn't timeout | ||
var shouldntTimeout = { | ||
url: s.url + "/timeout", | ||
timeout:300 | ||
} | ||
request(shouldntTimeout, function (err, resp, body) { | ||
assert.equal(!err); | ||
assert.equal(expectedBody, body) | ||
checkDone(); | ||
}) | ||
// Scenario that shouldn't timeout | ||
var shouldntTimeout = { | ||
url: s.url + "/timeout", | ||
timeout:300 | ||
} | ||
// Scenario with no timeout set, so shouldn't timeout | ||
var noTimeout = { | ||
url: s.url + "/timeout" | ||
} | ||
request(shouldntTimeout, function (err, resp, body) { | ||
assert.equal(err, null); | ||
assert.equal(expectedBody, body) | ||
checkDone(); | ||
}) | ||
request(noTimeout, function (err, resp, body) { | ||
assert.equal(!err); | ||
assert.equal(expectedBody, body) | ||
checkDone(); | ||
}) | ||
// Scenario with no timeout set, so shouldn't timeout | ||
var noTimeout = { | ||
url: s.url + "/timeout" | ||
} | ||
// Scenario with a negative timeout value, should be treated a zero or the minimum delay | ||
var negativeTimeout = { | ||
url: s.url + "/timeout", | ||
timeout:-1000 | ||
} | ||
request(noTimeout, function (err, resp, body) { | ||
assert.equal(err); | ||
assert.equal(expectedBody, body) | ||
checkDone(); | ||
}) | ||
request(negativeTimeout, function (err, resp, body) { | ||
assert.equal(err, "ETIMEDOUT"); | ||
checkDone(); | ||
}) | ||
// Scenario with a negative timeout value, should be treated a zero or the minimum delay | ||
var negativeTimeout = { | ||
url: s.url + "/timeout", | ||
timeout:-1000 | ||
} | ||
// Scenario with a float timeout value, should be rounded by setTimeout anyway | ||
var floatTimeout = { | ||
url: s.url + "/timeout", | ||
timeout: 100.76 | ||
} | ||
request(negativeTimeout, function (err, resp, body) { | ||
assert.equal(err.code, "ETIMEDOUT"); | ||
checkDone(); | ||
}) | ||
request(floatTimeout, function (err, resp, body) { | ||
assert.equal(err, "ETIMEDOUT"); | ||
checkDone(); | ||
}) | ||
// Scenario with a float timeout value, should be rounded by setTimeout anyway | ||
var floatTimeout = { | ||
url: s.url + "/timeout", | ||
timeout: 100.76 | ||
} | ||
function checkDone() { | ||
if(--remainingTests == 0) { | ||
s.close(); | ||
console.log("All tests passed."); | ||
request(floatTimeout, function (err, resp, body) { | ||
assert.equal(err.code, "ETIMEDOUT"); | ||
checkDone(); | ||
}) | ||
function checkDone() { | ||
if(--remainingTests == 0) { | ||
s.close(); | ||
console.log("All tests passed."); | ||
} | ||
} | ||
} | ||
}) | ||
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
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
0
194
85163
12
966