Back to moin

AttachFile

1. Reference

http://moinmo.in/HelpOnActions/AttachFile

2. 解决IE下载时的中文文件名称乱码

2.1. 解决办法

from MoinMoin import config, packages

# AttachFile.py line 820
        # TODO: fix the encoding here, plain 8 bit is not allowed according to the RFCs
        # There is no solution that is compatible to IE except stripping non-ascii chars
        # add by LiYan@20100525 fix chinese file name failed to save
        ua = request.http_user_agent
        if ua.find('MSIE')!=-1:
            filename_enc = filename.encode("GBK")
        else:
            filename_enc = filename.encode(config.charset)

# AttachFile.py line 827
        request.headers['Content-Disposition'] = content_dispo_string

2.2. 分析过程

通过学习MIME相关的规范,知道了服务器给定建议文件名的规范时RFC1806,但各种浏览器支持得并不是都很好。

目前发现,有些手机客户端的浏览器根本不支持,而IE对中文文件名支持的也不好。

相关的规范大约是这样的,RFC1341在HTTP头的Content-Type中定义了一个NAME字段用来建议打算写成文件的名称,但随后产生的RFC 1806在HTTP头中独立出一个Content-Disposition来定义文件名,并且废弃了RFC1341中的那个约定。

RFC 1341 also defined the use of a "NAME" parameter which gave a suggested file name to be used if the data were to be written to a file. This has been deprecated in anticipation of a separate Content-Disposition header field, to be defined in a subsequent RFC.

RFC 1341 - MIME (Multipurpose Internet Mail Extensions): Mechanisms for Specifying and Describing the Format of Internet Message Bodies

Read more: http://www.faqs.org/rfcs/rfc1341.html

7.4.1 The Application/Octet-Stream (primary) subtype 

The primary subtype of application, "octet-stream", may be used to indicate that a body contains binary data. The set of possible parameters includes, but is not limited to: 

NAME -- a suggested name for the binary data if stored as a file. 

TYPE -- the general type or category of binary data. This is intended as information for the human recipient rather than for any automatic processing. 

CONVERSIONS -- the set of operations that have been performed on the data before putting it in the mail (and before any Content-Transfer-Encoding that might have been applied). If multiple

Content-Type:  application/octet-stream;
                      name=foo.tar.Z; type=tar;
                      conversions="x-encrypt,x-compress"

RFC 1806 - Communicating Presentation Information in Internet Messages: The Content-Disposition Header

Read more: http://www.faqs.org/rfcs/rfc1806.html

Content-Type: image/jpeg 
Content-Disposition: attachment; filename=genome.jpeg 
Content-Description: a complete map of the human genome <jpeg data>

2.3. 调试

解决方法就是适配浏览器,改变文件名的编码方式,需要抓出UserAgent

AttachFile line 471
        request.write('<pre>' + request.__doc__ +'</pre>')
        
        # debug info
        request.write('<pre>' + '\n'.join(dir(request)) +'</pre>')

3. Howto Restrict Attach File Size

怎么控制上传文件的大小呢?

3.1. 解决方法

# AttachFile.py line 572
        # restrict upload file length
        #add by LiYan @2010/03/11
        limit = 1024*1024*300
        file_size = bytes
        if file_size>=limit:
            # get attached file name
                attach_dir = getAttachDir(request, pagename)
                fpath = os.path.join(attach_dir, target).encode(config.charset)

                os.remove(fpath)
                
                return _(u"reach file limit(300M)! your file size= %d" % file_size)

3.2. 分析过程

  1. 首先定位一下儿可能需要改的地方
    • 因为点上传对应的链接是?action=AttachFile,所以可以很方便的判定上传工作是一个叫AttachFile的Action,在我本地的地址是

      • $lib/python2.6/site-packages/MoinMoin/action/AttachFile.py
        
  2. 打开AttachFile.py,定位上传的地方:

    • def _do_upload(pagename, request):
      
  3. 找到上传的逻辑:
    • target, bytes = add_attachment(request, pagename, target, file_upload.stream, overwrite=overwrite)
      
      target是文件名
      bytes是文件大小
      
  4. 都在add_attachment了:
    • 呵呵,是直接把文件流存到本地了
  5. 所以,所谓的限制大小就是上传完了之后,如果文件超过大小了,就删掉
  6. 搞定

3.3. 调试

  1. 看看file_upload.stream里面能不能获得文件大小
    • AttachFile.py 568
          return _(', '.join(dir(file_upload.stream)))
      
  2. file_upload.content_length是0,呵呵

MainWiki: MoinHackingOnAttachFile (last edited 2010-05-24 19:21:46 by twotwo)