解析multipart/form-data中content-disposition头部的文件名

12
根据RFC,在multipart/form-data的content-disposition头部中,filename字段作为HTTP quoted string参数接收 - 即在引号之间的字符串,其中字符 '\' 可以转义任何其他ascii字符。
问题在于,Web浏览器并不遵循这一规定。
IE6发送:
Content-Disposition: form-data; name="file"; filename="z:\tmp\test.txt"

与预期不同

Content-Disposition: form-data; name="file"; filename="z:\\tmp\\test.txt"
应该按照规则解析为z:tmptest.txt,而不是z:\tmp\test.txt

例如Firefox、Konqueror和Chrome不会转义引号(")字符:

Content-Disposition: form-data; name="file"; filename=""test".txt"

与期望的不同

Content-Disposition: form-data; name="file"; filename="\"test\".txt"

那么...你会如何处理这个问题呢?

有人有想法吗?

2个回答

5
尽管这是一个旧的主题,但我为那些可能感兴趣的人添加了以下Java解决方案。
// import com.sun.xml.internal.messaging.saaj.packaging.mime.internet.*;

    try {
        ContentDisposition contentDisposition = new ContentDisposition("attachment; filename=\"myfile.log\"; filename*=UTF-8''myfile.log");
        System.out.println(contentDisposition.getParameter("filename"));
    } catch (ParseException e) {
        e.printStackTrace();
    }

由于问题并不特定于Java,解释这如何解决问题将会很有用。 - Nisse Engström
1
同意。在寻找相同问题的过程中,我甚至发现了一个讨论正则表达式模式的线程(https://dev59.com/gYXca4cB1Zd3GeqPLaaM#27226712)。将此解决方案添加进来,因为它可能对在同一情境下有类似问题的人有所帮助。人们只需要用适当的关键词谷歌搜索,就可以找到这里,如果他们碰巧是Java开发者,可能会觉得有用。 - Pavan Kumar
@PavanKumar 完全同意,考虑到问题没有提到Java,这应该是一个与语言无关的解决方案。但正如我经常说的那样,如果有选择的话,始终使用一个定义明确的库来进行解析 - Krusty the Clown

2

你需要解析这个文件名的原因是什么?

至少有一件事是一致的,那就是头部的filename部分以双引号结尾,所以你只需要读取在filename="和最后一个"之间的所有内容。

然后,除非你认为用户上传带有制表符的文件名的可能性特别大,否则你可以将除\\\"\"之外的任何反斜杠视为字面上的反斜杠。 :)


4
你需要解析文件名吗?-- 是的,我想知道文件名。至少有一件事是一致的,就是头部的文件名部分以双引号结尾。但文件名和名称字段不应按照特定的顺序出现,因此假设文件名以最后一个引号结尾是一个坏主意。 - Artyom
要 ≠ 需要。;) 好的,所以你至少可以保证它将以 " 结束或者以 "; 结束 -- 由于这种不一致性,你必须做出一些让步,比如依赖于用户不会在文件名中间放置 "; :) 或者,您是否使用支持为您解析此属性的最佳努力的Web框架? - Christopher Orr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接