【问题标题】:Uploading an image with application/octet-stream from an UTF-8 webpage with Perl使用 Perl 从 UTF-8 网页上传带有 application/octet-stream 的图像
【发布时间】:2012-07-05 11:44:33
【问题描述】:

我有一个 Javascript/Ajax 文件上传器 (https://github.com/Valums-File-Uploader/file-uploader),它在 latin-1 编码的网页上运行良好。现在我尝试在 UTF-8 环境中使用它,但它失败了。
这是我的代码(我只需要变量中的图像,保存在其他地方完成):

sub parseMultiPart{
  use CGI;
  use IO::Handle;
  use Encode;

  $CGITempFile::TMPDIRECTORY = $ENV{ADFRAME_TMP_FILES};
  $CGI::POST_MAX=1024 * 1024 * 5;
  #$CGI::PARAM_UTF8=1;
  my $cgi = new CGI;
  foreach $key ($cgi ->param) {
    my $upload = $cgi->upload($key);
    if(defined $upload) {

       # THIS DOES NOTHING SINCE UPLOAD IS NOT DEFINED

        my $file=$cgi->param($key);
        binmode $upload;
        my $data;
        while (read($upload_file, $upload, 1024)) {
            $main::in{$key} .=  $data;
        }

        $main::inct{$key} = $cgi->uploadInfo($file)->{'Content-Type'};
    }
    else {
        my @val = $cgi->param($key);

        # THIS DOES THE WORK
        if (scalar @val == 1) {
            $main::in{$key} = $val[0];
        }
        # /

        else {
            $main::in{$key} = \@val;  # save value as an array ref
        }
    }


}
}
1;

然后在下一步:

if (open (HI, ">$storePath/$filename")) {
        binmode HI;
        print HI $data;
        close(HI);
}

这里有几个问题:

  • CGI->upload() 不认为这是上传。我现在才注意到,因为它从来没有引起任何问题。
  • 使用multipart/formdata 会导致服务器中止并且不发送任何内容。
  • 像这样使用它,我会收到一条Wide character in print 消息。
  • 如果我encode $val[0] 不会收到消息,则生成的文件仍然损坏。
  • 如果我binmode $val[0] 我得到wide characters in print

有人可以帮忙吗?

谢谢,
托马斯

编辑:这里是“Follow TCP Stream”:


 POST /cgi-bin/adframe/upload/image_upload.html?ITEM_ID=1&CATEGORY=1_1&qqfile=button_logout.gif HTTP/1.1
 Host: productspecial
 Connection: keep-alive
 Content-Length: 583
 Origin: http://productspecial
 X-Mime-Type: image/gif
 X-Requested-With: XMLHttpRequest
 X-File-Name: button_logout.gif
 User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.47 Safari/536.11
 Content-Type: application/octet-stream
 Accept: */*
 Referer: http://productspecial/cgi-bin/adframe/online_produktdatenbank/1_komplettbikes/1_1_fullsuspension/1_1_fullsuspension.html?ITEM_ID=1&id=134149338812700131663
 Accept-Encoding: gzip,deflate,sdch
 Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

 GIF89aD......................................................................................................!.......,....D........ud...Y.*y....qJ....8.....6..[..rh,....ez..lI.q.D....&........n.....B.....>..L..u.............$...........}..............................}..}........................}....}...}.........}...................}...4h.............A...H.(P.....q..qB....<.8.CI..I..4y..H..^Z..kB...=t.S...>......(J.D{*U*R.@z..R...@0.
.>.. k@
...@.....g..m%....p.V.K.n].t..........I.,A0a....^l......
n...a..+..........V....p.T.FMa5j..N..M.....s......
.y.........+_..A....K.N.....;HTTP/1.1 200 OK
Date: Thu, 05 Jul 2012 13:32:09 GMT
Server: Apache/2.2.20 (Ubuntu)
Cache-Control: no-cache
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 104
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8

.............MNN-..*)*M.I..I.R.O.-...MLO-./J,.wqus....+.KW.)-..R..utw.7.C..4SKsSK...4u...*..5...~.
.Y...

【问题讨论】:

  • 查看 HTTP 流量很有用,请捕获小图像的上传并显示完整的 POST 请求:使用 Firefox Firebug、Opera Dragonfly 的浏览器网络面板 (ctrl+shift+i) , Chromium Web 检查员。或者,使用 Wireshark,完成捕获,在顶部附近的组合框中过滤表达式 http,选择开始上传的数据包,菜单分析 → 跟踪 TCP 流并复制/粘贴文本表示。
  • @daxim - 刚刚发布了 Wireshark 的输出

标签: ajax perl file-upload utf-8


【解决方案1】:

您的 Content-Type 不是用于 CGI->上传的,来自 CGI 文档

如果 POST 数据的类型不是 application/x-www-form-urlencoded 或 multipart/form-data,那么POSTed的数据不会被处理,而是 而是在名为 POSTDATA 的参数中按原样返回。检索 它,使用这样的代码:

   my $data = $query->param('POSTDATA');

更新:这是针对 CGI.pm-3.59 的补丁,以避免 PUTDATA/POSTDATA 损坏

它还提供了 PUTDATA/POSTDATA 方便的方法来代替 param 使用

diff -ruN CGI.pm-3.59-orig/lib/CGI.pm CGI.pm-3.59/lib/CGI.pm
--- CGI.pm-3.59-orig/lib/CGI.pm 2011-12-30 05:31:41.000000000 -0800
+++ CGI.pm-3.59/lib/CGI.pm  2012-07-25 05:08:19.656250000 -0700
@@ -20,7 +20,7 @@

 # The revision is no longer being updated since moving to git. 
 $CGI::revision = '$Id: CGI.pm,v 1.266 2009/07/30 16:32:34 lstein Exp $';
-$CGI::VERSION='3.59';
+$CGI::VERSION='3.5901';

 # HARD-CODED LOCATION FOR FILE UPLOAD TEMPORARY FILES.
 # UNCOMMENT THIS ONLY IF YOU KNOW WHAT YOU'RE DOING.
@@ -457,8 +457,12 @@
     my @result = @{$self->{param}{$name}};

     if ($PARAM_UTF8) {
-      eval "require Encode; 1;" unless Encode->can('decode'); # bring in these functions
-      @result = map {ref $_ ? $_ : $self->_decode_utf8($_) } @result;
+      if( $name eq 'PUTDATA' or $name eq 'POSTDATA' ){
+        warn "skip decoding utf8 for special param $name\n" if DEBUG;
+      } else {
+        eval "require Encode; 1;" unless Encode->can('decode'); # bring in these functions
+        @result = map {ref $_ ? $_ : $self->_decode_utf8($_) } @result;
+      }
     }

     return wantarray ?  @result : $result[0];
@@ -692,7 +696,7 @@
         && defined($ENV{'CONTENT_TYPE'})
         && $ENV{'CONTENT_TYPE'} !~ m|^application/x-www-form-urlencoded|
    && $ENV{'CONTENT_TYPE'} !~ m|^multipart/form-data| ) {
-       my($param) = $meth . 'DATA' ;
+       my($param) = $meth . 'DATA' ; # POSTDATA/PUTDATA
        $self->add_parameter($param) ;
        push (@{$self->{param}{$param}},$query_string);
        undef $query_string ;
@@ -985,6 +989,14 @@

 %SUBS = (

+'PUTDATA'=> <<'END_OF_FUNC',
+sub PUTDATA   { local $CGI::PARAM_UTF8=0; shift()->param('PUTDATA', @_)  }
+END_OF_FUNC
+
+'POSTDATA'=> <<'END_OF_FUNC',
+sub POSTDATA  { local $CGI::PARAM_UTF8=0; shift()->param('POSTDATA', @_) }
+END_OF_FUNC
+
 'URL_ENCODED'=> <<'END_OF_FUNC',
 sub URL_ENCODED { 'application/x-www-form-urlencoded'; }
 END_OF_FUNC

【讨论】:

  • 谢谢@obmib。我的问题是,这些数据在来自 UTF-8 编码页面时已损坏。
  • 如果你避免使用 $CGI::PARAM_UTF8=1;如果你使用 $CGI::PARAM_UTF8=0;那么数据不会被破坏,尽管 CGI.pm 确实应该拒绝破坏 POSTDATA
猜你喜欢
  • 2012-04-16
  • 2015-02-17
  • 2020-03-30
  • 2014-06-08
  • 2019-06-22
  • 2019-10-16
  • 2013-08-25
  • 2017-09-02
  • 2012-03-31
相关资源
最近更新 更多