Tengo un código heredado al que me refiero (así que no puedo usar una URL con un componente de nombre de archivo codificado) que permita al usuario descarga un archivo desde nuestro sitio web. Dado que nuestros nombres de archivo a menudo están en muchos idiomas diferentes, todos están almacenados como UTF-8. Escribí un código para manejar la conversión de RFC5987 a un parámetro de nombre de archivo * adecuado. Esto funciona muy bien hasta que tenga un nombre de archivo con caracteres no ASCII y espacios. Por RFC, el carácter de espacio no es parte de attr_char por lo que se codifica como% 20. Tengo nuevas versiones de Chrome y de Firefox, y todas se están convirtiendo a% 20 en + en la descarga. Intenté no codificar el espacio y poner el nombre de archivo codificado entre comillas y obtener el mismo resultado. He olfateado la respuesta proveniente del servidor para verificar que el contenedor del servlet no se estaba volcando con mis encabezados y me parecen correctos. El RFC incluso tiene ejemplos que contienen% 20. ¿Me estoy perdiendo algo, o todos estos navegadores tienen un error relacionado con esto?manejo de nombre de archivo * parámetros con espacios a través de RFC 5987 resultados en '+' en nombres de archivo
Muchas gracias de antemano. El código que uso para codificar el nombre de archivo está debajo.
Peter
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();
}
actualización
Aquí está una captura de pantalla del diálogo de descarga que me pasa por un archivo con caracteres chinos con los espacios que se han mencionado en mi comentario.
Aquí es una cabecera de la muestra que está causando este problema: Content- Disposición: archivo adjunto; filename * = UTF-8''Museum% 20% 5A% 69% 86.jpg –
Ver http://greenbytes.de/tech/tc2231/#attwithquotedsemicolon - ese caso de prueba tiene un carácter de espacio en una cadena citada y aparece para trabajar en Firefox ¿Estamos probando cosas diferentes? –
Eso se parece a algo más. Esa prueba comprueba el punto y coma dentro de una cadena entrecomillada. Mi problema es que tengo un nombre de archivo con caracteres chinos, así como espacios, así que estoy usando el formulario de nombre de archivo *, y en el token no se cita desde que leí algunos documentos que recomendaban no utilizar comillas con% escapes. Con el ejemplo de mi comentario anterior, los caracteres chinos se reconocen y convierten correctamente, pero el% 20 se asigna a +. –