Я использую fakeweb модуль, который переписывает узла http.request
с помощью следующей функции:Перезапись http.request с EventEmitter
var old_request = http.request;
http.request = function(options, callback){
var rule = match_rule(options);
if(rule){
var res = new events.EventEmitter();
res.headers = rule.headers || {'Content-Type': 'text/html'};
return {end: function(){
callback(res);
res.emit('data', rule.body || '');
res.emit('end');
}
};
} else {
return old_request.call(http, options, callback);
}
};
Моя проблема заключается в том, что я получаю ошибку: TypeError: Object #<Object> has no method 'on'
из следующего кода в другом файле:
var req = proto.request(options, function (res) { ... });
req.on('error', function (err) {
err.success = false;
settings.complete(err);
});
Я думаю, что моя проблема не возникает, потому что это уже не EventEmitter
, хотя я могу ошибаться. Как я могу успешно перезаписать http.request
, не получив эту проблему?
Фон: Я использую версию узла 0.8.2. Запрос НПМ версия 2.12.0
Update (11 февраля 2013): Я хочу, чтобы предоставить некоторую информацию о том, где http.request вызывается, так что я могу быть более конкретным о том, что нужно и что вызывает ошибки. Вот где она называется:
var proto = (options.protocol === 'https:') ? https : http;
var req = proto.request(options, function (res) {
var output = new StringStream();
switch (res.headers['content-encoding']) {
case 'gzip':
res.pipe(zlib.createGunzip()).pipe(output);
break;
case 'deflate':
res.pipe(zlib.createInflate()).pipe(output);
break;
default:
// Treat as uncompressed string
res.pipe(output);
break;
}
output.on('end', function() {
if (settings.cookieJar && res.headers['set-cookie']) {
var cookies = res.headers['set-cookie'];
for (var i = 0; i < cookies.length; i++) {
settings.cookieJar.set(cookies[i]);
}
}
if (res.statusCode >= 300 && res.statusCode < 400) {
if (settings.maxRedirects > settings.nRedirects++) {
// Follow redirect
var baseUrl = options.protocol + '//' + ((proxy) ? options.headers['host'] : options.host),
location = url.resolve(baseUrl, res.headers['location']);
request(location, settings);
} else {
var err = new Error('Max redirects reached.');
err.success = false;
settings.complete(err);
}
} else if (res.statusCode >= 400) {
var err = new Error(output.caught);
err.success = false;
err.code = res.statusCode;
settings.complete(err);
} else {
settings.complete(null, output.caught, res);
}
});
});
req.on('error', function (err) {
err.success = false;
settings.complete(err);
});
if (data) { req.write(data); }
req.end();
возвращаемое значение в 'если (правило) {'block is not EventEmitter – Chad
Да, как я мог правильно вернуть EventEmitter? – babonk
Зависит от того, что вы хотите испустить. Вы должны называть 'req.end()', и вы получите событие 'data', а затем событие' end'. Так работает библиотека. Поскольку вызов никогда не производится, вы никогда не получите сообщение об ошибке. Вы действительно должны объяснить свою конечную цель здесь. – Chad