Initial Commit
This commit is contained in:
355
database/perl/vendor/lib/Mojo/IOLoop/Client.pm
vendored
Normal file
355
database/perl/vendor/lib/Mojo/IOLoop/Client.pm
vendored
Normal file
@@ -0,0 +1,355 @@
|
||||
package Mojo::IOLoop::Client;
|
||||
use Mojo::Base 'Mojo::EventEmitter';
|
||||
|
||||
use Errno qw(EINPROGRESS);
|
||||
use IO::Socket::IP;
|
||||
use IO::Socket::UNIX;
|
||||
use Mojo::IOLoop;
|
||||
use Mojo::IOLoop::TLS;
|
||||
use Scalar::Util qw(weaken);
|
||||
use Socket qw(IPPROTO_TCP SOCK_STREAM TCP_NODELAY);
|
||||
|
||||
# Non-blocking name resolution requires Net::DNS::Native
|
||||
use constant NNR => $ENV{MOJO_NO_NNR} ? 0 : eval { require Net::DNS::Native; Net::DNS::Native->VERSION('0.15'); 1 };
|
||||
my $NDN;
|
||||
|
||||
# SOCKS support requires IO::Socket::Socks
|
||||
use constant SOCKS => $ENV{MOJO_NO_SOCKS}
|
||||
? 0
|
||||
: eval { require IO::Socket::Socks; IO::Socket::Socks->VERSION('0.64'); 1 };
|
||||
use constant READ => SOCKS ? IO::Socket::Socks::SOCKS_WANT_READ() : 0;
|
||||
use constant WRITE => SOCKS ? IO::Socket::Socks::SOCKS_WANT_WRITE() : 0;
|
||||
|
||||
has reactor => sub { Mojo::IOLoop->singleton->reactor }, weak => 1;
|
||||
|
||||
sub DESTROY { shift->_cleanup }
|
||||
|
||||
sub can_nnr {NNR}
|
||||
sub can_socks {SOCKS}
|
||||
|
||||
sub connect {
|
||||
my ($self, $args) = (shift, ref $_[0] ? $_[0] : {@_});
|
||||
|
||||
# Timeout
|
||||
weaken $self;
|
||||
my $reactor = $self->reactor;
|
||||
$self->{timer} = $reactor->timer($args->{timeout} || 10, sub { $self->emit(error => 'Connect timeout') });
|
||||
|
||||
# Blocking name resolution
|
||||
$_ && s/[[\]]//g for @$args{qw(address socks_address)};
|
||||
my $address = $args->{socks_address} || ($args->{address} ||= '127.0.0.1');
|
||||
return $reactor->next_tick(sub { $self && $self->_connect($args) }) if !NNR || $args->{handle} || $args->{path};
|
||||
|
||||
# Non-blocking name resolution
|
||||
$NDN //= Net::DNS::Native->new(pool => 5, extra_thread => 1);
|
||||
my $handle = $self->{dns}
|
||||
= $NDN->getaddrinfo($address, _port($args), {protocol => IPPROTO_TCP, socktype => SOCK_STREAM});
|
||||
$reactor->io(
|
||||
$handle => sub {
|
||||
my $reactor = shift;
|
||||
|
||||
$reactor->remove($self->{dns});
|
||||
my ($err, @res) = $NDN->get_result(delete $self->{dns});
|
||||
return $self->emit(error => "Can't resolve: $err") if $err;
|
||||
|
||||
$args->{addr_info} = \@res;
|
||||
$self->_connect($args);
|
||||
}
|
||||
)->watch($handle, 1, 0);
|
||||
}
|
||||
|
||||
sub _cleanup {
|
||||
my $self = shift;
|
||||
$NDN->timedout($self->{dns}) if $NDN && $self->{dns};
|
||||
return $self unless my $reactor = $self->reactor;
|
||||
$self->{$_} && $reactor->remove(delete $self->{$_}) for qw(dns timer handle);
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub _connect {
|
||||
my ($self, $args) = @_;
|
||||
|
||||
my $path = $args->{path};
|
||||
my $handle = $self->{handle} = $args->{handle};
|
||||
|
||||
unless ($handle) {
|
||||
my $class = $path ? 'IO::Socket::UNIX' : 'IO::Socket::IP';
|
||||
my %options = (Blocking => 0);
|
||||
|
||||
# UNIX domain socket
|
||||
if ($path) { $options{Peer} = $path }
|
||||
|
||||
# IP socket
|
||||
else {
|
||||
if (my $info = $args->{addr_info}) { $options{PeerAddrInfo} = $info }
|
||||
else {
|
||||
$options{PeerAddr} = $args->{socks_address} || $args->{address};
|
||||
$options{PeerPort} = _port($args);
|
||||
}
|
||||
$options{LocalAddr} = $args->{local_address} if $args->{local_address};
|
||||
}
|
||||
|
||||
return $self->emit(error => "Can't connect: $@") unless $self->{handle} = $handle = $class->new(%options);
|
||||
}
|
||||
$handle->blocking(0);
|
||||
|
||||
$path ? $self->_try_socks($args) : $self->_wait('_ready', $handle, $args);
|
||||
}
|
||||
|
||||
sub _port { $_[0]{socks_port} || $_[0]{port} || ($_[0]{tls} ? 443 : 80) }
|
||||
|
||||
sub _ready {
|
||||
my ($self, $args) = @_;
|
||||
|
||||
# Socket changes in between attempts and needs to be re-added for epoll/kqueue
|
||||
my $handle = $self->{handle};
|
||||
unless ($handle->connect) {
|
||||
return $self->emit(error => $!) unless $! == EINPROGRESS;
|
||||
$self->reactor->remove($handle);
|
||||
return $self->_wait('_ready', $handle, $args);
|
||||
}
|
||||
|
||||
return $self->emit(error => $! || 'Not connected') unless $handle->connected;
|
||||
|
||||
# Disable Nagle's algorithm
|
||||
setsockopt $handle, IPPROTO_TCP, TCP_NODELAY, 1;
|
||||
|
||||
$self->_try_socks($args);
|
||||
}
|
||||
|
||||
sub _socks {
|
||||
my ($self, $args) = @_;
|
||||
|
||||
# Connected
|
||||
my $handle = $self->{handle};
|
||||
return $self->_try_tls($args) if $handle->ready;
|
||||
|
||||
# Switch between reading and writing
|
||||
my $err = $IO::Socket::Socks::SOCKS_ERROR;
|
||||
if ($err == READ) { $self->reactor->watch($handle, 1, 0) }
|
||||
elsif ($err == WRITE) { $self->reactor->watch($handle, 1, 1) }
|
||||
else { $self->emit(error => $err) }
|
||||
}
|
||||
|
||||
sub _try_socks {
|
||||
my ($self, $args) = @_;
|
||||
|
||||
my $handle = $self->{handle};
|
||||
return $self->_try_tls($args) unless $args->{socks_address};
|
||||
return $self->emit(error => 'IO::Socket::Socks 0.64+ required for SOCKS support') unless SOCKS;
|
||||
|
||||
my %options = (ConnectAddr => $args->{address}, ConnectPort => $args->{port});
|
||||
@options{qw(AuthType Username Password)} = ('userpass', @$args{qw(socks_user socks_pass)}) if $args->{socks_user};
|
||||
my $reactor = $self->reactor;
|
||||
$reactor->remove($handle);
|
||||
return $self->emit(error => 'SOCKS upgrade failed') unless IO::Socket::Socks->start_SOCKS($handle, %options);
|
||||
|
||||
$self->_wait('_socks', $handle, $args);
|
||||
}
|
||||
|
||||
sub _try_tls {
|
||||
my ($self, $args) = @_;
|
||||
|
||||
my $handle = $self->{handle};
|
||||
return $self->_cleanup->emit(connect => $handle) unless $args->{tls};
|
||||
my $reactor = $self->reactor;
|
||||
$reactor->remove($handle);
|
||||
|
||||
# Start TLS handshake
|
||||
weaken $self;
|
||||
my $tls = Mojo::IOLoop::TLS->new($handle)->reactor($self->reactor);
|
||||
$tls->on(upgrade => sub { $self->_cleanup->emit(connect => pop) });
|
||||
$tls->on(error => sub { $self->emit(error => pop) });
|
||||
$tls->negotiate(%$args);
|
||||
}
|
||||
|
||||
sub _wait {
|
||||
my ($self, $next, $handle, $args) = @_;
|
||||
weaken $self;
|
||||
$self->reactor->io($handle => sub { $self->$next($args) })->watch($handle, 0, 1);
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=encoding utf8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Mojo::IOLoop::Client - Non-blocking TCP/IP and UNIX domain socket client
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Mojo::IOLoop::Client;
|
||||
|
||||
# Create socket connection
|
||||
my $client = Mojo::IOLoop::Client->new;
|
||||
$client->on(connect => sub ($client, $handle) {...});
|
||||
$client->on(error => sub ($client, $err) {...});
|
||||
$client->connect(address => 'example.com', port => 80);
|
||||
|
||||
# Start reactor if necessary
|
||||
$client->reactor->start unless $client->reactor->is_running;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
L<Mojo::IOLoop::Client> opens TCP/IP and UNIX domain socket connections for L<Mojo::IOLoop>.
|
||||
|
||||
=head1 EVENTS
|
||||
|
||||
L<Mojo::IOLoop::Client> inherits all events from L<Mojo::EventEmitter> and can emit the following new ones.
|
||||
|
||||
=head2 connect
|
||||
|
||||
$client->on(connect => sub ($client, $handle) {...});
|
||||
|
||||
Emitted once the connection is established.
|
||||
|
||||
=head2 error
|
||||
|
||||
$client->on(error => sub ($client, $err) {...});
|
||||
|
||||
Emitted if an error occurs on the connection, fatal if unhandled.
|
||||
|
||||
=head1 ATTRIBUTES
|
||||
|
||||
L<Mojo::IOLoop::Client> implements the following attributes.
|
||||
|
||||
=head2 reactor
|
||||
|
||||
my $reactor = $client->reactor;
|
||||
$client = $client->reactor(Mojo::Reactor::Poll->new);
|
||||
|
||||
Low-level event reactor, defaults to the C<reactor> attribute value of the global L<Mojo::IOLoop> singleton. Note that
|
||||
this attribute is weakened.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
L<Mojo::IOLoop::Client> inherits all methods from L<Mojo::EventEmitter> and implements the following new ones.
|
||||
|
||||
=head2 can_nnr
|
||||
|
||||
my $bool = Mojo::IOLoop::Client->can_nnr;
|
||||
|
||||
True if L<Net::DNS::Native> 0.15+ is installed and non-blocking name resolution support enabled.
|
||||
|
||||
=head2 can_socks
|
||||
|
||||
my $bool = Mojo::IOLoop::Client->can_socks;
|
||||
|
||||
True if L<IO::Socket::SOCKS> 0.64+ is installed and SOCKS5 support enabled.
|
||||
|
||||
=head2 connect
|
||||
|
||||
$client->connect(address => '127.0.0.1', port => 3000);
|
||||
$client->connect({address => '127.0.0.1', port => 3000});
|
||||
|
||||
Open a socket connection to a remote host. Note that non-blocking name resolution depends on L<Net::DNS::Native>
|
||||
(0.15+), SOCKS5 support on L<IO::Socket::Socks> (0.64), and TLS support on L<IO::Socket::SSL> (2.009+).
|
||||
|
||||
These options are currently available:
|
||||
|
||||
=over 2
|
||||
|
||||
=item address
|
||||
|
||||
address => 'mojolicious.org'
|
||||
|
||||
Address or host name of the peer to connect to, defaults to C<127.0.0.1>.
|
||||
|
||||
=item handle
|
||||
|
||||
handle => $handle
|
||||
|
||||
Use an already prepared L<IO::Socket::IP> object.
|
||||
|
||||
=item local_address
|
||||
|
||||
local_address => '127.0.0.1'
|
||||
|
||||
Local address to bind to.
|
||||
|
||||
=item path
|
||||
|
||||
path => '/tmp/myapp.sock'
|
||||
|
||||
Path of UNIX domain socket to connect to.
|
||||
|
||||
=item port
|
||||
|
||||
port => 80
|
||||
|
||||
Port to connect to, defaults to C<80> or C<443> with C<tls> option.
|
||||
|
||||
=item socks_address
|
||||
|
||||
socks_address => '127.0.0.1'
|
||||
|
||||
Address or host name of SOCKS5 proxy server to use for connection.
|
||||
|
||||
=item socks_pass
|
||||
|
||||
socks_pass => 'secr3t'
|
||||
|
||||
Password to use for SOCKS5 authentication.
|
||||
|
||||
=item socks_port
|
||||
|
||||
socks_port => 9050
|
||||
|
||||
Port of SOCKS5 proxy server to use for connection.
|
||||
|
||||
=item socks_user
|
||||
|
||||
socks_user => 'sri'
|
||||
|
||||
Username to use for SOCKS5 authentication.
|
||||
|
||||
=item timeout
|
||||
|
||||
timeout => 15
|
||||
|
||||
Maximum amount of time in seconds establishing connection may take before getting canceled, defaults to C<10>.
|
||||
|
||||
=item tls
|
||||
|
||||
tls => 1
|
||||
|
||||
Enable TLS.
|
||||
|
||||
=item tls_ca
|
||||
|
||||
tls_ca => '/etc/tls/ca.crt'
|
||||
|
||||
Path to TLS certificate authority file.
|
||||
|
||||
=item tls_cert
|
||||
|
||||
tls_cert => '/etc/tls/client.crt'
|
||||
|
||||
Path to the TLS certificate file.
|
||||
|
||||
=item tls_key
|
||||
|
||||
tls_key => '/etc/tls/client.key'
|
||||
|
||||
Path to the TLS key file.
|
||||
|
||||
=item tls_protocols
|
||||
|
||||
tls_protocols => ['foo', 'bar']
|
||||
|
||||
ALPN protocols to negotiate.
|
||||
|
||||
=item tls_verify
|
||||
|
||||
tls_verify => 0x00
|
||||
|
||||
TLS verification mode.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Mojolicious>, L<Mojolicious::Guides>, L<https://mojolicious.org>.
|
||||
|
||||
=cut
|
||||
204
database/perl/vendor/lib/Mojo/IOLoop/Delay.pm
vendored
Normal file
204
database/perl/vendor/lib/Mojo/IOLoop/Delay.pm
vendored
Normal file
@@ -0,0 +1,204 @@
|
||||
package Mojo::IOLoop::Delay;
|
||||
use Mojo::Base 'Mojo::Promise';
|
||||
|
||||
sub begin {
|
||||
my ($self, $offset, $len) = @_;
|
||||
$self->{pending}++;
|
||||
my $id = $self->{counter}++;
|
||||
return sub { $self->_step($id, $offset // 1, $len, @_) };
|
||||
}
|
||||
|
||||
sub pass { $_[0]->begin->(@_) }
|
||||
|
||||
sub steps {
|
||||
my ($self, @steps) = @_;
|
||||
$self->{steps} = \@steps;
|
||||
$self->ioloop->next_tick($self->begin);
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub _step {
|
||||
my ($self, $id, $offset, $len) = (shift, shift, shift, shift);
|
||||
|
||||
$self->{args}[$id] = [@_ ? defined $len ? splice @_, $offset, $len : splice @_, $offset : ()];
|
||||
return $self if $self->{fail} || --$self->{pending} || $self->{lock};
|
||||
local $self->{lock} = 1;
|
||||
my @args = map {@$_} @{delete $self->{args}};
|
||||
|
||||
$self->{counter} = 0;
|
||||
if (my $cb = shift @{$self->{steps}}) {
|
||||
unless (eval { $self->$cb(@args); 1 }) {
|
||||
my $err = $@;
|
||||
@{$self}{qw(fail steps)} = (1, []);
|
||||
return $self->reject($err);
|
||||
}
|
||||
}
|
||||
|
||||
($self->{steps} = []) and return $self->resolve(@args) unless $self->{counter};
|
||||
$self->ioloop->next_tick($self->begin) unless $self->{pending};
|
||||
return $self;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=encoding utf8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Mojo::IOLoop::Delay - Promises/A+ and flow-control helpers
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Mojo::IOLoop::Delay;
|
||||
|
||||
# Synchronize multiple non-blocking operations
|
||||
my $delay = Mojo::IOLoop::Delay->new;
|
||||
$delay->steps(sub { say 'BOOM!' });
|
||||
for my $i (1 .. 10) {
|
||||
my $end = $delay->begin;
|
||||
Mojo::IOLoop->timer($i => sub {
|
||||
say 10 - $i;
|
||||
$end->();
|
||||
});
|
||||
}
|
||||
$delay->wait;
|
||||
|
||||
# Sequentialize multiple non-blocking operations
|
||||
Mojo::IOLoop::Delay->new->steps(
|
||||
|
||||
# First step (simple timer)
|
||||
sub ($delay) {
|
||||
Mojo::IOLoop->timer(2 => $delay->begin);
|
||||
say 'Second step in 2 seconds.';
|
||||
},
|
||||
|
||||
# Second step (concurrent timers)
|
||||
sub ($delay, @args) {
|
||||
Mojo::IOLoop->timer(1 => $delay->begin);
|
||||
Mojo::IOLoop->timer(3 => $delay->begin);
|
||||
say 'Third step in 3 seconds.';
|
||||
},
|
||||
|
||||
# Third step (the end)
|
||||
sub ($delay, @args) {
|
||||
say 'And done after 5 seconds total.';
|
||||
}
|
||||
)->wait;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
L<Mojo::IOLoop::Delay> adds flow-control helpers to L<Mojo::Promise>, which can help you avoid deep nested closures
|
||||
that often result from continuation-passing style.
|
||||
|
||||
use Mojo::IOLoop;
|
||||
|
||||
# These deep nested closures are often referred to as "Callback Hell"
|
||||
Mojo::IOLoop->timer(3 => sub ($loop) {
|
||||
|
||||
say '3 seconds';
|
||||
Mojo::IOLoop->timer(3 => sub ($loop) {
|
||||
|
||||
say '6 seconds';
|
||||
Mojo::IOLoop->timer(3 => sub ($loop) {
|
||||
|
||||
say '9 seconds';
|
||||
Mojo::IOLoop->stop;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Mojo::IOLoop->start;
|
||||
|
||||
The idea behind L<Mojo::IOLoop::Delay> is to turn the nested closures above into a flat series of closures. In the
|
||||
example below, the call to L</"begin"> creates a code reference that we can pass to L<Mojo::IOLoop/"timer"> as a
|
||||
callback, and that leads to the next closure in the series when executed.
|
||||
|
||||
use Mojo::IOLoop;
|
||||
|
||||
# Instead of nested closures we now have a simple chain of steps
|
||||
my $delay = Mojo::IOLoop->delay(
|
||||
sub ($delay) { Mojo::IOLoop->timer(3 => $delay->begin) },
|
||||
sub ($delay) {
|
||||
say '3 seconds';
|
||||
Mojo::IOLoop->timer(3 => $delay->begin);
|
||||
},
|
||||
sub ($delay) {
|
||||
say '6 seconds';
|
||||
Mojo::IOLoop->timer(3 => $delay->begin);
|
||||
},
|
||||
sub ($delay) { say '9 seconds' }
|
||||
);
|
||||
$delay->wait;
|
||||
|
||||
Another positive side effect of this pattern is that we do not need to call L<Mojo::IOLoop/"start"> and
|
||||
L<Mojo::IOLoop/"stop"> manually, because we know exactly when our chain of L</"steps"> has reached the end. So
|
||||
L<Mojo::Promise/"wait"> can stop the event loop automatically if it had to be started at all in the first place.
|
||||
|
||||
=head1 ATTRIBUTES
|
||||
|
||||
L<Mojo::IOLoop::Delay> inherits all attributes from L<Mojo::Promise>.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
L<Mojo::IOLoop::Delay> inherits all methods from L<Mojo::Promise> and implements the following new ones.
|
||||
|
||||
=head2 begin
|
||||
|
||||
my $cb = $delay->begin;
|
||||
my $cb = $delay->begin($offset);
|
||||
my $cb = $delay->begin($offset, $len);
|
||||
|
||||
Indicate an active event by incrementing the event counter, the returned code reference can be used as a callback, and
|
||||
needs to be executed when the event has completed to decrement the event counter again. When all code references
|
||||
generated by this method have been executed and the event counter has reached zero, L</"steps"> will continue.
|
||||
|
||||
# Capture all arguments except for the first one (invocant)
|
||||
my $delay = Mojo::IOLoop->delay(sub ($delay, $err, $stream) { ... });
|
||||
Mojo::IOLoop->client({port => 3000} => $delay->begin);
|
||||
$delay->wait;
|
||||
|
||||
Arguments passed to the returned code reference are spliced with the given offset and length, defaulting to an offset
|
||||
of C<1> with no default length. The arguments are then combined in the same order L</"begin"> was called, and passed
|
||||
together to the next step.
|
||||
|
||||
# Capture all arguments
|
||||
my $delay = Mojo::IOLoop->delay(sub ($delay, $loop, $err, $stream) { ... });
|
||||
Mojo::IOLoop->client({port => 3000} => $delay->begin(0));
|
||||
$delay->wait;
|
||||
|
||||
# Capture only the second argument
|
||||
my $delay = Mojo::IOLoop->delay(sub ($delay, $err) { ... });
|
||||
Mojo::IOLoop->client({port => 3000} => $delay->begin(1, 1));
|
||||
$delay->wait;
|
||||
|
||||
# Capture and combine arguments
|
||||
my $delay = Mojo::IOLoop->delay(sub ($delay, $three_err, $three_stream, $four_err, $four_stream) { ... });
|
||||
Mojo::IOLoop->client({port => 3000} => $delay->begin);
|
||||
Mojo::IOLoop->client({port => 4000} => $delay->begin);
|
||||
$delay->wait;
|
||||
|
||||
=head2 pass
|
||||
|
||||
$delay = $delay->pass;
|
||||
$delay = $delay->pass(@args);
|
||||
|
||||
Shortcut for passing values between L</"steps">.
|
||||
|
||||
# Longer version
|
||||
$delay->begin(0)->(@args);
|
||||
|
||||
=head2 steps
|
||||
|
||||
$delay = $delay->steps(sub {...}, sub {...});
|
||||
|
||||
Sequentialize multiple events, every time the event counter reaches zero a callback will run, the first one
|
||||
automatically runs during the next reactor tick unless it is delayed by incrementing the event counter. This chain will
|
||||
continue until there are no remaining callbacks, a callback does not increment the event counter or an exception gets
|
||||
thrown in a callback. Finishing the chain will also result in the promise being fulfilled, or if an exception got
|
||||
thrown it will be rejected.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Mojolicious>, L<Mojolicious::Guides>, L<https://mojolicious.org>.
|
||||
|
||||
=cut
|
||||
313
database/perl/vendor/lib/Mojo/IOLoop/Server.pm
vendored
Normal file
313
database/perl/vendor/lib/Mojo/IOLoop/Server.pm
vendored
Normal file
@@ -0,0 +1,313 @@
|
||||
package Mojo::IOLoop::Server;
|
||||
use Mojo::Base 'Mojo::EventEmitter';
|
||||
|
||||
use Carp qw(croak);
|
||||
use IO::Socket::IP;
|
||||
use IO::Socket::UNIX;
|
||||
use Mojo::File qw(path);
|
||||
use Mojo::IOLoop;
|
||||
use Mojo::IOLoop::TLS;
|
||||
use Scalar::Util qw(weaken);
|
||||
use Socket qw(IPPROTO_TCP TCP_NODELAY);
|
||||
|
||||
has reactor => sub { Mojo::IOLoop->singleton->reactor }, weak => 1;
|
||||
|
||||
sub DESTROY {
|
||||
my $self = shift;
|
||||
$ENV{MOJO_REUSE} =~ s/(?:^|\,)\Q$self->{reuse}\E// if $self->{reuse};
|
||||
$self->stop if $self->{handle} && $self->reactor;
|
||||
}
|
||||
|
||||
sub generate_port { IO::Socket::IP->new(Listen => 5, LocalAddr => '127.0.0.1')->sockport }
|
||||
|
||||
sub handle { shift->{handle} }
|
||||
|
||||
sub is_accepting { !!shift->{active} }
|
||||
|
||||
sub listen {
|
||||
my ($self, $args) = (shift, ref $_[0] ? $_[0] : {@_});
|
||||
|
||||
# Look for reusable file descriptor
|
||||
my $path = $args->{path};
|
||||
my $address = $args->{address} || '0.0.0.0';
|
||||
my $port = $args->{port};
|
||||
$ENV{MOJO_REUSE} ||= '';
|
||||
my $fd = ($path && $ENV{MOJO_REUSE} =~ /(?:^|\,)unix:\Q$path\E:(\d+)/)
|
||||
|| ($port && $ENV{MOJO_REUSE} =~ /(?:^|\,)\Q$address:$port\E:(\d+)/) ? $1 : undef;
|
||||
|
||||
# Allow file descriptor inheritance
|
||||
local $^F = 1023;
|
||||
|
||||
# Reuse file descriptor
|
||||
my $handle;
|
||||
my $class = $path ? 'IO::Socket::UNIX' : 'IO::Socket::IP';
|
||||
if (defined($fd //= $args->{fd})) {
|
||||
$handle = $class->new_from_fd($fd, 'r') or croak "Can't open file descriptor $fd: $!";
|
||||
}
|
||||
|
||||
else {
|
||||
my %options = (Listen => $args->{backlog} // SOMAXCONN, Type => SOCK_STREAM);
|
||||
|
||||
# UNIX domain socket
|
||||
my $reuse;
|
||||
if ($path) {
|
||||
path($path)->remove if -S $path;
|
||||
$options{Local} = $path;
|
||||
$handle = $class->new(%options) or croak "Can't create listen socket: $!";
|
||||
$reuse = $self->{reuse} = join ':', 'unix', $path, fileno $handle;
|
||||
}
|
||||
|
||||
# IP socket
|
||||
else {
|
||||
$options{LocalAddr} = $address;
|
||||
$options{LocalAddr} =~ y/[]//d;
|
||||
$options{LocalPort} = $port if $port;
|
||||
$options{ReuseAddr} = 1;
|
||||
$options{ReusePort} = $args->{reuse};
|
||||
$handle = $class->new(%options) or croak "Can't create listen socket: $@";
|
||||
$fd = fileno $handle;
|
||||
$reuse = $self->{reuse} = join ':', $address, $handle->sockport, $fd;
|
||||
}
|
||||
|
||||
$ENV{MOJO_REUSE} .= length $ENV{MOJO_REUSE} ? ",$reuse" : "$reuse";
|
||||
}
|
||||
$handle->blocking(0);
|
||||
@$self{qw(args handle)} = ($args, $handle);
|
||||
|
||||
croak 'IO::Socket::SSL 2.009+ required for TLS support' if !Mojo::IOLoop::TLS->can_tls && $args->{tls};
|
||||
}
|
||||
|
||||
sub port { shift->{handle}->sockport }
|
||||
|
||||
sub start {
|
||||
my $self = shift;
|
||||
weaken $self;
|
||||
++$self->{active} and $self->reactor->io($self->{handle} => sub { $self->_accept })->watch($self->{handle}, 1, 0);
|
||||
}
|
||||
|
||||
sub stop { delete($_[0]{active}) and $_[0]->reactor->remove($_[0]{handle}) }
|
||||
|
||||
sub _accept {
|
||||
my $self = shift;
|
||||
|
||||
# Greedy accept
|
||||
my $args = $self->{args};
|
||||
my $accepted = 0;
|
||||
while ($self->{active} && !($args->{single_accept} && $accepted++)) {
|
||||
return unless my $handle = $self->{handle}->accept;
|
||||
$handle->blocking(0);
|
||||
|
||||
# Disable Nagle's algorithm
|
||||
setsockopt $handle, IPPROTO_TCP, TCP_NODELAY, 1;
|
||||
|
||||
$self->emit(accept => $handle) and next unless $args->{tls};
|
||||
|
||||
# Start TLS handshake
|
||||
my $tls = Mojo::IOLoop::TLS->new($handle)->reactor($self->reactor);
|
||||
$tls->on(upgrade => sub { $self->emit(accept => pop) });
|
||||
$tls->on(error => sub { });
|
||||
$tls->negotiate(%$args, server => 1);
|
||||
}
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=encoding utf8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Mojo::IOLoop::Server - Non-blocking TCP and UNIX domain socket server
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Mojo::IOLoop::Server;
|
||||
|
||||
# Create listen socket
|
||||
my $server = Mojo::IOLoop::Server->new;
|
||||
$server->on(accept => sub ($server, $handle) {...});
|
||||
$server->listen(port => 3000);
|
||||
|
||||
# Start and stop accepting connections
|
||||
$server->start;
|
||||
$server->stop;
|
||||
|
||||
# Start reactor if necessary
|
||||
$server->reactor->start unless $server->reactor->is_running;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
L<Mojo::IOLoop::Server> accepts TCP/IP and UNIX domain socket connections for L<Mojo::IOLoop>.
|
||||
|
||||
=head1 EVENTS
|
||||
|
||||
L<Mojo::IOLoop::Server> inherits all events from L<Mojo::EventEmitter> and can emit the following new ones.
|
||||
|
||||
=head2 accept
|
||||
|
||||
$server->on(accept => sub ($server, $handle) {...});
|
||||
|
||||
Emitted for each accepted connection.
|
||||
|
||||
=head1 ATTRIBUTES
|
||||
|
||||
L<Mojo::IOLoop::Server> implements the following attributes.
|
||||
|
||||
=head2 reactor
|
||||
|
||||
my $reactor = $server->reactor;
|
||||
$server = $server->reactor(Mojo::Reactor::Poll->new);
|
||||
|
||||
Low-level event reactor, defaults to the C<reactor> attribute value of the global L<Mojo::IOLoop> singleton. Note that
|
||||
this attribute is weakened.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
L<Mojo::IOLoop::Server> inherits all methods from L<Mojo::EventEmitter> and implements the following new ones.
|
||||
|
||||
=head2 generate_port
|
||||
|
||||
my $port = Mojo::IOLoop::Server->generate_port;
|
||||
|
||||
Find a free TCP port, primarily used for tests.
|
||||
|
||||
=head2 handle
|
||||
|
||||
my $handle = $server->handle;
|
||||
|
||||
Get handle for server, usually an L<IO::Socket::IP> object.
|
||||
|
||||
=head2 is_accepting
|
||||
|
||||
my $bool = $server->is_accepting;
|
||||
|
||||
Check if connections are currently being accepted.
|
||||
|
||||
=head2 listen
|
||||
|
||||
$server->listen(port => 3000);
|
||||
$server->listen({port => 3000});
|
||||
|
||||
Create a new listen socket. Note that TLS support depends on L<IO::Socket::SSL> (2.009+).
|
||||
|
||||
These options are currently available:
|
||||
|
||||
=over 2
|
||||
|
||||
=item address
|
||||
|
||||
address => '127.0.0.1'
|
||||
|
||||
Local address to listen on, defaults to C<0.0.0.0>.
|
||||
|
||||
=item backlog
|
||||
|
||||
backlog => 128
|
||||
|
||||
Maximum backlog size, defaults to C<SOMAXCONN>.
|
||||
|
||||
=item fd
|
||||
|
||||
fd => 3
|
||||
|
||||
File descriptor with an already prepared listen socket.
|
||||
|
||||
=item path
|
||||
|
||||
path => '/tmp/myapp.sock'
|
||||
|
||||
Path for UNIX domain socket to listen on.
|
||||
|
||||
=item port
|
||||
|
||||
port => 80
|
||||
|
||||
Port to listen on, defaults to a random port.
|
||||
|
||||
=item reuse
|
||||
|
||||
reuse => 1
|
||||
|
||||
Allow multiple servers to use the same port with the C<SO_REUSEPORT> socket option.
|
||||
|
||||
=item single_accept
|
||||
|
||||
single_accept => 1
|
||||
|
||||
Only accept one connection at a time.
|
||||
|
||||
=item tls
|
||||
|
||||
tls => 1
|
||||
|
||||
Enable TLS.
|
||||
|
||||
=item tls_ca
|
||||
|
||||
tls_ca => '/etc/tls/ca.crt'
|
||||
|
||||
Path to TLS certificate authority file.
|
||||
|
||||
=item tls_cert
|
||||
|
||||
tls_cert => '/etc/tls/server.crt'
|
||||
tls_cert => {'mojolicious.org' => '/etc/tls/mojo.crt'}
|
||||
|
||||
Path to the TLS cert file, defaults to a built-in test certificate.
|
||||
|
||||
=item tls_ciphers
|
||||
|
||||
tls_ciphers => 'AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH'
|
||||
|
||||
TLS cipher specification string. For more information about the format see
|
||||
L<https://www.openssl.org/docs/manmaster/apps/ciphers.html#CIPHER-STRINGS>.
|
||||
|
||||
=item tls_key
|
||||
|
||||
tls_key => '/etc/tls/server.key'
|
||||
tls_key => {'mojolicious.org' => '/etc/tls/mojo.key'}
|
||||
|
||||
Path to the TLS key file, defaults to a built-in test key.
|
||||
|
||||
=item tls_protocols
|
||||
|
||||
tls_protocols => ['foo', 'bar']
|
||||
|
||||
ALPN protocols to negotiate.
|
||||
|
||||
=item tls_verify
|
||||
|
||||
tls_verify => 0x00
|
||||
|
||||
TLS verification mode.
|
||||
|
||||
=item tls_version
|
||||
|
||||
tls_version => 'TLSv1_2'
|
||||
|
||||
TLS protocol version.
|
||||
|
||||
=back
|
||||
|
||||
=head2 port
|
||||
|
||||
my $port = $server->port;
|
||||
|
||||
Get port this server is listening on.
|
||||
|
||||
=head2 start
|
||||
|
||||
$server->start;
|
||||
|
||||
Start or resume accepting connections.
|
||||
|
||||
=head2 stop
|
||||
|
||||
$server->stop;
|
||||
|
||||
Stop accepting connections.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Mojolicious>, L<Mojolicious::Guides>, L<https://mojolicious.org>.
|
||||
|
||||
=cut
|
||||
327
database/perl/vendor/lib/Mojo/IOLoop/Stream.pm
vendored
Normal file
327
database/perl/vendor/lib/Mojo/IOLoop/Stream.pm
vendored
Normal file
@@ -0,0 +1,327 @@
|
||||
package Mojo::IOLoop::Stream;
|
||||
use Mojo::Base 'Mojo::EventEmitter';
|
||||
|
||||
use Errno qw(EAGAIN ECONNRESET EINTR EWOULDBLOCK);
|
||||
use Mojo::IOLoop;
|
||||
use Mojo::Util;
|
||||
use Scalar::Util qw(weaken);
|
||||
|
||||
has high_water_mark => 1048576;
|
||||
has reactor => sub { Mojo::IOLoop->singleton->reactor }, weak => 1;
|
||||
|
||||
sub DESTROY { Mojo::Util::_global_destruction() or shift->close }
|
||||
|
||||
sub bytes_read { shift->{read} || 0 }
|
||||
|
||||
sub bytes_waiting { length(shift->{buffer} // '') }
|
||||
|
||||
sub bytes_written { shift->{written} || 0 }
|
||||
|
||||
sub can_write { $_[0]{handle} && $_[0]->bytes_waiting < $_[0]->high_water_mark }
|
||||
|
||||
sub close {
|
||||
my $self = shift;
|
||||
return unless my $reactor = $self->reactor;
|
||||
return unless my $handle = delete $self->timeout(0)->{handle};
|
||||
$reactor->remove($handle);
|
||||
$self->emit('close');
|
||||
}
|
||||
|
||||
sub close_gracefully { $_[0]->is_writing ? $_[0]{graceful}++ : $_[0]->close }
|
||||
|
||||
sub handle { shift->{handle} }
|
||||
|
||||
sub is_readable {
|
||||
my $self = shift;
|
||||
$self->_again;
|
||||
return $self->{handle} && Mojo::Util::_readable(0, fileno $self->{handle});
|
||||
}
|
||||
|
||||
sub is_writing {
|
||||
my $self = shift;
|
||||
return undef unless $self->{handle};
|
||||
return !!length($self->{buffer}) || $self->has_subscribers('drain');
|
||||
}
|
||||
|
||||
sub new { shift->SUPER::new(handle => shift, timeout => 15) }
|
||||
|
||||
sub start {
|
||||
my $self = shift;
|
||||
|
||||
# Resume
|
||||
return unless $self->{handle};
|
||||
my $reactor = $self->reactor;
|
||||
return $reactor->watch($self->{handle}, 1, $self->is_writing) if delete $self->{paused};
|
||||
|
||||
weaken $self;
|
||||
my $cb = sub { pop() ? $self->_write : $self->_read };
|
||||
$reactor->io($self->timeout($self->{timeout})->{handle} => $cb);
|
||||
}
|
||||
|
||||
sub steal_handle {
|
||||
my $self = shift;
|
||||
$self->reactor->remove($self->{handle});
|
||||
return delete $self->{handle};
|
||||
}
|
||||
|
||||
sub stop { $_[0]->reactor->watch($_[0]{handle}, 0, $_[0]->is_writing) if $_[0]{handle} && !$_[0]{paused}++ }
|
||||
|
||||
sub timeout {
|
||||
my ($self, $timeout) = @_;
|
||||
|
||||
return $self->{timeout} unless defined $timeout;
|
||||
$self->{timeout} = $timeout;
|
||||
|
||||
my $reactor = $self->reactor;
|
||||
if ($self->{timer}) {
|
||||
if (!$self->{timeout}) { $reactor->remove(delete $self->{timer}) }
|
||||
else { $reactor->again($self->{timer}, $self->{timeout}) }
|
||||
}
|
||||
elsif ($self->{timeout}) {
|
||||
weaken $self;
|
||||
$self->{timer}
|
||||
= $reactor->timer($timeout => sub { $self and delete($self->{timer}) and $self->emit('timeout')->close });
|
||||
}
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub write {
|
||||
my ($self, $chunk, $cb) = @_;
|
||||
|
||||
# IO::Socket::SSL will corrupt data with the wrong internal representation
|
||||
utf8::downgrade $chunk;
|
||||
$self->{buffer} .= $chunk;
|
||||
if ($cb) { $self->once(drain => $cb) }
|
||||
elsif (!length $self->{buffer}) { return $self }
|
||||
$self->reactor->watch($self->{handle}, !$self->{paused}, 1) if $self->{handle};
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub _again { $_[0]->reactor->again($_[0]{timer}) if $_[0]{timer} }
|
||||
|
||||
sub _read {
|
||||
my $self = shift;
|
||||
|
||||
if (defined(my $read = $self->{handle}->sysread(my $buffer, 131072, 0))) {
|
||||
$self->{read} += $read;
|
||||
return $read == 0 ? $self->close : $self->emit(read => $buffer)->_again;
|
||||
}
|
||||
|
||||
# Retry
|
||||
return undef if $! == EAGAIN || $! == EINTR || $! == EWOULDBLOCK;
|
||||
|
||||
# Closed (maybe real error)
|
||||
$! == ECONNRESET ? $self->close : $self->emit(error => $!)->close;
|
||||
}
|
||||
|
||||
sub _write {
|
||||
my $self = shift;
|
||||
|
||||
# Handle errors only when reading (to avoid timing problems)
|
||||
my $handle = $self->{handle};
|
||||
if (length $self->{buffer}) {
|
||||
return undef unless defined(my $written = $handle->syswrite($self->{buffer}));
|
||||
$self->{written} += $written;
|
||||
$self->emit(write => substr($self->{buffer}, 0, $written, ''))->_again;
|
||||
}
|
||||
|
||||
# Clear the buffer to free the underlying SV* memory
|
||||
undef $self->{buffer}, $self->emit('drain') unless length $self->{buffer};
|
||||
return undef if $self->is_writing;
|
||||
return $self->close if $self->{graceful};
|
||||
$self->reactor->watch($handle, !$self->{paused}, 0) if $self->{handle};
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=encoding utf8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Mojo::IOLoop::Stream - Non-blocking I/O stream
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Mojo::IOLoop::Stream;
|
||||
|
||||
# Create stream
|
||||
my $stream = Mojo::IOLoop::Stream->new($handle);
|
||||
$stream->on(read => sub ($stream, $bytes) {...});
|
||||
$stream->on(close => sub ($stream) {...});
|
||||
$stream->on(error => sub ($stream, $err) {...});
|
||||
|
||||
# Start and stop watching for new data
|
||||
$stream->start;
|
||||
$stream->stop;
|
||||
|
||||
# Start reactor if necessary
|
||||
$stream->reactor->start unless $stream->reactor->is_running;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
L<Mojo::IOLoop::Stream> is a container for I/O streams used by L<Mojo::IOLoop>.
|
||||
|
||||
=head1 EVENTS
|
||||
|
||||
L<Mojo::IOLoop::Stream> inherits all events from L<Mojo::EventEmitter> and can emit the following new ones.
|
||||
|
||||
=head2 close
|
||||
|
||||
$stream->on(close => sub ($stream) {...});
|
||||
|
||||
Emitted if the stream gets closed.
|
||||
|
||||
=head2 drain
|
||||
|
||||
$stream->on(drain => sub ($stream) {...});
|
||||
|
||||
Emitted once all data has been written.
|
||||
|
||||
=head2 error
|
||||
|
||||
$stream->on(error => sub ($stream, $err) {...});
|
||||
|
||||
Emitted if an error occurs on the stream, fatal if unhandled.
|
||||
|
||||
=head2 read
|
||||
|
||||
$stream->on(read => sub ($stream, $bytes) {...});
|
||||
|
||||
Emitted if new data arrives on the stream.
|
||||
|
||||
=head2 timeout
|
||||
|
||||
$stream->on(timeout => sub ($stream) {...});
|
||||
|
||||
Emitted if the stream has been inactive for too long and will get closed automatically.
|
||||
|
||||
=head2 write
|
||||
|
||||
$stream->on(write => sub ($stream, $bytes) {...});
|
||||
|
||||
Emitted if new data has been written to the stream.
|
||||
|
||||
=head1 ATTRIBUTES
|
||||
|
||||
L<Mojo::IOLoop::Stream> implements the following attributes.
|
||||
|
||||
=head2 high_water_mark
|
||||
|
||||
my $size = $msg->high_water_mark;
|
||||
$msg = $msg->high_water_mark(1024);
|
||||
|
||||
Maximum size of L</"write"> buffer in bytes before L</"can_write"> returns false, defaults to C<1048576> (1MiB).
|
||||
|
||||
=head2 reactor
|
||||
|
||||
my $reactor = $stream->reactor;
|
||||
$stream = $stream->reactor(Mojo::Reactor::Poll->new);
|
||||
|
||||
Low-level event reactor, defaults to the C<reactor> attribute value of the global L<Mojo::IOLoop> singleton. Note that
|
||||
this attribute is weakened.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
L<Mojo::IOLoop::Stream> inherits all methods from L<Mojo::EventEmitter> and implements the following new ones.
|
||||
|
||||
=head2 bytes_read
|
||||
|
||||
my $num = $stream->bytes_read;
|
||||
|
||||
Number of bytes received.
|
||||
|
||||
=head2 bytes_waiting
|
||||
|
||||
my $num = $stream->bytes_waiting;
|
||||
|
||||
Number of bytes that have been enqueued with L</"write"> and are waiting to be written.
|
||||
|
||||
=head2 bytes_written
|
||||
|
||||
my $num = $stream->bytes_written;
|
||||
|
||||
Number of bytes written.
|
||||
|
||||
=head2 can_write
|
||||
|
||||
my $bool = $stream->can_write;
|
||||
|
||||
Returns true if calling L</"write"> is safe.
|
||||
|
||||
=head2 close
|
||||
|
||||
$stream->close;
|
||||
|
||||
Close stream immediately.
|
||||
|
||||
=head2 close_gracefully
|
||||
|
||||
$stream->close_gracefully;
|
||||
|
||||
Close stream gracefully.
|
||||
|
||||
=head2 handle
|
||||
|
||||
my $handle = $stream->handle;
|
||||
|
||||
Get handle for stream, usually an L<IO::Socket::IP> or L<IO::Socket::SSL> object.
|
||||
|
||||
=head2 is_readable
|
||||
|
||||
my $bool = $stream->is_readable;
|
||||
|
||||
Quick non-blocking check if stream is readable, useful for identifying tainted sockets.
|
||||
|
||||
=head2 is_writing
|
||||
|
||||
my $bool = $stream->is_writing;
|
||||
|
||||
Check if stream is writing.
|
||||
|
||||
=head2 new
|
||||
|
||||
my $stream = Mojo::IOLoop::Stream->new($handle);
|
||||
|
||||
Construct a new L<Mojo::IOLoop::Stream> object.
|
||||
|
||||
=head2 start
|
||||
|
||||
$stream->start;
|
||||
|
||||
Start or resume watching for new data on the stream.
|
||||
|
||||
=head2 steal_handle
|
||||
|
||||
my $handle = $stream->steal_handle;
|
||||
|
||||
Steal L</"handle"> and prevent it from getting closed automatically.
|
||||
|
||||
=head2 stop
|
||||
|
||||
$stream->stop;
|
||||
|
||||
Stop watching for new data on the stream.
|
||||
|
||||
=head2 timeout
|
||||
|
||||
my $timeout = $stream->timeout;
|
||||
$stream = $stream->timeout(45);
|
||||
|
||||
Maximum amount of time in seconds stream can be inactive before getting closed automatically, defaults to C<15>.
|
||||
Setting the value to C<0> will allow this stream to be inactive indefinitely.
|
||||
|
||||
=head2 write
|
||||
|
||||
$stream = $stream->write($bytes);
|
||||
$stream = $stream->write($bytes => sub {...});
|
||||
|
||||
Enqueue data to be written to the stream as soon as possible, the optional drain callback will be executed once all
|
||||
data has been written.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Mojolicious>, L<Mojolicious::Guides>, L<https://mojolicious.org>.
|
||||
|
||||
=cut
|
||||
265
database/perl/vendor/lib/Mojo/IOLoop/Subprocess.pm
vendored
Normal file
265
database/perl/vendor/lib/Mojo/IOLoop/Subprocess.pm
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
package Mojo::IOLoop::Subprocess;
|
||||
use Mojo::Base 'Mojo::EventEmitter';
|
||||
|
||||
use Config;
|
||||
use Mojo::IOLoop;
|
||||
use Mojo::IOLoop::Stream;
|
||||
use Mojo::JSON;
|
||||
use Mojo::Promise;
|
||||
use POSIX ();
|
||||
|
||||
has deserialize => sub { \&Mojo::JSON::decode_json };
|
||||
has ioloop => sub { Mojo::IOLoop->singleton }, weak => 1;
|
||||
has serialize => sub { \&Mojo::JSON::encode_json };
|
||||
|
||||
sub exit_code { shift->{exit_code} }
|
||||
|
||||
sub pid { shift->{pid} }
|
||||
|
||||
sub run {
|
||||
my ($self, @args) = @_;
|
||||
$self->ioloop->next_tick(sub { $self->_start(@args) });
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub run_p {
|
||||
my ($self, $child) = @_;
|
||||
|
||||
my $p = Mojo::Promise->new;
|
||||
my $parent = sub {
|
||||
my ($self, $err) = (shift, shift);
|
||||
$err ? $p->reject($err) : $p->resolve(@_);
|
||||
};
|
||||
$self->ioloop->next_tick(sub { $self->_start($child, $parent) });
|
||||
|
||||
return $p;
|
||||
}
|
||||
|
||||
sub _start {
|
||||
my ($self, $child, $parent) = @_;
|
||||
|
||||
# No fork emulation support
|
||||
return $self->$parent('Subprocesses do not support fork emulation') if $Config{d_pseudofork};
|
||||
|
||||
# Pipe for subprocess communication
|
||||
return $self->$parent("Can't create pipe: $!") unless pipe(my $reader, $self->{writer});
|
||||
$self->{writer}->autoflush(1);
|
||||
|
||||
# Child
|
||||
return $self->$parent("Can't fork: $!") unless defined(my $pid = $self->{pid} = fork);
|
||||
unless ($pid) {
|
||||
eval {
|
||||
$self->ioloop->reset({freeze => 1});
|
||||
my $results = eval { [$self->$child] } // [];
|
||||
print {$self->{writer}} '0-', $self->serialize->([$@, @$results]);
|
||||
$self->emit('cleanup');
|
||||
} or warn $@;
|
||||
POSIX::_exit(0);
|
||||
}
|
||||
|
||||
# Parent
|
||||
my $me = $$;
|
||||
close $self->{writer};
|
||||
my $stream = Mojo::IOLoop::Stream->new($reader)->timeout(0);
|
||||
$self->emit('spawn')->ioloop->stream($stream);
|
||||
my $buffer = '';
|
||||
$stream->on(
|
||||
read => sub {
|
||||
$buffer .= pop;
|
||||
while (1) {
|
||||
my ($len) = $buffer =~ /^([0-9]+)\-/;
|
||||
last unless $len and length $buffer >= $len + $+[0];
|
||||
my $snippet = substr $buffer, 0, $len + $+[0], '';
|
||||
my $args = $self->deserialize->(substr $snippet, $+[0]);
|
||||
$self->emit(progress => @$args);
|
||||
}
|
||||
}
|
||||
);
|
||||
$stream->on(
|
||||
close => sub {
|
||||
return unless $$ == $me;
|
||||
waitpid $pid, 0;
|
||||
$self->{exit_code} = $? >> 8;
|
||||
substr $buffer, 0, 2, '';
|
||||
my $results = eval { $self->deserialize->($buffer) } // [];
|
||||
$self->$parent(shift(@$results) // $@, @$results);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub progress {
|
||||
my ($self, @args) = @_;
|
||||
my $serialized = $self->serialize->(\@args);
|
||||
print {$self->{writer}} length($serialized), '-', $serialized;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=encoding utf8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Mojo::IOLoop::Subprocess - Subprocesses
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Mojo::IOLoop::Subprocess;
|
||||
|
||||
# Operation that would block the event loop for 5 seconds
|
||||
my $subprocess = Mojo::IOLoop::Subprocess->new;
|
||||
$subprocess->run(
|
||||
sub ($subprocess) {
|
||||
sleep 5;
|
||||
return '♥', 'Mojolicious';
|
||||
},
|
||||
sub ($subprocess, $err, @results) {
|
||||
say "Subprocess error: $err" and return if $err;
|
||||
say "I $results[0] $results[1]!";
|
||||
}
|
||||
);
|
||||
|
||||
# Operation that would block the event loop for 5 seconds (with promise)
|
||||
$subprocess->run_p(sub {
|
||||
sleep 5;
|
||||
return '♥', 'Mojolicious';
|
||||
})->then(sub (@results) {
|
||||
say "I $results[0] $results[1]!";
|
||||
})->catch(sub {
|
||||
my $err = shift;
|
||||
say "Subprocess error: $err";
|
||||
});
|
||||
|
||||
# Start event loop if necessary
|
||||
$subprocess->ioloop->start unless $subprocess->ioloop->is_running;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
L<Mojo::IOLoop::Subprocess> allows L<Mojo::IOLoop> to perform computationally expensive operations in subprocesses,
|
||||
without blocking the event loop.
|
||||
|
||||
=head1 EVENTS
|
||||
|
||||
L<Mojo::IOLoop::Subprocess> inherits all events from L<Mojo::EventEmitter> and can emit the following new ones.
|
||||
|
||||
=head2 cleanup
|
||||
|
||||
$subprocess->on(cleanup => sub ($subprocess) {...});
|
||||
|
||||
Emitted in the subprocess right before the process will exit.
|
||||
|
||||
$subprocess->on(cleanup => sub ($subprocess) { say "Process $$ is about to exit" });
|
||||
|
||||
=head2 progress
|
||||
|
||||
$subprocess->on(progress => sub ($subprocess, @data) {...});
|
||||
|
||||
Emitted in the parent process when the subprocess calls the L<progress|/"progress1"> method.
|
||||
|
||||
=head2 spawn
|
||||
|
||||
$subprocess->on(spawn => sub ($subprocess) {...});
|
||||
|
||||
Emitted in the parent process when the subprocess has been spawned.
|
||||
|
||||
$subprocess->on(spawn => sub ($subprocess) {
|
||||
my $pid = $subprocess->pid;
|
||||
say "Performing work in process $pid";
|
||||
});
|
||||
|
||||
=head1 ATTRIBUTES
|
||||
|
||||
L<Mojo::IOLoop::Subprocess> implements the following attributes.
|
||||
|
||||
=head2 deserialize
|
||||
|
||||
my $cb = $subprocess->deserialize;
|
||||
$subprocess = $subprocess->deserialize(sub {...});
|
||||
|
||||
A callback used to deserialize subprocess return values, defaults to using L<Mojo::JSON>.
|
||||
|
||||
$subprocess->deserialize(sub ($bytes) { return [] });
|
||||
|
||||
=head2 ioloop
|
||||
|
||||
my $loop = $subprocess->ioloop;
|
||||
$subprocess = $subprocess->ioloop(Mojo::IOLoop->new);
|
||||
|
||||
Event loop object to control, defaults to the global L<Mojo::IOLoop> singleton. Note that this attribute is weakened.
|
||||
|
||||
=head2 serialize
|
||||
|
||||
my $cb = $subprocess->serialize;
|
||||
$subprocess = $subprocess->serialize(sub {...});
|
||||
|
||||
A callback used to serialize subprocess return values, defaults to using L<Mojo::JSON>.
|
||||
|
||||
$subprocess->serialize(sub ($array) { return '' });
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
L<Mojo::IOLoop::Subprocess> inherits all methods from L<Mojo::EventEmitter> and implements the following new ones.
|
||||
|
||||
=head2 exit_code
|
||||
|
||||
my $code = $subprocess->exit_code;
|
||||
|
||||
Returns the subprocess exit code, or C<undef> if the subprocess is still running.
|
||||
|
||||
=head2 pid
|
||||
|
||||
my $pid = $subprocess->pid;
|
||||
|
||||
Process id of the spawned subprocess if available.
|
||||
|
||||
=head2 progress
|
||||
|
||||
$subprocess->progress(@data);
|
||||
|
||||
Send data serialized with L<Mojo::JSON> to the parent process at any time during the subprocess's execution. Must be
|
||||
called by the subprocess and emits the L</"progress"> event in the parent process with the data.
|
||||
|
||||
# Send progress information to the parent process
|
||||
$subprocess->run(
|
||||
sub ($subprocess) {
|
||||
$subprocess->progress('0%');
|
||||
sleep 5;
|
||||
$subprocess->progress('50%');
|
||||
sleep 5;
|
||||
return 'Hello Mojo!';
|
||||
},
|
||||
sub ($subprocess, $err, @results) {
|
||||
say 'Progress is 100%';
|
||||
say $results[0];
|
||||
}
|
||||
);
|
||||
$subprocess->on(progress => sub ($subprocess, @data) { say "Progress is $data[0]" });
|
||||
|
||||
=head2 run
|
||||
|
||||
$subprocess = $subprocess->run(sub {...}, sub {...});
|
||||
|
||||
Execute the first callback in a child process and wait for it to return one or more values, without blocking
|
||||
L</"ioloop"> in the parent process. Then execute the second callback in the parent process with the results. The return
|
||||
values of the first callback and exceptions thrown by it, will be serialized with L<Mojo::JSON>, so they can be shared
|
||||
between processes.
|
||||
|
||||
=head2 run_p
|
||||
|
||||
my $promise = $subprocess->run_p(sub {...});
|
||||
|
||||
Same as L</"run">, but returns a L<Mojo::Promise> object instead of accepting a second callback.
|
||||
|
||||
$subprocess->run_p(sub {
|
||||
sleep 5;
|
||||
return '♥', 'Mojolicious';
|
||||
})->then(sub (@results) {
|
||||
say "I $results[0] $results[1]!";
|
||||
})->catch(sub ($err) {
|
||||
say "Subprocess error: $err";
|
||||
})->wait;
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Mojolicious>, L<Mojolicious::Guides>, L<https://mojolicious.org>.
|
||||
|
||||
=cut
|
||||
221
database/perl/vendor/lib/Mojo/IOLoop/TLS.pm
vendored
Normal file
221
database/perl/vendor/lib/Mojo/IOLoop/TLS.pm
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
package Mojo::IOLoop::TLS;
|
||||
use Mojo::Base 'Mojo::EventEmitter';
|
||||
|
||||
use Mojo::File qw(curfile);
|
||||
use Mojo::IOLoop;
|
||||
use Scalar::Util qw(weaken);
|
||||
|
||||
# TLS support requires IO::Socket::SSL
|
||||
use constant TLS => $ENV{MOJO_NO_TLS} ? 0 : eval { require IO::Socket::SSL; IO::Socket::SSL->VERSION('2.009'); 1 };
|
||||
use constant READ => TLS ? IO::Socket::SSL::SSL_WANT_READ() : 0;
|
||||
use constant WRITE => TLS ? IO::Socket::SSL::SSL_WANT_WRITE() : 0;
|
||||
|
||||
has reactor => sub { Mojo::IOLoop->singleton->reactor }, weak => 1;
|
||||
|
||||
# To regenerate the certificate run this command (28.06.2019)
|
||||
# openssl req -x509 -newkey rsa:4096 -nodes -sha256 -out server.crt \
|
||||
# -keyout server.key -days 7300 -subj '/CN=localhost'
|
||||
my $CERT = curfile->sibling('resources', 'server.crt')->to_string;
|
||||
my $KEY = curfile->sibling('resources', 'server.key')->to_string;
|
||||
|
||||
sub DESTROY { shift->_cleanup }
|
||||
|
||||
sub can_tls {TLS}
|
||||
|
||||
sub negotiate {
|
||||
my ($self, $args) = (shift, ref $_[0] ? $_[0] : {@_});
|
||||
|
||||
return $self->emit(error => 'IO::Socket::SSL 2.009+ required for TLS support') unless TLS;
|
||||
|
||||
my $handle = $self->{handle};
|
||||
return $self->emit(error => $IO::Socket::SSL::SSL_ERROR)
|
||||
unless IO::Socket::SSL->start_SSL($handle, %{$self->_expand($args)});
|
||||
$self->reactor->io($handle => sub { $self->_tls($handle, $args->{server}) });
|
||||
}
|
||||
|
||||
sub new { shift->SUPER::new(handle => shift) }
|
||||
|
||||
sub _cleanup {
|
||||
my $self = shift;
|
||||
return undef unless my $reactor = $self->reactor;
|
||||
$reactor->remove($self->{handle}) if $self->{handle};
|
||||
return $self;
|
||||
}
|
||||
|
||||
sub _expand {
|
||||
my ($self, $args) = @_;
|
||||
|
||||
weaken $self;
|
||||
my $tls = {SSL_error_trap => sub { $self->_cleanup->emit(error => $_[1]) }, SSL_startHandshake => 0};
|
||||
$tls->{SSL_alpn_protocols} = $args->{tls_protocols} if $args->{tls_protocols};
|
||||
$tls->{SSL_ca_file} = $args->{tls_ca} if $args->{tls_ca} && -T $args->{tls_ca};
|
||||
$tls->{SSL_cert_file} = $args->{tls_cert} if $args->{tls_cert};
|
||||
$tls->{SSL_cipher_list} = $args->{tls_ciphers} if $args->{tls_ciphers};
|
||||
$tls->{SSL_key_file} = $args->{tls_key} if $args->{tls_key};
|
||||
$tls->{SSL_server} = $args->{server} if $args->{server};
|
||||
$tls->{SSL_verify_mode} = $args->{tls_verify} if defined $args->{tls_verify};
|
||||
$tls->{SSL_version} = $args->{tls_version} if $args->{tls_version};
|
||||
|
||||
if ($args->{server}) {
|
||||
$tls->{SSL_cert_file} ||= $CERT;
|
||||
$tls->{SSL_key_file} ||= $KEY;
|
||||
}
|
||||
else {
|
||||
$tls->{SSL_hostname} = IO::Socket::SSL->can_client_sni ? $args->{address} : '';
|
||||
$tls->{SSL_verifycn_name} = $args->{address};
|
||||
}
|
||||
|
||||
return $tls;
|
||||
}
|
||||
|
||||
sub _tls {
|
||||
my ($self, $handle, $server) = @_;
|
||||
|
||||
# Switch between reading and writing
|
||||
if (!($server ? $handle->accept_SSL : $handle->connect_SSL)) {
|
||||
my $err = $IO::Socket::SSL::SSL_ERROR;
|
||||
if ($err == READ) { $self->reactor->watch($handle, 1, 0) }
|
||||
elsif ($err == WRITE) { $self->reactor->watch($handle, 1, 1) }
|
||||
}
|
||||
|
||||
else { $self->_cleanup->emit(upgrade => delete $self->{handle}) }
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=encoding utf8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Mojo::IOLoop::TLS - Non-blocking TLS handshake
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Mojo::IOLoop::TLS;
|
||||
|
||||
# Negotiate TLS
|
||||
my $tls = Mojo::IOLoop::TLS->new($old_handle);
|
||||
$tls->on(upgrade => sub ($tls, $new_handle) {...});
|
||||
$tls->on(error => sub ($tls, $err) {...});
|
||||
$tls->negotiate(server => 1, tls_version => 'TLSv1_2');
|
||||
|
||||
# Start reactor if necessary
|
||||
$tls->reactor->start unless $tls->reactor->is_running;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
L<Mojo::IOLoop::TLS> negotiates TLS for L<Mojo::IOLoop>.
|
||||
|
||||
=head1 EVENTS
|
||||
|
||||
L<Mojo::IOLoop::TLS> inherits all events from L<Mojo::EventEmitter> and can emit the following new ones.
|
||||
|
||||
=head2 upgrade
|
||||
|
||||
$tls->on(upgrade => sub ($tls, $handle) {...});
|
||||
|
||||
Emitted once TLS has been negotiated.
|
||||
|
||||
=head2 error
|
||||
|
||||
$tls->on(error => sub ($tls, $err) {...});
|
||||
|
||||
Emitted if an error occurs during negotiation, fatal if unhandled.
|
||||
|
||||
=head1 ATTRIBUTES
|
||||
|
||||
L<Mojo::IOLoop::TLS> implements the following attributes.
|
||||
|
||||
=head2 reactor
|
||||
|
||||
my $reactor = $tls->reactor;
|
||||
$tls = $tls->reactor(Mojo::Reactor::Poll->new);
|
||||
|
||||
Low-level event reactor, defaults to the C<reactor> attribute value of the global L<Mojo::IOLoop> singleton. Note that
|
||||
this attribute is weakened.
|
||||
|
||||
=head1 METHODS
|
||||
|
||||
L<Mojo::IOLoop::TLS> inherits all methods from L<Mojo::EventEmitter> and implements the following new ones.
|
||||
|
||||
=head2 can_tls
|
||||
|
||||
my $bool = Mojo::IOLoop::TLS->can_tls;
|
||||
|
||||
True if L<IO::Socket::SSL> 2.009+ is installed and TLS support enabled.
|
||||
|
||||
=head2 negotiate
|
||||
|
||||
$tls->negotiate(server => 1, tls_version => 'TLSv1_2');
|
||||
$tls->negotiate({server => 1, tls_version => 'TLSv1_2'});
|
||||
|
||||
Negotiate TLS.
|
||||
|
||||
These options are currently available:
|
||||
|
||||
=over 2
|
||||
|
||||
=item server
|
||||
|
||||
server => 1
|
||||
|
||||
Negotiate TLS from the server-side, defaults to the client-side.
|
||||
|
||||
=item tls_ca
|
||||
|
||||
tls_ca => '/etc/tls/ca.crt'
|
||||
|
||||
Path to TLS certificate authority file.
|
||||
|
||||
=item tls_cert
|
||||
|
||||
tls_cert => '/etc/tls/server.crt'
|
||||
tls_cert => {'mojolicious.org' => '/etc/tls/mojo.crt'}
|
||||
|
||||
Path to the TLS cert file, defaults to a built-in test certificate on the server-side.
|
||||
|
||||
=item tls_ciphers
|
||||
|
||||
tls_ciphers => 'AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH'
|
||||
|
||||
TLS cipher specification string. For more information about the format see
|
||||
L<https://www.openssl.org/docs/manmaster/apps/ciphers.html#CIPHER-STRINGS>.
|
||||
|
||||
=item tls_key
|
||||
|
||||
tls_key => '/etc/tls/server.key'
|
||||
tls_key => {'mojolicious.org' => '/etc/tls/mojo.key'}
|
||||
|
||||
Path to the TLS key file, defaults to a built-in test key on the server-side.
|
||||
|
||||
=item tls_protocols
|
||||
|
||||
tls_protocols => ['foo', 'bar']
|
||||
|
||||
ALPN protocols to negotiate.
|
||||
|
||||
=item tls_verify
|
||||
|
||||
tls_verify => 0x00
|
||||
|
||||
TLS verification mode.
|
||||
|
||||
=item tls_version
|
||||
|
||||
tls_version => 'TLSv1_2'
|
||||
|
||||
TLS protocol version.
|
||||
|
||||
=back
|
||||
|
||||
=head2 new
|
||||
|
||||
my $tls = Mojo::IOLoop::TLS->new($handle);
|
||||
|
||||
Construct a new L<Mojo::IOLoop::Stream> object.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Mojolicious>, L<Mojolicious::Guides>, L<https://mojolicious.org>.
|
||||
|
||||
=cut
|
||||
27
database/perl/vendor/lib/Mojo/IOLoop/resources/server.crt
vendored
Normal file
27
database/perl/vendor/lib/Mojo/IOLoop/resources/server.crt
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEpDCCAowCCQD2f63fTFHflTANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls
|
||||
b2NhbGhvc3QwHhcNMTkwNjI4MjExNDI5WhcNMzkwNjIzMjExNDI5WjAUMRIwEAYD
|
||||
VQQDDAlsb2NhbGhvc3QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2
|
||||
lW4DOBswU1YJkekNF6c4b1VVcpOvtqsLHhTxUz538bffcvhI2vv+aCltG6g5mlvJ
|
||||
wo5NEu9l0ZG5TD9Ca4+WOOisVWrAI/i2YxXFQLOdjhKRBB1BvrOxSaFOuCXz9+cj
|
||||
VRo0R8Dq3k+1aSy93Yf+fq9pL7LFJaUOlxcU2FOM+HW9FYPeVbqCzYqpPJoaBnwN
|
||||
tQkQg7i8ufbeMS0bCcFpfTSV4pCgpWg1L9z6cVmBHtxc4MQv7rTTal+BF/iZDfDk
|
||||
qTNFJpuK7IGtSVB5laTcssYKGuY5QhN5BBPoGEMP3f0KiZmgMOUqwR6fMUiidacG
|
||||
iSIcgy05uOJyZ4oroqOzesz8nm2jH1eRPys2WLLFd801GKOZZE2LvNhCVzNIE0s1
|
||||
Rr8yyWBU9jbjQuxlTAtyMUKKOqG9qsfEnKOsl9T9/pFcpJjad3spwhQSWhWEPWca
|
||||
avw0CGVaGQ3nYmr9aJ9vpGBIiIsLQOPTzpOOPCDauMFpAPOoKnvIu+iz3Z8sUrMu
|
||||
Ld+aT/3yxpAtNkmVv5A951XyFt9WDXF7jZOMHdOSZPvvI/Yn7joJUzfP9d7TLKjz
|
||||
Xu+dzQnrAN3xuAXuy+jBpMIl3OPzwER6a8v7gUKRA/achNlIeOOmBdNn1cyHddcn
|
||||
k6wiaXHJlFsl8X6IjCs9ILwv6H+ZGq/5QNU1Nrv5kQIDAQABMA0GCSqGSIb3DQEB
|
||||
CwUAA4ICAQCo3xjINrsIQYvpVwVLpcO1p+oE5NV0ipA30JT+89Dn+vCejel9NzxT
|
||||
msuD9aQSiNaB4znlIDqux4bSKkcRXDGINiaGNIDNXOtO/787LXjUZlljPVVHoPWi
|
||||
hxgwc0nUHz3l/YvoXMKHI8blPkIhXl7xgKSuKQu05evjd//kpdHs1h+7b2vtCB0/
|
||||
VoYTX/NrIX5oMYCvHkZEypQbDJ3VeAkOhRJ4efGEuEskPRm0+eDSL7elas/65saZ
|
||||
l8vgkKDHZ9K0pd8JXc7EKmg3OBS22C5Lfhhy8AgqMa6R9p54oE4rH4yFaTe3BzFL
|
||||
xSA6HWqC987L2OCFr2LJ8hZpawDF1otukGHDou/5+4Q03EZz10RuZfzlCLO5DXzW
|
||||
Q28AtcCxz40n9o1giWzEj4LSYW4qsrpr5cNIhCqMzGPwp2OyS/TazPNJGoT8WKFU
|
||||
Kr+Y/prfkXAwgVkXlUSiu7ukiYslSM4BbYWHDxd75Iv4GzzhUirSuJKN95RglxR8
|
||||
XsJFlQwZ/tLvpflqb1Z8gPIV/4avtF+ybdx1AvqYViBQDf6GmLkM3p6Nwfj1LnCn
|
||||
kFhnqY80gyVjbZXvp9ClypExzgz55/o2ZIijznCaDkFSVBdv+aUIzl98IicZxHqP
|
||||
WREB+GMKmkaYrfKqlliQKdkXd2mXP/N8rv7SJEzHHpGRKBXsIAalrA==
|
||||
-----END CERTIFICATE-----
|
||||
52
database/perl/vendor/lib/Mojo/IOLoop/resources/server.key
vendored
Normal file
52
database/perl/vendor/lib/Mojo/IOLoop/resources/server.key
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
0N/URKPaZ8Z9V/c15kNhIZBgJhOoVg==
|
||||
-----END PRIVATE KEY-----
|
||||
Reference in New Issue
Block a user