Net-API-Telegram
view release on metacpan or search on metacpan
lib/Net/API/Telegram.pm view on Meta::CPAN
## https://core.telegram.org/bots/webhooks
## while( my $client = $httpd->accept )
my $client;
my $loopback = Net::IP->new( '127.0.0.1' );
while( !$self->{_stop_daemon} && !$TIME_TO_DIE )
{
## Set when we receive signals
## last if( $self->{_stop_daemon} );
$client = $httpd->accept || do
{
$self->log( "Unable to accept queries on tcp port $self->{port}" );
## https://www.perlmonks.org/bare/?node_id=244384
next if( $! == EINTR );
warn( "Error on accept: $!\n" );
next;
};
$client->autoflush( 1 );
my $pid = POSIX::getpid();
if( !defined( $pid = fork() ) )
{
$self->log( "Cannot fork child process: $!" );
}
## Parent process
elsif( $pid )
{
$self->log( "Received an incoming connection, forking to $pid" );
$CHILDREN->{ $pid } = [Time::HiRes::gettimeofday()];
$pid = POSIX::getpid();
$client->close();
waitpid( $pid, 0 );
sleep( 0.1 );
}
## Child process == 0
else
{
## Close STDIN, STDOUT and STDERR
$in->close;
$out->close;
$err->close;
$log_io->close if( $log_io );
## Then, re-open them
$out->fdopen( fileno( STDOUT ), 'w' );
$out->binmode( ':utf8' );
$out->autoflush( 1 );
$err->fdopen( fileno( STDERR ), 'w' );
$err->binmode( ':utf8' );
$err->autoflush( 1 );
$in->fdopen( fileno( STDIN ), 'r' );
$in->binmode( ':utf8' );
$httpd->close();
$pid = POSIX::getpid();
$self->log( "Child answering on socket with pid $pid" );
## Processing here
my $req;
my $ip_check = 0;
REQUEST: while( $req = $client->get_request )
{
my $remote_addr;
if( $req->header( 'X-Forwarded-For' ) )
{
$remote_addr = Net::IP->new( $req->header( 'X-Forwarded-For' ) );
}
else
{
$remote_addr = Net::IP->new( Socket::inet_ntoa( $client->peeraddr ) );
}
## First Check the IP
if( !$ip_check )
{
$ip_check++;
my $ok_ips = $self->authorised_ips;
if( scalar( @$ok_ips ) )
{
$ip_is_authorised = 0;
if( $remote_addr->overlaps( $loopback ) == $Net::IP::IP_IDENTICAL )
{
$ip_is_authorised++;
}
else
{
IP_BLOCK_CHECKED: foreach my $block ( @$ok_ips )
{
## We found an overlap, we're good.
if( !( $remote_addr->overlaps( $block ) == $Net::IP::IP_NO_OVERLAP ) )
{
$ip_is_authorised++, last IP_BLOCK_CHECKED;
}
}
}
}
}
my $uri = $req->uri;
if( $uri->path ne $self->{webhook_path} )
{
$client->send_response( HTTP::Response->new( 404 ) );
last;
}
## We need to send back a reply to Telegram quicly or Telegram will issue a "read timeout" error and will re-send the message
$client->send_response( HTTP::Response->new( 200 ) );
my $res = $self->data2json( $req->decoded_content );
$client->close();
my $upd = $self->_response_to_object( 'Net::API::Telegram::Update', $res ) || do
{
$self->error( "Could not create a Net::API::Telegram::Update with following data: " . $self->dumper( $res ) );
$client->send_response( HTTP::Response->new( 500 ) );
next;
};
## Get the Webhook information for possible error
my $info = $self->getWebhookInfo;
if( length( $info->last_error_message ) )
{
my $err_time = $info->last_error_date;
$self->error( sprintf( "Warning only: webhook error occured on $err_time: %s", $info->last_error_message ) );
}
my $msg_epoch = $upd->message->date if( $upd->message );
if( !$self->{skip_past_messages} ||
( $check_messages_after && $msg_epoch && $msg_epoch > $check_messages_after ) ||
( $msg_epoch && $msg_epoch > $start ) )
{
( run in 0.583 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )