2012-07-02 28 views
6

मेरे पास कुछ विरासत कोड है जिसके साथ मैं काम कर रहा हूं (इसलिए नहीं, मैं केवल एक एन्कोडेड फ़ाइल नाम घटक के साथ एक यूआरएल का उपयोग नहीं कर सकता) जो उपयोगकर्ता को हमारी वेबसाइट से एक फाइल डाउनलोड करें। चूंकि हमारे फ़ाइल नाम अक्सर कई अलग-अलग भाषाओं में होते हैं, इसलिए वे सभी यूटीएफ -8 के रूप में संग्रहीत होते हैं। मैंने RFC5987 रूपांतरण को उचित फ़ाइल नाम * पैरामीटर में संभालने के लिए कुछ कोड लिखा था। यह तब तक बढ़िया काम करता है जब तक मेरे पास non-ascii वर्ण और रिक्त स्थान के साथ फ़ाइल नाम नहीं है। प्रति आरएफसी, अंतरिक्ष चरित्र attr_char का हिस्सा नहीं है, इसलिए यह% 20 के रूप में एन्कोड किया जाता है। मेरे पास क्रोम के साथ-साथ फ़ायरफ़ॉक्स के नए संस्करण हैं और वे सभी डाउनलोड पर% 20 से + में परिवर्तित हो रहे हैं। मैंने अंतरिक्ष को एन्कोड करने और एन्कोडेड फ़ाइल नाम उद्धरणों में डालने की कोशिश नहीं की है और एक ही परिणाम प्राप्त किया है। मैंने सर्वर से आने वाली प्रतिक्रिया को छीन लिया है ताकि यह सत्यापित किया जा सके कि सर्वलेट कंटेनर मेरे शीर्षकों के साथ नहीं मिल रहा था और वे मेरे लिए सही लग रहे थे। आरएफसी में ऐसे उदाहरण भी हैं जिनमें% 20 शामिल हैं। क्या मुझे कुछ याद आ रही है, या इन सभी ब्राउज़रों से संबंधित एक बग है?आरएफसी 5 9 87 के माध्यम से रिक्त स्थान के साथ पैरामीटर के साथ पैरामीटर * फाइलों में '+' में परिणाम

अग्रिम में बहुत धन्यवाद। फ़ाइल नाम को एन्कोड करने के लिए मैं जिस कोड का उपयोग करता हूं वह नीचे है।

पीटर

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

+0

यहां एक नमूना हैडर है कि इस समस्या पैदा कर रहा है: सामग्री- स्वभाव: लगाव; फ़ाइल नाम * = यूटीएफ -8 'संग्रहालय% 20% 5 ए% 69% 86.jpg –

+0

http://greenbytes.de/tech/tc2231/#attwithquotedsemicolon देखें - उस परीक्षण मामले में उद्धृत-स्ट्रिंग में एक स्पेस कैरेक्टर है और प्रकट होता है फ़ायरफ़ॉक्स में काम करने के लिए। क्या हम अलग-अलग चीजों का परीक्षण कर रहे हैं? –

+0

ऐसा कुछ और दिखता है। वह टेस्ट अर्धविराम के लिए एक उद्धृत स्ट्रिंग के भीतर जांचता है। मेरी समस्या यह है कि मेरे पास चीनी वर्णों के साथ-साथ रिक्त स्थान के साथ एक फ़ाइल नाम है, इसलिए मैं फ़ाइल नाम * फॉर्म का उपयोग कर रहा हूं, और टोकन में उद्धृत रूप में नहीं है क्योंकि मैंने कुछ दस्तावेज़ पढ़े हैं जो% escapes के साथ उद्धरणों का उपयोग नहीं करने की अनुशंसा करते हैं। चीनी वर्णों के ऊपर मेरी टिप्पणी के उदाहरण के साथ पहचाने जाते हैं और सही तरीके से परिवर्तित होते हैं, लेकिन% 20 को + पर मैप किया जा रहा है। –

उत्तर

10

तो जैसा कि जूलियन टिप्पणी में कहा, मैं एकदम शुरुआत में जावा त्रुटि इसलिए बनाया है और बाइट रूपांतरण करने के लिए अपने चरित्र करना भूल (इस प्रकार मैं चरित्र की बाइट प्रतिनिधित्व के बजाय चरित्र की कोडपॉइंट इनकोडिंग), एन्कोडिंग पूरी तरह से गलत था। आरएफसी 5 9 87 में इसकी आवश्यकता के रूप में स्पष्ट रूप से उल्लेख किया गया है। मैं रूपांतरण करने के लिए सही कोड पोस्ट करूँगा। एक बार एन्कोडिंग सही हो जाने पर, फ़ाइल नाम * पैरामीटर ब्राउज़र द्वारा ठीक से पहचाना जाता है और डाउनलोड के लिए उपयोग किए गए फ़ाइल नाम सही है।

नीचे सही एस्केपिंग कोड है जो स्ट्रिंग के यूटीएफ -8 बाइट्स पर संचालित होता है। फ़ाइल नाम जो मुझे परेशानी दे रहा था, अब ठीक तरह से एन्कोड किया गया इस तरह दिखता है:

सामग्री-विस्थापन: लगाव; फ़ाइल नाम * = UTF-8''Museum% से 20% E5% 8D% 9 ए% E7% 89% A9% E9% ए 6% 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(); 
} 
+0

यह इंगित करना चाहते हैं कि चरित्र '' 'rfc5987 की अनुमत सूची में नहीं है। – Gedrox

+0

.. लेकिन चरित्र '\' '(गंभीर उच्चारण प्रतीक, बैकटिक) है। जवाब संपादित किया है। – Gedrox