Comparing version 0.2.7 to 0.2.8
@@ -76,105 +76,115 @@ // Copyright 2014 Tjatse | ||
var req = this.client.request(this.options, function (res) { | ||
var status = res.statusCode; | ||
if(!!~[301,302,303].indexOf(status)){ | ||
if(!this.options.disableRedirect && this.redirects.length < this.options.maxRedirects){ | ||
var nextTarget = URI(res.headers.location).absoluteTo(this.options.uri); | ||
this.redirects.push(nextTarget.valueOf()); | ||
try { | ||
var req = this.client.request(this.options, function(res){ | ||
var status = res.statusCode; | ||
if (!!~[301, 302, 303].indexOf(status)) { | ||
if (!this.options.disableRedirect && this.redirects.length < this.options.maxRedirects) { | ||
var nextTarget = URI(res.headers.location).absoluteTo(this.options.uri); | ||
this.redirects.push(nextTarget.valueOf()); | ||
// reset host | ||
this.options.headers.host = nextTarget.host(); | ||
this.options.path = nextTarget.path() + nextTarget.search(); | ||
this.options.host = nextTarget.hostname(); | ||
this.options.port = nextTarget.port(); | ||
// reset client, host | ||
this.client = myUtil.analyzeUri(nextTarget, this.options); | ||
if(this.options.trackCookie){ | ||
var cookies = myUtil.cookieJar(res.headers['set-cookie']); | ||
for(var k in cookies){ | ||
this.cookies[k] = cookies[k]; | ||
if (this.options.trackCookie) { | ||
var cookies = myUtil.cookieJar(res.headers['set-cookie']); | ||
for (var k in cookies) { | ||
this.cookies[k] = cookies[k]; | ||
} | ||
} | ||
// CAUTION: abort previous request at first. | ||
try { | ||
req && req.abort(); | ||
req = null; | ||
} catch (err) { | ||
} | ||
return myUtil.next(this.request, this); | ||
} else { | ||
// just fake it, no more redirects. | ||
status = 200; | ||
} | ||
// CAUTION: abort previous request at first. | ||
try{ req && req.abort(); req = null; }catch(err){ } | ||
return myUtil.next(this.request, this); | ||
}else{ | ||
// just fake it, no more redirects. | ||
status = 200; | ||
} | ||
} | ||
// not okay | ||
if(status < 200 || status > 207){ | ||
return this.emit('error', new Error(status + ' ' + (http.STATUS_CODES[status] || 'status code.')), {statusCode: status}); | ||
} | ||
// on data was received | ||
function onData(o, chunk){ | ||
if(req._aborted){ | ||
o.removeAllListeners(); | ||
return onError.call(this, new Error('ETIMEOUT')); | ||
// not okay | ||
if (status < 200 || status > 207) { | ||
return this.emit('error', new Error(status + ' ' + (http.STATUS_CODES[status] || 'status code.')), {statusCode: status}); | ||
} | ||
if (chunk && chunk.length > 0) { | ||
this.emit('data', this.options.encoding ? chunk.toString(this.options.encoding) : chunk); | ||
// on data was received | ||
function onData(o, chunk){ | ||
if (req._aborted) { | ||
o.removeAllListeners(); | ||
return onError.call(this, new Error('ETIMEOUT')); | ||
} | ||
if (chunk && chunk.length > 0) { | ||
this.emit('data', this.options.encoding ? chunk.toString(this.options.encoding) : chunk); | ||
} | ||
} | ||
} | ||
// on error was caught | ||
function onError(error){ | ||
this.emit('error', error); | ||
} | ||
// on the end | ||
function onEnd(o) { | ||
if(req._aborted){ | ||
o.removeAllListeners(); | ||
return onError.call(this, new Error('ETIMEOUT')); | ||
// on error was caught | ||
function onError(error){ | ||
this.emit('error', error); | ||
} | ||
this.emit('end'); | ||
} | ||
this.emit('extra', { | ||
headers: res.headers, | ||
redirects: this.redirects, | ||
cookies: this.cookies, | ||
statusCode: res.statusCode | ||
}); | ||
delete this.redirects; | ||
delete this.cookies; | ||
// on the end | ||
function onEnd(o){ | ||
if (req._aborted) { | ||
o.removeAllListeners(); | ||
return onError.call(this, new Error('ETIMEOUT')); | ||
} | ||
this.emit('end'); | ||
} | ||
// gzip,deflate encoding | ||
var encoding; | ||
if(!this.options.disableGzip && (encoding = res.headers['content-encoding'])){ | ||
encoding = encoding.toLowerCase(); | ||
var method = {'gzip': 'Gunzip', 'deflate': 'Inflate'}[encoding]; | ||
if(method){ | ||
var gz = zlib['create' + method](); | ||
gz.on('data', onData.bind(this, gz)); | ||
gz.on('end', onEnd.bind(this, gz)); | ||
gz.once('error', onError.bind(this)); | ||
return res.pipe(gz); | ||
this.emit('extra', { | ||
headers : res.headers, | ||
redirects : this.redirects, | ||
cookies : this.cookies, | ||
statusCode: res.statusCode | ||
}); | ||
delete this.redirects; | ||
delete this.cookies; | ||
// gzip,deflate encoding | ||
var encoding; | ||
if (!this.options.disableGzip && (encoding = res.headers['content-encoding'])) { | ||
encoding = encoding.toLowerCase(); | ||
var method = {'gzip': 'Gunzip', 'deflate': 'Inflate'}[encoding]; | ||
if (method) { | ||
var gz = zlib['create' + method](); | ||
gz.on('data', onData.bind(this, gz)); | ||
gz.on('end', onEnd.bind(this, gz)); | ||
gz.once('error', onError.bind(this)); | ||
return res.pipe(gz); | ||
} | ||
} | ||
} | ||
// normalize | ||
res.on('data', onData.bind(this, res)); | ||
res.on('end', onEnd.bind(this, res)); | ||
res.once('error', onError.bind(this)); | ||
}.bind(this)); | ||
// normalize | ||
res.on('data', onData.bind(this, res)); | ||
res.on('end', onEnd.bind(this, res)); | ||
res.once('error', onError.bind(this)); | ||
}.bind(this)); | ||
// timeout. | ||
if(typeof this.options.timeout == 'number'){ | ||
req.setTimeout(this.options.timeout, function(){ | ||
try{req.abort();}catch(err){} | ||
req._aborted = true; | ||
// timeout. | ||
if (typeof this.options.timeout == 'number') { | ||
req.setTimeout(this.options.timeout, function(){ | ||
try { | ||
req.abort(); | ||
} catch (err) { | ||
} | ||
req._aborted = true; | ||
}.bind(this)); | ||
} | ||
// on error. | ||
req.once('error', function(error){ | ||
this.emit('error', error); | ||
}.bind(this)); | ||
} | ||
// on error. | ||
req.once('error', function (error) { | ||
this.emit('error', error); | ||
}.bind(this)); | ||
// send data if necessary. | ||
if(!!~['POST', 'PUT', 'PATCH'].indexOf(this.options.method) && this.options._data){ | ||
req.write(this.options._data); | ||
// send data if necessary. | ||
if (!!~['POST', 'PUT', 'PATCH'].indexOf(this.options.method) && this.options._data) { | ||
req.write(this.options._data); | ||
} | ||
delete this.options._data; | ||
// sent. | ||
req.end(); | ||
}catch(err){ | ||
this.emit('error', new Error('Request failed due to ' + err.message), {statusCode: 503}); | ||
} | ||
delete this.options._data; | ||
// sent. | ||
req.end(); | ||
}; |
@@ -148,19 +148,4 @@ var qs = require('querystring'), | ||
retVal.client = util.analyzeUri(uriEntity, options); | ||
options.path = uriEntity.path() + uriEntity.search(); | ||
options.host = uriEntity.hostname(); | ||
options.port = uriEntity.port(); | ||
// http && https | ||
if (uriEntity.protocol() == 'https') { | ||
retVal.client = https; | ||
!options.port && (options.port = 443); | ||
// can not use protocol here, complicated with [http.request]'s options. | ||
options.__protocol = 'https'; | ||
} else { | ||
retVal.client = http; | ||
!options.port && (options.port = 80); | ||
options.__protocol = 'http'; | ||
} | ||
// proxy. | ||
@@ -184,1 +169,26 @@ if (typeof options.proxy != 'object' || !options.proxy.host) { | ||
}; | ||
/** | ||
* Analyze the uri and generate request client, host, port, protocol... | ||
* @param {uri} uriEntity | ||
* @param {Object} options | ||
*/ | ||
util.analyzeUri = function(uriEntity, options){ | ||
options.path = uriEntity.path() + uriEntity.search(); | ||
options.host = uriEntity.hostname(); | ||
options.port = uriEntity.port(); | ||
// http && https | ||
if (uriEntity.protocol() == 'https') { | ||
!options.port && (options.port = 443); | ||
// can not use protocol here, complicated with [http.request]'s options. | ||
options.__protocol = 'https'; | ||
return https; | ||
} else { | ||
!options.port && (options.port = 80); | ||
options.__protocol = 'http'; | ||
return http; | ||
} | ||
}; |
{ | ||
"name": "req-fast", | ||
"version": "0.2.7", | ||
"version": "0.2.8", | ||
"description": "This module is designed to be the fast, lightweight way to fetch the web content(HTML stream).", | ||
@@ -5,0 +5,0 @@ "main": "lib/req.js", |
@@ -49,4 +49,13 @@ var req = require('../'), | ||
}); | ||
}) | ||
}); | ||
it('automatic change request client from http to https', function(done){ | ||
req({ | ||
url: 'http://dentistvschef.wordpress.com/2013/01/16/japanese-spring-onionscallionleek-pancake-ala-dentist-chef/' | ||
}, function(err, resp){ | ||
should.not.exist(err); | ||
should.equal(resp.statusCode, 200); | ||
done(); | ||
}); | ||
}); | ||
}) | ||
}); |
54547
1112