通过RFC文件名中处理与空格的文件名* 5987个的参数结果“+”(handling filenam

2019-07-30 05:38发布

我有我处理一些遗留代码(所以没有我不能只用带编码的文件名部分的URL),允许用户从我们的网站下载的文件。 由于我们的文件名是经常在许多不同的语言,他们都被存储为UTF-8。 我写了一些代码来处理RFC5987转换到一个适当的文件名*参数。 直到我有非ASCII字符空格的文件名这个伟大的工程。 每RFC,所以它被编码为%20的空格字符不是attr_char的一部分。 我有Chrome浏览器的新版本,以及Firefox和他们都转换到%20 +上下载。 我试图不编码的空间,并把在引号的编码的文件名,并得到同样的结果。 我也嗅到来自服务器,以验证该servlet容器不符合我的头摆弄它们看起来正确的给我答复。 该RFC甚至有包含20%的实例。 难道我失去了一些东西,或者做所有这些浏览器都与此相关的一个错误?

提前谢谢了。 我使用的编码文件名中的代码如下。

彼得

public static boolean bcsrch(final char[] chars, final char c) {
    final int len = chars.length;
    int base = 0;
    int last = len - 1; /* Last element in table */
    int p;

    while (last >= base) {
        p = base + ((last - base) >> 1);

        if (c == chars[p])
            return true; /* Key found */
        else if (c < chars[p])
            last = p - 1;
        else
            base = p + 1;
    }

    return false; /* Key not found */
}

public static String rfc5987_encode(final String s) {
    final int len = s.length();
    final StringBuilder sb = new StringBuilder(len << 1);
    final char[] digits = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    final char[] attr_char = {'!','#','$','&','\'','+','-','.','0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','^','_','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','|', '~'};
    for (int i = 0; i < len; ++i) {
        final char c = s.charAt(i);
        if (bcsrch(attr_char, c))
            sb.append(c);
        else {
            final char[] encoded = {'%', 0, 0};
            encoded[1] = digits[0x0f & (c >>> 4)];
            encoded[2] = digits[c & 0x0f];
            sb.append(encoded);
        }
    }

    return sb.toString();
}

更新

这里是下载对话框,我得到了与中国文字与在我的评论中提到空格的文件的屏幕截图。

Answer 1:

因此,作为在朱利安的评论中指出,我犯了一个新手的Java错误,忘了做我的性格字节转换(因此我的编码字符的代码点,而不是人物的字节表示),因此编码完全不正确。 这显然是提到在RFC 5987.要求我将张贴更正的代码做转换。 一旦编码是正确的,文件名*参数是由浏览器正确识别和用于下载的文件名是正确的。

下面是对UTF-8字节字符串的操作校正逸出代码。 这是给我找麻烦的文件名,现在可以正确编码如下所示:

内容处置:附件; 文件名* = UTF-8''Museum%20%E5%8D%9A%E7%89%A9%E9%A6%86.jpg

public static String rfc5987_encode(final String s) throws UnsupportedEncodingException {
    final byte[] s_bytes = s.getBytes("UTF-8");
    final int len = s_bytes.length;
    final StringBuilder sb = new StringBuilder(len << 1);
    final char[] digits = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    final byte[] attr_char = {'!','#','$','&','+','-','.','0','1','2','3','4','5','6','7','8','9',           'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','^','_','`',                        'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','|', '~'};
    for (int i = 0; i < len; ++i) {
        final byte b = s_bytes[i];
        if (Arrays.binarySearch(attr_char, b) >= 0)
            sb.append((char) b);
        else {
            sb.append('%');
            sb.append(digits[0x0f & (b >>> 4)]);
            sb.append(digits[b & 0x0f]);
        }
    }

    return sb.toString();
}


文章来源: handling filename* parameters with spaces via RFC 5987 results in '+' in filenames