Lemonldap-NG-Common

 view release on metacpan or  search on metacpan

eg/llng-pubsub-server  view on Meta::CPAN

    my $log  = "$ip - - $date $msg -\n";
    if ( $accessLog eq 'STDERR' ) {
        print STDERR $log;
    }
    else {
        print $log;
    }
    debug "Request: $msg";
}

if ( $accessLog and $accessLog ne '-' and $accessLog ne 'STDERR' ) {
    debug "Access logs will be written into $accessLog\n";
    open STDOUT, '>>', $accessLog or die "Unable to write logs: $!";
    if ($daemon) {
        open STDERR, '>&', fileno(STDOUT) or die "Can't dup STDERR: $!";
        STDERR->autoflush(1);
    }
}

if ( $cert xor $key ) {
    die '--cert and --key must be used together';
}

unless ($token) {
    warning "No token given, this means that anybody can use this server"
      unless $quiet;
}

# 2. Create server

my @servers;
my $selector = IO::Select->new;
$addr = [0] unless @$addr;

foreach my $a (@$addr) {
    my $server;
    my $p;

    # IPv6 addresses with port
    if ( $a =~ s/^\s*\[($RE{net}{IPv6})\]:(\d+)\s*$/$1/ ) {
        $p = $2;
    }
    elsif ( $a =~ s/^\s*($RE{net}{IPv4}):(\d+)\s*$/$1/ ) {
        $p = $2;
    }
    elsif ( $a and $a !~ s/^\s*\[?($RE{net}{IPv4}|$RE{net}{IPv6})\]?\s*/$1/ ) {
        die qq'Malformed IP address "$a"';
    }
    else {
        $p = $port || ( $ENV{PUBSUB_PORT} || ( $cert ? 8443 : 8080 ) );
    }

    my %args = (
        ( $a ? ( LocalAddr => $a ) : () ),
        LocalPort => $p,
        Listen    => $maxWaitingConn,
        ReuseAddr => 1,
        ReusePort => 1,
    );
    if ($cert) {
        require IO::Socket::SSL;
        $server = IO::Socket::SSL->new(
            %args,
            SSL_cert_file => $cert,
            SSL_key_file  => $key,
            SSL_server    => 1,
        );
    }
    else {
        require IO::Socket::IP;
        $server = IO::Socket::IP->new( %args, Proto => 'tcp', );
    }

    die "Cannot create socket ("
      . ( $a ? "address: $a, " : '' )
      . "port: $p): $!"
      unless $server;

    debug 'Listening on ' . ( $a ? "$a:" : 'port ' ) . $p;
    $selector->add($server);
    push @servers, $server;
}

if ($group) {
    my $grp = getgrnam($group) or die "Can't change gid to $group";
    setgid($grp)               or die "setgid: $!";
}

if ($user) {
    my $uid = getpwnam($user) or die "Can't change uid to $user";
    setuid($uid)              or die "setuid: $!";
}

my $json = JSON->new->utf8;

# 3. Manage requests

my %clients;

while (1) {
    for my $sock ( $selector->can_read(0.1) ) {
        my ($server) = grep { $sock eq $_ } @servers;
        if ($server) {
            my $client = $server->accept or next;
            $client->autoflush(1);
            $selector->add($client);
        }
        else {
            my $fileno = fileno($sock);
            my $buf    = '';
            my $n      = sysread( $sock, $buf, 4096 );
            if ( !defined $n || $n == 0 ) {
                cleanupClient($sock);
                next;
            }

            # Known clients are subscribers, we can discard
            if ( exists $clients{$fileno} ) {
                my $frame = $clients{$fileno}->{frame};
                $frame->append($buf);
                while ( my $msg = $frame->next ) {



( run in 0.471 second using v1.01-cache-2.11-cpan-75ffa21a3d4 )