Я сделал простой HTTP прокси-сервер, это отлично работает, но не быстро, потому что в функции handle_request, я используюPerl: асинхронный HTTP прокси через Mojolicious
my $tx = $ua->start(Mojo::Transaction::HTTP->new(req=>$request));
сделать запрос, он блокирует.
Я пытаюсь использовать функцию обратного вызова, как:
$ua->start(Mojo::Transaction::HTTP->new(req=>$request))=>sub{ ... }
сделать это без блокировки, а затем получил ошибку:
'error' => { 'message' => 'Premature connection close'}
Я предполагаю, что это потому, что функция handle_request
возвращение немедленно, его не дождался завершения обратного вызова. Если я использую семафор, чтобы ждать обратного вызова, это значит, что он снова блокирует.
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use Mojo::IOLoop::Server;
use Mojo::UserAgent;
use Mojo::Message::Response;
use Mojo::Message::Request;
use Mojo::Transaction::HTTP;
use Data::Dumper;
binmode STDOUT, ":encoding(UTF-8)";
my %buffer;
Mojo::IOLoop->server({port => 3128} => sub {
my ($loop, $stream, $client) = @_;
$stream->on(
read => sub {
my ($stream, $chunk) = @_;
my $buffer = $buffer{$client}{read_buffer} .= $chunk;
if ($buffer =~ /^GET\s+|POST\s+|HEAD\s+(.*)\r\n\r\n$/i) {
$buffer{$client}{read_buffer} = '';
&handle_request($client,$stream,$buffer);
}
elsif ($buffer =~ /^CONNECT\s+(.*)\r\n\r\n$/i) {
$buffer{$client}{read_buffer} = '';
&handle_connect($stream,$buffer);
}
elsif($buffer{$client}{connection})
{
$buffer{$client}{read_buffer} = '';
Mojo::IOLoop->stream($buffer{$client}{connection})->write($chunk);
}
if(length($buffer)>= 20 *1024 * 1024) {
delete $buffer{$client};
Mojo::IOLoop->remove($client);
return;
}
});
});
sub handle_request{
my($client,$stream,$chunk) = @_;
my $request = Mojo::Message::Request->new;
$request = $request->parse($chunk);
my $ua = Mojo::UserAgent->new;
my $tx = $ua->start(Mojo::Transaction::HTTP->new(req=>$request));
$stream->write($tx->res->to_string);
}
sub handle_connect{
my ($stream, $chunk) = @_;
my $request = Mojo::Message::Request->new;
my $ua = Mojo::UserAgent->new;
$request = $request->parse($chunk);
print Dumper($request);
}
Mojo::IOLoop->start;
Надеемся получить некоторые предложения.
Большое спасибо. Я храню $ ua в хеш-таблице, теперь все в порядке. для первой проблемы я не знаю, что я должен делать. 'my $ ua = Mojo :: UserAgent-> new; $ buffer {$ client} {ua} = $ ua; my $ tx = $ buffer {$ client} {ua} -> start (Mojo :: Transaction :: HTTP-> new (req => $ request) => sub {my ($ ua, $ tx) = @_ ; $ stream-> write ($ tx-> res-> to_string);}}); ' –
Я пишу пример. – Logioniz