Die Behandlung von Dateinamen * -Parametern mit Leerzeichen über RFC 5987 führt zu '+' in Dateinamen

Ich habe einen älteren Code, mit dem ich es zu tun habe (also nein, ich kann nicht einfach eine URL mit einer verschlüsselten Dateinamenkomponente verwenden), mit der ein Benutzer eine Datei von unserer Website herunterladen kann. Da unsere Dateinamen oft in vielen verschiedenen Sprachen vorliegen, werden sie alle als UTF-8 gespeichert. Ich habe Code geschrieben, um die RFC5987-Konvertierung in einen richtigen Dateinamen * -Parameter durchzuführen. Dies funktioniert hervorragend, bis ich einen Dateinamen mit Nicht-ASCII-Zeichen habeund Leerzeichen. Gemäß RFC ist das Leerzeichen nicht Teil von attr_char und wird daher als% 20 codiert. Ich habe neue Versionen von Chrome sowie Firefox und sie konvertieren alle beim Download auf% 20 to +. Ich habe versucht, den Raum nicht zu kodieren und den kodierten Dateinamen in Anführungszeichen zu setzen und das gleiche Resultat zu erhalten. Ich habe die Antwort vom Server abgehört, um sicherzustellen, dass der Servlet-Container nicht mit meinen Headern verschmutzt ist und sie für mich korrekt aussehen. Der RFC enthält sogar Beispiele, die% 20 enthalten. Vermisse ich etwas oder haben alle diese Browser einen Fehler im Zusammenhang damit?

Vielen Dank im Voraus. Der Code, den ich benutze, um den Dateinamen zu kodieren, ist unten.

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

Aktualisieren

Hier ist ein Screenshot des Download-Dialogs, den ich für eine Datei mit chinesischen Zeichen mit Leerzeichen erhalte, wie in meinem Kommentar erwähnt.

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

Aktualisieren

Hier ist ein Screenshot des Download-Dialogs, den ich für eine Datei mit chinesischen Zeichen mit Leerzeichen erhalte, wie in meinem Kommentar erwähnt.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage