Invocación de un método asíncrono dentro de un middleware en el nodo-http-proxy

Estoy intentando crear un proxy con node-http-proxy en Node.js que verifica si una solicitud está autorizada en un mongodb.

Básicamente, creé un módulo de middleware para el nodo-http-proxy que uso así:

httpProxy.createServer( require('./example-middleware')(), 9005, 'localhost' ).listen(8005) 

Lo que hace el módulo de middleware es usar mongojs para conectarse a mongodb y ejecutar una consulta para ver si el usuario está autorizado para acceder al recurso:

 module.exports = function(){ // Do something when first loaded! console.log("Middleware loaded!"); return function (req, res, next) { var record = extractCredentials(req); var query = -- Db query -- //Debug: log("Query result", query); db.authList.find(query).sort({ "url.len": -1 }, function(err, docs){ console.log(docs); // Return the creator for the longest matching path: if(docs.length > 0) { console.log("User confirmed!"); next(); } else { console.log("User not confirmed!"); res.writeHead(403, { 'Content-Type': 'text/plain' }); res.write('You are not allowed to access this resource...'); res.end(); } }); } } 

Ahora el problema es que tan pronto como agrego la llamada asíncrona a mongodb usando mongojs, el proxy cuelga y nunca devuelve la respuesta.

Para aclarar: en un “Usuario no confirmado” todo funciona bien y se devuelve el 403. En un “usuario confirmado”, sin embargo, veo el registro pero el navegador se cuelga para siempre y la solicitud no se envía por proxy.

Ahora, si elimino la parte “confirmada por el usuario” y siguiente () fuera de una callback, funciona:

 module.exports = function(){ // Do something when first loaded! console.log("Middleware loaded!"); return function (req, res, next) { var record = extractCredentials(req); var query = --- query --- console.log("User confirmed!"); next(); } 

pero no puedo hacer eso, ya que la consulta de mongojs está destinada (con razón, supongo) a ejecutarse de forma asíncrona, la callback se activa solo cuando la db responde …

También probé la versión sin usar un middleware:

 http.createServer(function (req, res) { // run the async query here! proxy.proxyRequest(req, res, { host: 'localhost', port: 9000 }); }).listen(8001); 

Pero eso tampoco ayudó …

¿Cualquier pista? Tenga en cuenta que soy nuevo en node.js, así que sospecho que hay un malentendido por mi parte …

Encontré la respuesta, en realidad el problema es que la solicitud debe ser almacenada en búfer:

 httpProxy.createServer(function (req, res, proxy) { // ignore favicon if (req.url === '/favicon.ico') { res.writeHead(200, { 'Content-Type': 'image/x-icon' } ); res.end(); console.log('favicon requested'); return; } var credentials = extractCredentials(req); console.log(credentials); var buffer = httpProxy.buffer(req); checkRequest(credentials, function(user){ if(user == ...) { console.log("Access granted!"); proxy.proxyRequest(req, res, { host: 'localhost', port: 9005, buffer: buffer }); } else { console.log("Access denied!"); res.writeHead(403, { "Content-Type": "text/plain" }); res.write("You are not allowed to access this resource..."); res.end(); } }); }).listen(8005); 

Dos problemas:

  1. No estás llamando next(); en el caso else de su callback de sort .
  2. El segundo parámetro para su callback de sort es un Cursor , no una matriz de documentos. Como tal, docs.length > 0 nunca es verdadero y el código siempre sigue la ruta else .
    Intereting Posts