2012-01-24 20 views
0

私はブラウザから他のPCにHTTPリクエストをリダイレクトする解決策を探しています。 一言で言えば、HttpRequestとしてクライアントに着信HttpListenerRequestを送信する、より正確な方法はありますか?HttpRequestsをリダイレクトする最も正確な方法

背景:ブラウザは、ダウンロードプログラムによって回答されるべき127.0.0.1:9666(yes、click'n'load)にHTTPリクエストを送信します。 私の場合、ブラウザを実行しているマシンでダウンロードプログラムが実行されていません。 これらのようなポートフォワーディングツールは私のためには機能しません:http://www.quantumg.net/portforward.php だから私はC#で特定のclick'n'loadリダイレクタを書くことにしました。 私の問題は、ブラウザのリクエストをリダイレクトすることです。 ATM、私は127.0.0.1:9666に耳を傾け、いくつかの情報をクライアントに送り、クライアントはこれをダウンローダプログラムにリダイレクトします。 (長期的には、これはブラウザにリダイレクトされます)。 しかし、事前定義されたケースを使用してコア情報だけをリダイレクトすることは、私にとってはあまり適切ではないようです。要求全体をリダイレクトすることが可能でなければなりません。ですから、私はさまざまなケースで異なる必要はありません。これはより正確でなければなりません。 すべてのヘッダーとプロパティのコピーを除いて、この要求をリダイレクトする方法はありますか?

サーバーは、HttpListenerを使用してブラウザの要求を待ち受けます。 次に、サーバーはHttpReqestをクライアントに送信します。 クライアントは、HttpListenerを使用してサーバーの要求を待ち受けます。 クライアントは、DownloaderにHttpRequestを送信し、 はGetResponseを使用し、これをブラウザに応答するサーバーへの応答として送信します。 MSDNでいくつかの関数を検索しましたが、「要求全体をコピーする」という良い方法が見つかりませんでした。だからここ

は私の問題のコードです:

Thread.Sleep(1500); 
//Read client's/JDownloader's stream, send to browser/redirector 
do 
{ 
    Read = Outstream.Read(Buffer, 0, Buffer.Length); 
    Totalr += Read; 
    Instream.Write(Buffer, 0, Read); 
    Sent += Read; 
    // Bufferstr += ASCIIEncoding.ASCII.GetString(Buffer, 0, Read); debugging 
} while (Read != 0); 

のThread.sleepがなければ、最初の読み取りは、(バッファ長が1024bytesで、公正かつ正確にHTTPヘッダ)171のバイトが読み込まれた返されます。 2番目の反復:Outstream.Readを実行すると何も起こりません。どんなに長く待っても。読者がトラフィックを受け取るのを待っていますが、受信するトラフィックはありません(変な...)スレッドが500-1500msの間スリープすると、最初の読み取りは351バイトが読み取られたことを返します(完全なHTTP要求)。もう一度、2番目の反復、何も。 これは、ブラウザまたはJDownloaderのNetworkStreamから読み取るときに発生します。これらのメソッドは、0を返すことはありません。これを行うには、Buffer.Lengthバイトが受信されたときに失敗するため、while-argumentをRead == Buffer.Length、dirtyに置き換えてください。 DataAvailableプロパティも常に正しいとは思われません。プログラムがストリームから何かを読み込みませんでしたが、受信するバイトがあったときにfalseに設定されることもあります。 Any適切な受信ループのための他のアイデア?


誰もいませんか?私の問題の短い要約:ブラウザーのリクエストストリームもJDownloadersレスポンスストリームも0を返しません。別の読み取りを試みると、プログラムは受信するより多くのバイトを待ちます。 したがって、ストリーム全体を読み込むためのフェイルセーフメソッドがわかりません。 読み込みバイト数がバッファの長さを下回るまで繰り返すだけで、streamlength%bufferlength == 0の場合、前述の無限待機待ちになります。

また、JDownloaderは応答を生成するためにより多くの時間が必要と思われます。私のプログラムがストリームを読み込もうとするよりもストリームに書き込んでください。だから私はストリームの一部だけを受け取るでしょう。もう一度読み込みを試みると、無限にバイトを待つことになります。 スタティックな遅延なしに(スレッドスリープ経由で)ストリーム全体を受信する別の方法はありますか?

+0

これで「手動」の方法で完了しました - それほど正確ではありませんが、うまくいきます:ヘッダー以外のものが送られてくると、ストリーム全体は読み込まれません。また、POSTデータがある場合は、コンテンツ長ヘッダーもあります。だから、ちょうどtcpバッファが空になるまでストリームから読み込み、コンテンツの長さが指定されているかどうかを確認します。 yesの場合、content-lengthがフィルタされ、content-length + header-lengthが受信バイトの合計量と等しいかそれより少ないまでreadが繰り返されます。 voilà。 – NoMad

答えて

1

TcpListenerを開いて生のバイトを転送できますか?そうすれば、HTTPに心配する必要は全くありません。

+0

ありがとう、ソケット(または関連する何か)を使用して私の心に来ていない、私は一度ソケットでプログラミング2日を無駄に、HttpRequestベースのコードは、この方法をより良くし、4時間かかったコーディング。 (それは私がC#でプログラミングを始めたときだった)。 TCP経由でバイトをリダイレクトするだけで完璧に動作します。唯一の問題は、リクエストに答えるダウンローダプログラムでした...それは遅すぎます。ストリームから読み込んだとき(リクエストに対する答え)、ヘッダーだけがあり、コンテンツが欠落しています。 Thread.Sleep(1000)より良い方法がありますか?必要に応じて、後でソースコードを投稿することができます – NoMad

+0

睡眠は必要ありません。 0を返すまでreadを呼び出すだけです。そして、ソケットは閉じられます。読み取りは、バイトが使用可能になるか、ソケットが閉じられるまでブロックされます。 – usr

1

あなたが求めているのは、基本的にプロキシの実装です。HTTPなどの両方向を理解し、処理する必要があるため、うまく動作するプロキシを構築するのは簡単な作業ではありません。

私はそのために、既存のライブラリまたはいくつかの設定可能なプロキシを使用するかをお勧めします:

関連する問題