el manejo de los parámetros de nombre de archivo * con espacios a través de RFC 5987 da como resultado '+' en los nombres de archivo

Tengo un código heredado con el que estoy tratando (por lo que no, no puedo simplemente usar una URL con un componente de nombre de archivo codificado) que permita a un usuario descargar un archivo de nuestro sitio web. Como los nombres de nuestros archivos suelen estar en muchos idiomas diferentes, todos se almacenan como UTF-8. Escribí algo de código para manejar la conversión RFC5987 a un parámetro de nombre de archivo * correcto. Esto funciona muy bien hasta que tenga un nombre de archivo con caracteres no-asciiy 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 a + en la descarga. He intentado no codificar el espacio y poner el nombre del 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 juntando 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?

Muchas gracias de antemano. El código que utilizo para codificar el nombre de archivo está abajo.

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 = {'!','#','

Actualizar

Aquí hay una captura de pantalla del cuadro de diálogo de descarga que obtengo para un archivo con caracteres chinos con espacios como se menciona en mi comentario.

,'&','\'','+','-','.','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(); }

Actualizar

Aquí hay una captura de pantalla del cuadro de diálogo de descarga que obtengo para un archivo con caracteres chinos con espacios como se menciona en mi comentario.

Respuestas a la pregunta(1)

Su respuesta a la pregunta