2012-07-26 33 views
7

Próbuję utworzyć serwer proxy z węzłem-http-proxy w Node.js, który sprawdza, czy żądanie jest autoryzowane w mongodb.Wywoływanie metody asynchronicznej wewnątrz oprogramowania pośredniego w węźle-http-proxy

Zasadniczo, stworzyłem moduł middleware dla węzła-http-proxy, że używam tak:

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

Co moduł middleware robi korzysta mongojs połączyć się MongoDB i uruchomić kwerendę, aby sprawdzić, czy użytkownik jest uprawniony do dostępu do zasobów:

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

}); 

} 
} 

teraz problemem jest to, że jak tylko dodam asynchroniczne wywołanie MongoDB użyciu mongojs zawiesza proxy i nie wysyła odpowiedź z powrotem.

Aby wyjaśnić: na "Użytkownik nie potwierdzony" wszystko działa poprawnie, a 403 jest zwracana. Na "potwierdzonym przez użytkownika" widzę jednak log, ale przeglądarka zawiesza się na zawsze, a prośba nie jest proxowana.

Teraz, jeśli usunąć „użytkownik potwierdził” i następne() część poza wywołania zwrotnego to działa:

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

ale nie mogę tego zrobić, ponieważ kwerenda mongojs rozumie (I słusznie chyba) być wykonywane asynchronicznie, callback jest uruchamiany tylko wtedy, gdy db odpowiedział ...

próbowałem też wersję bez użycia middleware:

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

Ale to nie pomogło albo ...

Jakaś wskazówka? Zauważ, że jestem nowy node.js więc podejrzewam nieporozumienie na mojej stronie ...

+0

co middleware używasz? połączyć? –

Odpowiedz

6

znaleźć odpowiedź, faktycznie haczyk jest, że wniosek musi być buforowane:

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); 
+0

Ale w jaki sposób w środku oprogramowania pośredniego, jako obiekt proxy, nadal nie jest on dostępny (ponieważ middleware są ładowane zanim zadeklarujesz funkcję zawierającą argument "proxy")? – Mark

2

dwa problemy:

  1. Nie jesteś wzywającą next(); w else przypadku swojej sort zwrotnego.
  2. Drugi parametr wywołania zwrotnego sort to Cursor, a nie tablica dokumentów. Jako takie, docs.length > 0 nigdy nie jest prawdziwe, a kod zawsze podąża za ścieżką else.
+0

Cześć! Dzięki. Myślę, że moje pytanie nie było wystarczająco jasne, więc zredagowałem to (moje złe!). Zrobiłem wywołanie zapisu odpowiedzi w klauzuli else (zobacz nowe zmiany), a drugim parametrem sortowania jest wywołanie zwrotne, a nie kursor, ponieważ powiedziałem, że używam mongojs, a nie ngo macierzystego sterownika javascript (zapytanie działa poprawnie). – domguinard

+0

Ah, bez problemu; moje złe za brakujące części proxy tego. Czy trzeci parametr dla twojej funkcji pośredniej węzła-http-proxy nie jest obiektem 'proxy', a nie' next'? https://github.com/nodejitsu/node-http-proxy/#setup-a-stand-alone-proxy-server-with-custom-server-logic – JohnnyHK

+0

Najwyraźniej jest to funkcja next(). Próbowałem z proxy, ale ma ten sam wynik: zarówno proxy.proxyRequest (req, res); i dalej(); pracować poza callbackiem, ale nie w środku. Serwer proxy wciąż się zawiesza ... – domguinard

Powiązane problemy