Ho un codice legacy con cui ho a che fare (quindi non posso usare solo un URL con un componente di nome file codificato) che consente a un utente di scarica un file dal nostro sito web. Poiché i nostri nomi di file sono spesso in molte lingue diverse, sono tutti memorizzati come UTF-8. Ho scritto un codice per gestire la conversione RFC5987 in un parametro filename * appropriato. Funziona perfettamente finché non ho un nome file con caratteri non ASCII e spazi. Per RFC, il carattere dello spazio non fa parte di attr_char quindi viene codificato come% 20. Ho nuove versioni di Chrome e Firefox e tutte si convertono in% 20 in + al download. Ho provato a non codificare lo spazio ea inserire il nome file codificato tra virgolette e ottenere lo stesso risultato. Ho annusato la risposta proveniente dal server per verificare che il contenitore della servlet non stesse masticando con le mie intestazioni e mi sembrano corretti. La RFC ha anche esempi che contengono% 20. Mi manca qualcosa o tutti questi browser hanno un bug relativo a questo?gestione del nome file * parametri con spazi tramite RFC 5987 risultati in '+' nei nomi dei file
Molte grazie in anticipo. Il codice che uso per codificare il nome file è sotto.
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();
}
Aggiornamento
Ecco uno screenshot della finestra di scaricare ottengo un file con i caratteri cinesi con spazi come indicato nel mio commento.
Ecco un'intestazione campione che causa il problema: Content Disposition: attachment; nome file * = UTF-8''Museum% 20% 5A% 69% 86.jpg –
Vedere http://greenbytes.de/tech/tc2231/#attwithquotedsemicolon - che il test case ha uno spazio in una stringa tra virgolette e viene visualizzato lavorare in Firefox. Stiamo testando cose diverse? –
Sembra qualcos'altro. Quel test controlla il punto e virgola all'interno di una stringa quotata. Il mio problema è che ho un nome di file con caratteri cinesi e spazi, quindi sto usando il nome del file * e, in forma non indicata, dato che ho letto alcuni documenti che raccomandavano di non usare le virgolette con% escape. Con l'esempio del mio commento sopra i caratteri cinesi sono riconosciuti e convertiti correttamente, ma% 20 viene mappato su +. –