2017-07-26 7 views
5

私は、tls以上のhttps要求をトンネリングする機能を必要とするすべてのプロキシサーバーをまとめてNodeに配置しました。次の2つのパッケージを使用すると、セットアップが非常に簡単でした:proxyhttps-proxy-agent。私の問題は、私はミドルウェア層としてconnectを使用してHARファイルをキャプチャしようとしていると私は、次のエラーを取得していますということです。Node.jsカスタムHttp(s)エージェントとConnect.jsミドルウェアを持つプロキシ

_http_outgoing.js:357 
throw new Error('Can\'t set headers after they are sent.'); 
^ 
Error: Can't set headers after they are sent. 
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:357:11) 
at ServerResponse.writeHead (_http_server.js:180:21) 
at ClientRequest.<anonymous> (/.../node_modules/proxy/proxy.js:233:11) 
at emitOne (events.js:96:13) 
at ClientRequest.emit (events.js:188:7) 
at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:473:21) 
at HTTPParser.parserOnHeadersComplete (_http_common.js:99:23) 
at Socket.socketOnData (_http_client.js:362:20) 
at emitOne (events.js:96:13) 
at Socket.emit (events.js:188:7) 

ザ・は次のように単純であり、唯一私が「時に起こるようですmをconnectを使用し、私のローカルブラウザ(このプロキシは実際にBrowserStackLocalと一緒に使用されています)でプロキシします。私がローカルマシンブラウザ以外のものからプロキシを通過するとき、それはミドルウェアが存在することさえ知らないのと同様です。

基本的に、このシナリオでは接続を確立する必要があります。何かを一時停止して再開する必要があるかどうかわかりません。何か考えていただければ幸いです。基本コードは次のとおりです。

const path = require('path'); 
const http = require('http'); 
const proxy = require('proxy'); 
const Agent = require('https-proxy-agent'); 
const connect = require('connect'); 
const har = require('./har'); 

const middleware = connect(); 

middleware.use(har({ 
    harOutputDir: path.resolve(process.cwd(), 'har/') 
})); 

const server = proxy(http.createServer(middleware)); 
server.agent = new Agent('http://localhost:8081'); 

server.listen(8081) 

ありがとうございます!

編集:ちょっとした注意:harミドルウェアはヘッダーをまったく変更していません。

+0

は、レスポンス・オブジェクトにデータを送信する./harミドルウェアですが?そうであれば、ヘッダーが設定され、2番目のsetHeaderエラーが発生します。 – Myonara

+0

@Myonaraいいえ、応答からデータが読み込まれ、 "./har"ミドルウェアがなくても問題が存在します。場所。 – mike

+0

クライアント側では、2番目のヘッダーの代わりに送信されたものを識別できますか? – Myonara

答えて

1

proxyはしばらくの間維持されていません。ビルドはパスしない、最後にコミットはテストに合格しない。スタックトレースのソースは、here in Line 233 - バグのライブラリコードから来ています。

同様のプロキシの作成は簡単です。次のコードは、作成方法を示しています。

const http = require('http'); 
const urlP = require('url'); 

const proxiedServer = 'http://localhost:8888'; 

// Proxy server 
http.createServer((req, res) => { 
    console.log(`Proxy: Got ${req.url}`); 

    const _r = http.request(
    Object.assign(
     {}, 
     urlP.parse(proxiedServer), 
     { 
     method: req.method, 
     path: req.url 
     } 
    ), 
    _res => { 
     res.writeHead(_res.statusCode, _res.headers); 
     _res.pipe(res); 
    } 
); 

    req.pipe(_r); 

}).listen(3124,() => { 
    console.log("Listening on 3124"); 
}); 


// Regular server. Could be Express 
http.createServer((req, res) => { 
    console.log('Proxied server: ', req.url); 
    let b = ''; 
    req.on('data', c => { 
    b += c; 
    }); 
    req.on('end',() => { 
    console.log('Proxied server: ', b); 
    }); 
    res.writeHead(200); 
    res.end('ok'); 
}).listen(8888,() => { 
    console.log('proxied server listening on 8888'); 
}); 

次のようになり、独自のカスタムプロキシを使用してコード:

const urlP = require('url'); 
const path = require('path'); 
const http = require('http'); 
const connect = require('connect'); 
const har = require('./har'); 

const proxiedServer = 'http://localhost:8888'; 

// Proxy server 
http.createServer((req, res) => { 
    console.log(`Proxy: Got ${req.url}`); 

    const _r = http.request(
    Object.assign(
     {}, 
     urlP.parse(proxiedServer), 
     { 
     method: req.method, 
     path: req.url 
     } 
    ), 
    _res => { 
     res.writeHead(_res.statusCode, _res.headers); 
     _res.pipe(res); 
    } 
); 

    req.pipe(_r); 

}).listen(3124,() => { 
    console.log("Listening on 3124"); 
}); 

const middleware = connect(); 
middleware.use(har({ 
    harOutputDir: path.resolve(process.cwd(), 'har/') 
})); 

middleware.use((req, res) => { 
    console.log('Proxied server: ', req.url); 
    let b = ''; 
    req.on('data', c => { 
    b += c; 
    }); 
    req.on('end',() => { 
    console.log('Proxied server: ', b); 
    }); 
    res.writeHead(200); 
    res.end('ok'); 
}); 


http.createServer(middleware).listen(8888,() => { 
    console.log('proxied server listening on 8888'); 
}); 
+0

Ok-助けを感謝...私は実際に自分の書き込みを始めたが、httpを介してhttpsをトンネリングするあまりにも多くの問題に遭遇した。私は、代理人がプロキシを通過するもののために証明書を作成しようとしていることに対する解決策であることを理解しました。ご協力いただきありがとうございます! – mike

+0

回答のスニペットは役に立ちましたか? –

+0

はい、私は実際にそれを調べて、それを少しきれいにしてPRを提出するつもりでしたが、ちょうどあなたが示唆したように自分自身を書くことになった...私はエージェントとの必要性のためにもう少し関与しています必要に応じてTLSにスワッピングしてください。私は本質的に置き換えるJavaScriptソリューションを書いています。 BrowserMobb Procy。助けてくれてありがとう! – mike

関連する問題