J'utilise le module fakeweb qui remplace http.request
de nœud avec la fonction suivante:Écrasement http.request avec 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);
}
};
Mon problème est que je reçois le bug: TypeError: Object #<Object> has no method 'on'
du code suivant dans un autre fichier:
var req = proto.request(options, function (res) { ... });
req.on('error', function (err) {
err.success = false;
settings.complete(err);
});
Je pense que mon problème se produit parce qu'il est plus un EventEmitter
, si je peux me tromper. Comment puis-je écraser avec succès http.request
sans problème? Contexte: J'utilise la version du nœud 0.8.2. La demande NPM est une version 2.12.0
mise à jour (11 février 2013): Je veux donner un peu plus d'informations sur l'endroit où le http.request est appelé pour que je puisse être plus précis sur ce qui est nécessaire et ce qui cause les bugs. Voici où il est appelé:
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();
la valeur de retour dans le 'si (règle) {'block n'est pas un EventEmitter – Chad
Oui, comment pourrais-je renvoyer un EventEmitter ici correctement? – babonk
Dépend de ce que vous voulez avoir émis. Vous êtes censé appeler 'req.end()' et vous obtiendrez un événement 'data' puis un événement' end'. C'est ainsi que fonctionne la bibliothèque. Comme aucun appel n'est jamais fait, vous n'obtiendrez jamais d'erreur. Vous devez vraiment expliquer votre objectif final ici. – Chad