gpt4 book ai didi

java - 通过 RFC 5987 处理带空格的文件名*参数导致文件名中的 '+'

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:51:15 26 4
gpt4 key购买 nike

我有一些我正在处理的遗留代码(所以不,我不能只使用带有编码文件名组件的 URL),允许用户从我们的网站下载文件。由于我们的文件名通常使用多种不同的语言,因此它们都存储为 UTF-8。我编写了一些代码来处理 RFC5987 到正确文件名* 参数的转换。在我有一个包含非 ascii 字符 空格的文件名之前,这很好用。根据 RFC,空格字符不是 attr_char 的一部分,因此它被编码为 %20。我有新版本的 Chrome 和 Firefox,它们都在下载时转换为 %20 到 +。我试过不对空格进行编码并将编码后的文件名放在引号中并得到相同的结果。我嗅探了来自服务器的响应,以验证 servlet 容器没有破坏我的 header ,它们对我来说看起来是正确的。 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();
}

更新

这是我在评论中提到的带有空格的汉字文件的下载对话框的屏幕截图。

screen cap of download dialog

最佳答案

正如 Julian 在评论中指出的那样,我犯了一个新手 Java 错误,忘记了将字符转换为字节(因此我编码了字符的代码点而不是字符的字节表示),因此编码完全不正确。这在 RFC 5987 中作为一项要求被明确提及。我将发布更正的代码以进行转换。一旦编码正确,文件名*参数就会被浏览器正确识别,并且用于下载的文件名也是正确的。

下面是更正后的转义代码,它对字符串的 UTF-8 字节进行操作。给我带来麻烦的文件名,现在正确编码如下:

内容处理:附件;文件名*=UTF-8''博物馆%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();
}

关于java - 通过 RFC 5987 处理带空格的文件名*参数导致文件名中的 '+',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11302361/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com