IO :: Socket: SSL sometimes adds a new line when printing on a socket

I have a method that sends a message to a remote SSL server. The class is embedded in the program, which can be called from the command line, or the program can be run as a daemon and can call the class method on demand. I use Net::Server::Forkto start the daemon:

package myserver;

use 5.10.1;
use strict;
use warnings;

use parent 'Net::Server::Fork';

myserver->run(
    'port'            => $main::config{'backend.ssl.host'} . '/ssl',
    'ipv'             => '*',
    'log_level'       => $main::config{'backend.loglevel'},
    'log_file'        => $main::config{'backend.logfile'},
    'pid_file'        => $main::config{'backend.pidfile'},
    'user'            => $main::config{'backend.user'},
    'group'           => $main::config{'backend.group'},
    'max_servers'     => $main::config{'backend.maxconnections'},
    'background'      => !$main::config{'backend.foreground'},
    'leave_children_open_on_hup' => 1,
    'allow'           => $main::config{'ip'},
    'reverse_lookups' => 1,
    'SSL_key_file'    => $main::config{'backend.ssl.key'},
    'SSL_cert_file'   => $main::config{'backend.ssl.crt'},
    'SSL_ca_file'     => $main::config{'backend.ssl.bundle'},
);

sub process_request {
    # call connect and sendframe if requested
};

The external communication class connects to IO::Socket::SSLand sends data, adding the packet length as a 4-byte header, and then sends the message as is:

package communicator;

use 5.10.1;
use strict;
use warnings;

use IO::Socket::SSL;

sub connect {
    my $self   = shift @_;
    my $server = shift @_;
    my @field    = split /\:/, $server;

    my $socket;

    $socket = IO::Socket::SSL->new(
        'PeerAddr' => $field[0],
        'PeerPort' => $field[1],
        'Blocking' => 1,
    );

    if ( $socket ) {
        binmode $socket;
    }
    else {
        # error handling
    };

    $self->{'SOCK'} = $socket;
};

sub sendframe {
    my $self = shift @_;
    my $msg  = shift @_;

    if ($self->{'SOCK'}) {
        my $length = pack("N", bytes($msg));
        ($self->{'SOCK'})->print($length);
        ($self->{'SOCK'})->print($msg);
    };
};

This works when invoked from the command line, but does not execute on execution Net::Server. I tried to register the content sent to the remote server, but the log files are identical for both approaches.

SSL- , Net::Server , . ,

[packet length in binary]Line 1
Line 2
--- [Received announced length + 4 bytes]

[packet length in binary]
Line 1
Line 2

--- [Received announced length + 6 bytes]

Net::Server. , .

, Net::Server IO::Socket::SSL, sendframe, , .

, communicator. IO::Socket::SSL , IO::Socket::SSL - , $socket->print.

, , , , .

- Debian 7 Perl 5.14, IO:: Socket:: SSL 2.020 Net:: Server 2.006

+4
1

print IO:: Socket:: SSL print , $\. perldoc perlvar:

  $\      The output record separator for the print operator.  
          If defined, this value is printed after the last of print's
          arguments.  Default is "undef".

undef , , - . , Net:: Server . , , ? , , ..

if ($self->{'SOCK'}) {
    local $\ = undef; ### make sure to disable side effects
    my $length = pack("N", bytes($msg));
    ($self->{'SOCK'})->print($length);
    ($self->{'SOCK'})->print($msg);
};
+3

Source: https://habr.com/ru/post/1653810/


All Articles