web-dev-qa-db-ja.com

C#で簡単なプロキシを作成する方法は?

数週間前にPrivoxyをダウンロードしましたが、楽しみのために、Privoxyの簡単なバージョンをどのように実行できるか知りたいと思いました。

プロキシにリクエストを送信するようにブラウザー(クライアント)を構成する必要があることを理解しています。プロキシはWebにリクエストを送信します(httpプロキシであると言います)。プロキシは回答を受け取ります...しかし、プロキシはどのようにしてリクエストをブラウザ(クライアント)に送り返すことができますか?

WebでC#とhttpプロキシを検索しましたが、舞台裏で正しく機能する仕組みを理解できるものが見つかりませんでした。 (逆プロキシは必要ないと思いますが、確信はありません)。

この小さなプロジェクトを続けるための説明や情報がありますか?

更新

これは私が理解していることです(下の図を参照)。

ステップ1すべてのリクエストがプロキシがリッスンするポートで127.0.0.1に送信されるようにクライアント(ブラウザ)を構成します。この方法では、リクエストはインターネットに直接送信されず、プロキシによって処理されます。

Step2プロキシは、新しい接続を確認し、HTTPヘッダーを読み取り、実行する必要がある要求を確認します。彼はリクエストを実行します。

Step3プロキシはリクエストから回答を受け取ります。今、彼はウェブからクライアントに答えを送らなければならないが、どうやって?

alt text

便利なリンク

Mentalis Proxy :プロキシであるこのプロジェクトを見つけました(ただし、もっと必要です)。私はソースをチェックするかもしれませんが、私は本当にもっと概念を理解するために基本的な何かが欲しかったです。

ASP Proxy :ここでもいくつかの情報を取得できるかもしれません。

リクエストリフレクター :これは簡単な例です。

Git Hub Repository with a Simple Http Proxy です。

137

着信リクエストをリッスンする HttpListener クラスと、リクエストをリレーする HttpWebRequest クラスでビルドできます。

33
Mark Cidade

私はHttpListenerなどを使用しません。そうすれば、非常に多くの問題に遭遇します。

最も重要なことは、サポートすることは大きな苦痛になることです。

  • プロキシキープアライブ
  • SSLは機能しません(正しい方法で、ポップアップが表示されます)
  • .NETライブラリは厳密にRFCに準拠しているため、一部のリクエストは失敗します(IE、FF、および世界中のその他のブラウザーでも機能します)。

あなたがする必要があるのは:

  • TCPポートをリッスンします
  • ブラウザのリクエストを解析する
  • TCPレベルでそのホストに接続するホストを抽出します
  • カスタムヘッダーなどを追加する場合を除き、すべてを前後に転送します。

さまざまな要件を持つ2つの異なるHTTPプロキシを.NETで記述しましたが、これが最善の方法であることがわかります。

Mentalisはこれを行っていますが、コードは「デリゲートスパゲッティ」であり、GoToよりも悪いです:)

86
dr. evil

最近、C#.netで TcpListener および TcpClient を使用して軽量プロキシを作成しました。

https://github.com/titanium007/Titanium-Web-Proxy

セキュアHTTPを正しい方法でサポートします。クライアントマシンは、プロキシが使用するルート証明書を信頼する必要があります。 WebSocketリレーもサポートします。パイプラインを除くHTTP 1.1のすべての機能がサポートされています。とにかく、パイプラインはほとんどの最新のブラウザーでは使用されていません。 Windows認証(プレーン、ダイジェスト)もサポートしています。

プロジェクトを参照してアプリケーションを接続し、すべてのトラフィックを表示および変更できます。 (リクエストとレスポンス)。

パフォーマンスに関しては、マシンでテストしており、目立った遅延なく動作しています。

22
justcoding121

プロキシは次のように機能します。

手順1、proxyHost:proxyPortを使用するようにクライアントを構成します。

プロキシは、proxyHost:proxyPortでリッスンしているTCPサーバーです。ブラウザはプロキシとの接続を開き、HTTPリクエストを送信します。プロキシはこのリクエストを解析し、「Host」ヘッダーの検出を試みます。このヘッダーは、接続を開く場所をプロキシに指示します。

ステップ2:プロキシは、「Host」ヘッダーで指定されたアドレスへの接続を開きます。次に、HTTP要求をそのリモートサーバーに送信します。応答を読み取ります。

ステップ3:応答がリモートHTTPサーバーから読み取られた後、プロキシはブラウザーで以前に開いたTCP接続を介して応答を送信します。

概略的には次のようになります。

Browser                            Proxy                     HTTP server
  Open TCP connection  
  Send HTTP request  ----------->                       
                                 Read HTTP header
                                 detect Host header
                                 Send request to HTTP ----------->
                                 Server
                                                      <-----------
                                 Read response and send
                   <-----------  it back to the browser
Render content
19
Vadym Stetsiak

トラフィックを傍受するだけの場合、フィドラーコアを使用してプロキシを作成できます...

http://fiddler.wikidot.com/fiddlercore

最初にUIでfiddlerを実行して、その機能を確認します。これは、http/httpsトラフィックをデバッグできるプロキシです。 C#で記述されており、独自のアプリケーションに組み込むことができるコアを備えています。

FiddlerCoreは商用アプリケーションには無料ではないことに注意してください。

14
Dean North

OWINとWebAPIにより、物事は本当に簡単になりました。 C#プロキシサーバーの検索で、この投稿に出会いました http://blog.kloud.com.au/2013/11/24/do-it-yourself-web-api-proxy/ 。これが私が取っている道です。

6

HTTPListenerを使用すると、多くの問題が発生し、リクエストを解析する必要があり、ヘッダーに関与し、...

  1. Tcpリスナーを使用してブラウザー要求をリッスンします
  2. リクエストの最初の行のみを解析し、接続するホストドメインとポートを取得します
  3. ブラウザーリクエストの最初の行で見つかったホストに正確な生のリクエストを送信します
  4. ターゲットサイトからデータを受信します(このセクションに問題があります)
  5. ホストから受信した正確なデータをブラウザに送信します

ブラウザリクエストの内容を把握して解析する必要さえないことがわかります。最初の行からターゲットサイトのアドレスを取得するのは、通常、このGET http://google.com HTTP1だけです。 1またはCONNECT facebook.com:443(これはSSLリクエスト用です)

5
Alireza Rinan

Socks4は、実装が非常に簡単なプロトコルです。初期接続をリッスンし、クライアントから要求されたホスト/ポートに接続し、成功コードをクライアントに送信してから、ソケットを介して送信および受信ストリームを転送します。

HTTPを使用する場合は、いくつかのHTTPヘッダーを読み取り、場合によっては設定/削除する必要があるため、もう少し手間がかかります。

私の記憶が正しければ、SSLはHTTPプロキシとSocksプロキシで機能します。 HTTPプロキシの場合、CONNECT動詞を実装します。これは、上記のsocks4のように動作し、クライアントはプロキシ化されたtcpストリームでSSL接続を開きます。

4
C.M.

ブラウザはプロキシに接続されているため、プロキシがWebサーバーから取得するデータは、ブラウザがプロキシに対して開始したのと同じ接続を介して送信されます。

2