Invoking an asynchronous method inside middleware in node-http-proxy

I am trying to create a proxy with node-http-proxy in Node.js, which checks if the request is allowed in mongodb.

Basically, I created a middleware module for node-http-proxy, which I use as follows:

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

What the middleware module does is use mongojs to connect to mongodb and run a request to find out if the user is allowed access to the resource:

 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(); } }); } } 

Now the problem is that as soon as I add an asynchronous call to mongodb using mongojs, the proxy freezes and never sends a response.

To clarify: to "User is not confirmed" everything works fine and returns 403. When "user is confirmed", however, I see a log, but the browser then freezes forever and the request is not proxied.

Now, if I delete the "user-confirmed" and the following () part outside the callback, it works:

 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(); } 

but I can’t do this, since the mongojs request is implied (rightfully, I think) to be executed asynchronously, the callback is only triggered when the db response ...

I also tried the middleware version:

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

But that didn't help either ...

Any clue? Note that I am new to Node.js, so I suspect that I have misunderstanding ...

+7
source share
2 answers

Found the answer, in fact catch is that the request should be buffered:

 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); 
+6
source

Two problems:

  • You do not call next(); otherwise the case of your sort callback.
  • The second parameter to your sort callback is Cursor , not an array of documents. So docs.length > 0 never true, and the code always follows the else path.
+2
source

All Articles