Perl

时间:2018-02-27 04:55:26

标签: perl

我最初的问题是making sure that my handling of utf8 is correct,我已经开始根据这些建议修改我的代码,但我仍然遇到问题。以下是对情况的更全面介绍。

一步一步:

  1. 我的服务收到一个发布到它的UTF-8文件。它分为父母和孩子。
  2. 孩子用open打开文件并阅读。
  3. 孩子对该数据进行了一些处理。
  4. 孩子用open打开一个新文件并将数据写入其中,然后退出。
  5. 父文件读取该文件,并将其作为HTTP响应返回。我们在PSGI服务器(Starman)中使用Plack :: Request。
  6. 我在服务开始时采用了以下编译指示:use open ":std", ":encoding(UTF-8)";

    我认为该服务实际上是基于测试成功返回UTF-8,即使在采用该pragma之后,我只是在日志记录中获得了广泛的字符堆栈跟踪(我认为它们只是警告)。

    此外,我的服务的一部分未明确配置为使用UTF-8是Plack :: Request。我不认为我提到的open pragma足以满足下面的堆栈跟踪。

    了解我的代码的重要一点是,它都是在回调服务器时返回的,类似于此处的第二个示例(这是PSGI规范的一部分):https://metacpan.org/pod/PSGI#Delayed-Response-and-Streaming-Body。意思是,我在顶部概述的所有5个步骤都发生在回调中。堆栈跟踪中的__ANON__方法可能是该回调。

    来自我的实际应用的堆栈跟踪中的行是Plack::Util::Prototype::AUTOLOAD('Plack::Util::Prototype=HASH(0x195c200) ... called at /app/app.psgi line 114。代码中与该行对应的行是while ( my $line = <$fh>){

    但疯狂的是,堆栈跟踪的第一行是syswrite,但堆栈跟踪的第4行是读取(正如我在前一段中提到的)。写入可能触发广泛的字符警告是有道理的,但我不明白为什么它会在读取时发生。也许我只是不理解堆栈跟踪。

    所以基本上,我需要以某种方式告诉包含服务器(Starman)使用UTF-8。但由于它使用的是syswrite而我无法直接控制该代码,因此可能很难。

    这是我的代码的精简副本,我认为它显示了重要的部分。如果您想了解更多信息,请与我们联系。存在于$ app中的子例程在POST请求进入时执行,并将回调返回给服务器。 $ writer是我们告诉PSGI我们想要HTTP响应的方式,我认为它是堆栈跟踪中的第一个东西:

    use open ":std", ":encoding(UTF-8)";
    
    my $app = sub {
        my $env          = shift;
        my $req          = Plack::Request->new($env);
        my @upload = $req->upload('input_file');
    
        #This is the callback returned to the server
        return sub {
            my $responder = shift;
            my $writer = $responder->([ 200, [ 'Content-Type', 'text/plain' ]]);
            my $pass_data = '/tmp/pass_data_' . utilities::randomString(10);
            my $pid = fork // die "Can't fork: $!";
            if ($pid){
                #parent
                ... wait for child
                #child is done, read the file it wrote
                open(my $fh, '<', $pass_data) or die "err msg 1";
                while ( my $line = <$fh>){
                    $writer->write($line);
                }
                close $fh;
                $writer->close();
            }
            else {
                #child
                open(my $fh, '>', $pass_data) or die "err msg 2";
    
                #get the path to the file that was posted to us
                my $infile = $upload[0]->path();
    
                open(my $in, '<', $infile) or die "err msg 3";
                my $result = some_processing(join('', <$in>));
                close $in;                
    
                print $fh $result;
                close $fh;
    
                exit;
            }
        }
    }
    

    这是堆栈跟踪:

    Wide character in syswrite at /app/local/lib/perl5/Starman/Server.pm line 566, <> line 4.
        Starman::Server::_syswrite('Net::Server::Proto::TCP=GLOB(0x29093d8)', 'SCALAR(0x2909ee8)') called at /app/local/lib/perl5/Starman/Server.pm line 551
        Starman::Server::__ANON__('【 表 纸 】
    ') called at /app/local/lib/perl5/Plack/Util.pm line 358
        Plack::Util::Prototype::AUTOLOAD('Plack::Util::Prototype=HASH(0x195c200)', '【 表 纸 】
    ') called at /app/app.psgi line 114
        Plack::Sandbox::_2fapp_2fapp_2epsgi::__ANON__('CODE(0x2954628)') called at /app/local/lib/perl5/Starman/Server.pm line 197
        Starman::Server::dispatch_request('Starman::Server=HASH(0x1aa56f8)', 'HASH(0x29098d0)') called at /app/local/lib/perl5/Starman/Server.pm line 298
    

0 个答案:

没有答案