Perl中非致命处理错误

Dem*_*ess 0 encryption error-handling perl cryptography

在我之前的问题中,建议我使用该模块Crypt::OpenSSL::RSA导出和发送RSA密钥.但是,我发现这个模块似乎无法处理非致命错误,因此只需发送格式错误的字符串(即不是RSA密钥),服务器程序在尝试使用创建新对象时就会崩溃它与消息:

server.pl第46行无法识别的密钥格式

第46行包含代码

$clients{$cur_client}->{pub_key}    = Crypt::OpenSSL::RSA->new_public_key($message) or do {
            server_log "Bad key exchange, dropping user $address:$port..."; 
            delete $clients{$cur_client};
            next;
        }; # Key exchange
Run Code Online (Sandbox Code Playgroud)

我该如何解决?

编辑:这是Github上完整代码的链接

Bor*_*din 6

您需要使用BLOCK形式eval来防止程序在引发异常时死亡.不幸的是,裸露的使用eval充满了尴尬的角落情况,最好使用Try::Tiny处理这些的模块

为了达到你的问题代码的目的,你会写这样的东西.显然,您必须为变量提供有用的数据

要注意这一点很重要的是trycatch子程序.这意味着你之后需要一个分号catch,而你不能next在内,catch因为你不能在子程序中做到这一点.您必须保留某种状态集,以便后续代码可以执行任何必要的操作,在这种情况下,我只检查是否$clients{$cur_client}仍然存在 - catch如果出现问题,它将被例程删除

同样值得解释的die是,$_catch例程中的字符串可用,因此您可以检查失败的原因.在这种情况下,catch期望只处理unrecognized key format错误,因此代码检查这确实是失败的原因.如果没有,那么它会发出另一个,die $_以反映发生了未处理的错误

use strict;
use warnings 'all';

use Crypt::OpenSSL::RSA;
use Try::Tiny;

my %clients = ( aa => {} );
my $message = 'xxx';
my ($address, $port) = qw/ 127.0.0.1 80 /;

for my $cur_client ( keys %clients ) {

    try {
        $clients{$cur_client}{pub_key} = Crypt::OpenSSL::RSA->new_public_key($message);
    }
    catch {
        if ( /unrecognized key format/ ) {
            server_log("Bad key exchange, dropping user $address:$port...");
            delete $clients{$cur_client};
        }
        else {
            die $!;
        }
    };

    next unless exists $clients{$cur_client};

    # More handling of $cur_client in the case that
    # the call to new_public_key succeeds
}

sub server_log {
    print "Logging: $_[0]\n";
}
Run Code Online (Sandbox Code Playgroud)