2012-11-20 19 views
12

एक साधारण http प्रॉक्सी सर्वर बनाकर node.js के बारे में अधिक जानने की कोशिश कर रहा है। उपयोग परिदृश्य सरल है: उपयोगकर्ता -> प्रॉक्सी -> सर्वर -> प्रॉक्सी -> उपयोगकर्ताhttp अनुरोध पर http सर्वर को पाइप करके सरल node.js प्रॉक्सी

निम्न कोड अंतिम चरण तक काम करता है। पाइप कनेक्टर के आउटपुट को उपयोगकर्ता को वापस नहीं ढूंढ सका।

#!/usr/bin/env node 

var 
    url = require('url'), 
    http = require('http'), 
    acceptor = http.createServer().listen(3128); 

acceptor.on('request', function(request, response) { 
    console.log('request ' + request.url); 
    request.pause(); 
    var options = url.parse(request.url); 
    options.headers = request.headers; 
    options.method = request.method; 
    options.agent = false; 

    var connector = http.request(options); 
    request.pipe(connector); 
    request.resume(); 
// connector.pipe(response); // doesn't work 
// connector.pipe(request); // doesn't work either 
}); 

का उपयोग tcpflow मैं, तो बाहर जाने वाले प्रॉक्सी अनुरोध ब्राउज़र से आने वाली अनुरोध देखते हैं, तो सर्वर प्रतिक्रिया वापस प्रॉक्सी के लिए। किसी भी तरह से मैं ब्राउज़र पर प्रतिक्रिया वापस पुनः प्रेषित करने का प्रबंधन नहीं कर सका।

इस तर्क को पाइप के साथ लागू करने का उचित तरीका क्या है?

उत्तर

19

ठीक है। समझ गया।

अद्यतन: एनबी! जैसा कि टिप्पणियों में बताया गया है, यह उदाहरण अब और काम नहीं करता है।

#!/usr/bin/env node 

var 
    url = require('url'), 
    http = require('http'), 
    acceptor = http.createServer().listen(3128); 

acceptor.on('request', function(request, response) { 
    console.log('request ' + request.url); 
    request.pause(); 
    var options = url.parse(request.url); 
    options.headers = request.headers; 
    options.method = request.method; 
    options.agent = false; 

    var connector = http.request(options, function(serverResponse) { 
      serverResponse.pause(); 
      response.writeHeader(serverResponse.statusCode, serverResponse.headers); 
      serverResponse.pipe(response); 
      serverResponse.resume(); 
    }); 
    request.pipe(connector); 
    request.resume(); 
}); 
+0

-1 क्योंकि: stream.js: 94 फेंक एर; // पाइप में अनचाहे स्ट्रीम त्रुटि। ^ त्रुटि: errnoException पर ECONNREFUSED कनेक्ट (net.js: 901: 11) Object.afterConnect [के रूप में oncomplete] (net.js: 892: 19) पर –

+3

@rob, संभवत: इस उदाहरण के साथ काम नहीं करता है नई स्ट्रीम 2 एपीआई। स्ट्रीम 2 को नोड 0.9 में बीटा के रूप में पेश किया गया था और 0.10 शाखा में स्थिर हो गया था। 0.10 मार्च 2013 को जारी किया गया था - इस चर्चा के महीनों बाद। इसलिए, यदि आप वास्तव में अधिक रचनात्मक बनना चाहते हैं, तो -1 को डालने के बजाय, नए एपीआई के लिए उदाहरण अनुकूलित करें। –

+0

@NikolaiGorchilov उपर्युक्त उदाहरण नोड 0.10.13 के साथ मेरे लिए काम किया। केवल मुझे बदलना था 'प्रतिक्रिया। लिखना' प्रतिक्रिया के बजाय 'प्रतिक्रिया.writeHeader' – Gireesh

19

आप न 'रोकें' करने के लिए है, सिर्फ 'पाइप': अधिकांश शायद Streams2 API परिवर्तन (नोड 0.9+)

पाइपिंग वापस ग्राहक के लिए की वजह से इस प्रकार के अंदर कनेक्टर के कॉलबैक होना होता है ठीक है

var connector = http.request(options, function(res) { 
    res.pipe(response, {end:true});//tell 'response' end=true 
}); 
request.pipe(connector, {end:true}); 

http अनुरोध तब तक समाप्त नहीं होगा जब तक आप इसे 'अंत' नहीं बताते;

+4

{अंत: सत्य} एक अच्छा सुझाव है। 10x। विराम के संबंध में, मुझे अभी भी लगता है कि इसका उपयोग करना बेहतर है। कल्पना करें कि उपयोगकर्ता HTTP पोस्ट के साथ एक बड़ी फ़ाइल अपलोड कर रहा है। आउटगोइंग कनेक्शन निर्माणाधीन होने पर उसकी फ़ाइल सर्वर की रैम में क्यों बफर हो जाएगी? और क्या होगा यदि एक कारण या किसी अन्य कारण से यह आउटगोइंग कनेक्शन संभव नहीं है? –

+1

FWIW, '{end: true} 'अब आधुनिक नोड के साथ आवश्यक नहीं है - डिफ़ॉल्ट' सत्य 'है, इसलिए यदि आप अक्षम कर रहे हैं तो आपको केवल विकल्पों को पारित करने की आवश्यकता है। – Jesse

1

मैंने इस पोस्ट के उदाहरण प्रॉक्सी http/s अनुरोधों के लिए उपयोग किए। समस्या से सामना करना पड़ा कि कुकीज़ कहीं खो गई थी।

तो इसे ठीक करने के लिए आपको प्रॉक्सी प्रतिक्रिया से शीर्षलेखों को संभालने की आवश्यकता है।

काम कर उदाहरण नीचे:

req = service.request(options, function(res) { 
    response.writeHead(res.statusCode, res.headers); 
    return res.pipe(response, {end: true}); 
}); 
request.pipe(req, {end: true});