3

透過的なHTTP プロキシを 1 つ作成しようとしています。その目的は、ブラウザーと Web サーバーの間に留まり、見えないようにすることです。これが私が使用しているコードです。残念ながら、うまく機能していません。Web ページ ( で参照$base_uri) を開くと、ブラウザのみを使用して開いたか、ブラウザとプロキシを使用して開いたかによって結果が異なります。「 」を含むあらゆる種類の応答を返す Web サイトで試していますtransfer-encoding: chunked(問題があるのではないでしょうか?!)。Cookie にも問題がある可能性があると思いますが、解決方法がわかりません (もしあれば...)。

#!/usr/bin/perl

use strict;

use HTTP::Daemon;
use LWP::UserAgent;
use HTTP::Cookies;

my $cookie_jar = HTTP::Cookies->new();

my $ua = LWP::UserAgent->new( max_redirect => 0, env_proxy => 0,keep_alive => 1, timeout => 30, agent => "Mozilla/4.76 [en] (Win98; U)");
my $d = HTTP::Daemon->new( 
    LocalHost => "localhost",  # remove this to listen from other machines 
                   # (i.e. open-relay... be careful of spammers!)
    LocalPort => 33331
) || die;
print "[Proxy URL:", $d->url, "]\n";

fork(); fork(); fork();  # 2^3 = 8 processes

$ua->cookie_jar($cookie_jar);

my $base_uri = 'http://example.com/';

while (my $c = $d->accept) {
        while (my $request = $c->get_request) {
            my $uri = $base_uri . $request->uri->as_string();
            my $method = $request->method;
            my $req = HTTP::Request->new($method, $uri);

            $request->uri($uri);

            print "[[ $method >> $uri ]]\n";
            my $response = $ua->simple_request($request);
            $c->send_response( $response );
        }
    $c->close;
    undef($c);
}

前もって感謝します!

4

1 に答える 1

0

あなたが本当に欲しいものは明らかではありません。あなたはそれをもっとうまく説明するべきです。そのプロキシが必要なものとその理由、および必要な機能を説明すると、どんなヘルプもはるかに優れたものになります. それでもやってみます。

現在行っていることは、着信接続を取得し、URI と呼び出しメソッドを抽出してソースに渡すことです。HTTP ははるかに複雑です。トランスポートされたデータ (POST リクエストなど) やすべてのヘッダー行 (Cookie、ログイン データ、ブラウザー ID、言語仕様など) など、通常は重要な情報を運ぶすべてのものを取り除きます。 . また、タイミング動作を大幅に変更します。次に、それをプロキシ ターゲットに送信しました。

ここで、サーバーの回答を取得し、関連するすべてのものを再び取り除きます。また、回答は終了後に返信するだけです。ストリーミング データの場合、これは機能しません (チャンク転送モードについては既に説明しました)。また、この方法では、大きなファイル (DVD イメージ - 4GB など) に多くのメモリが必要です。

アプリケーションに関する詳細がなければ、実際の提案はできませんが、いくつかのアイデアがあります。

a) コメントで述べたように、利用可能な Perl モジュールがあります。それらをテストして、ニーズに合っているかどうかを確認できます。

b) レベルを下げることができます。IO::Socket::INETまたはを使用INET6して、ソケット レベルで直接作業します。入ってくる各パケットを出力に直接送信します。これはほぼ 100% 透過的です (IP アドレスとおそらく TCP パケット サイズを除く)。データを変更または検査したい場合は、HTTP を自分で直接処理する必要がありますが、これは最近では非常に複雑になる可能性があります (特に転送エンコーディングが原因で)。

c) 自分でコーディングせずに、既存のプロキシ (Apache Web サーバーや特定のプロキシ プログラムなど) を使用することもできます。

于 2013-01-04T21:25:13.020 に答える