简体   繁体   English

使用Perl提供图片会显示错误的内容长度(在Chrome中为net :: ERR_CONTENT_LENGTH_MISMATCH)

[英]Serving Image with Perl prints wrong Content-Length (Gives net::ERR_CONTENT_LENGTH_MISMATCH in Chrome)

Activeperl 5.16 + Windows environment. Activeperl 5.16 + Windows环境。

Windows machine: Windows机器:

Summary of my perl5 (revision 5 version 16 subversion 3) configuration: 我的perl5(修订版5,版本16,版本3)的摘要:

Linux machine: Linux机器:

Summary of my perl5 (revision 5 version 14 subversion 2) configuration: 我的perl5(修订版5,版本14,版本2)的摘要:

Doesn't occur on Linux based at all with the same code. 完全不会在具有相同代码的Linux上发生。

Here's my code that fetches a weather gif image, and does some magic (serving from cached directory for failover support in case internet dies or remote server does a radar update in the middle of a fetch, going offline) 这是我的代码,获取天气gif图像,并做了一些魔术处理(从高速缓存的目录中提供故障转移支持,以防Internet中断或远程服务器在获取过程中进行雷达更新,然后脱机)

sub get_map
{
    my $whichImage = $_[0];

    my $ua = LWP::UserAgent->new;
    my $cache_file      = $GLOB{'cache_mapA'};          # tempdata file path
    my $cache_file_age  = 100000;                       # this is used to determine if we have to get fresh data from the ems site will hold the tempdata file age in seconds 
    my $data            = '';                           # initializing empty data variable to enable later check for empty variable
    my $cache_time      = $GLOB{'cache_timeMap'};       # Max age of the temdata file in seconds
    my $useCached       = 0;
    my $url             = $GLOB{'mapAurl'};

    if( $whichImage eq "B" )
    {
        $cache_file     = $GLOB{'cache_mapB'};
        $url            = $GLOB{'mapBurl'};
    }

    if ( -s $cache_file )   # test existence of the tempdata file - if it has a size it exists
    {
        my $mtime           = ( stat $cache_file )[9];  # get the Unix time of the last change (in seconds)
        my $current_time    = time;                     # get the current Unix time (in  seconds)
        $cache_file_age     = $current_time - $mtime;       # get the age of the tempdata fileim seconds!       
    }

    if( $cache_file_age > $cache_time ) # check if we have to query the ems server 
    {
        my $response = $ua->get($url);

        if ($response->is_success) # checking if we were able to get the website
        {
            $data = $response->decoded_content( charset => 'none' );
            open my $filehandle , '>' , $cache_file or die 'Horribly';  
            binmode $filehandle;
            print $filehandle $data;
            close $filehandle;
        }
    }

    my $file = $cache_file;
    my $length = -s $file;

    print "Content-type: image/gif\n";
    print "Content-length: $length \n\n";

    binmode STDOUT;

    open (FH,'<', $file) || die "Could not open $file: $!";
    my $buffer = "";

    while (read(FH, $buffer, 10240)) 
    {
        print $buffer;
    }
    close(FH);
}

cache_mapA points to tmp/map.A.gif and cache cache_mapA指向tmp / map.A.gif和缓存

Going to http://mywebserver.com/whatever.cgi?type=mapA gives a corrupted gif file that shows net::ERR_CONTENT_LENGTH_MISMATCH in Google Chrome's debugger. 转到http://mywebserver.com/whatever.cgi?type=mapA会给出损坏的gif文件,该文件在Google Chrome浏览器的调试器中显示net :: ERR_CONTENT_LENGTH_MISMATCH。

Going to http://mywebserver.com/tmp/map.A.gif works fine in a browser. 转到http://mywebserver.com/tmp/map.A.gif在浏览器中可以正常工作。

Tried switching server software on my test box, Apache and LightTPD both show this behavior. 在我的测试箱上尝试过的交换服务器软件Apache和LightTPD都显示了此行为。

I'm out of ideas since this works perfectly fine on non Windows based machine. 我没有想法,因为这在非基于Windows的计算机上可以很好地工作。

It's possible there is an issue with this section but it looks fine to me: 这部分可能有问题,但对我来说看起来不错:

print "Content-type: image/gif\n";
print "Content-length: $length \n\n";

binmode STDOUT;

open (FH,'<', $file) || die "Could not open $file: $!";
my $buffer = "";

while (read(FH, $buffer, 10240)) 
{
    print $buffer;
}
close(FH);

Help! 救命!

You did binmode STDOUT but not binmode FH . 您执行了binmode STDOUT ,但未执行binmode FH Windows Perl opens files with :crlf enabled by default; Windows Perl将打开默认情况下启用:crlf文件; Unix Perl does not. Unix Perl没有。

The more modern technique would be open (FH,'<:raw', $file) instead of using a separate call to binmode . 更现代的技术将是open (FH,'<:raw', $file)而不是使用对binmode的单独调用。

If the image displays in other browsers, then the corruption for that particular image is probably minor enough that it doesn't prevent decoding. 如果该图像在其他浏览器中显示,则该特定图像的损坏可能很小,无法阻止解码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM