2013年10月9日 星期三

在 HTTP header 放入特殊字元或文字

在正常的 HTTP header 中,依據 [1] 的回應,RFC 2616 文件中有以下的描述。
Words of *TEXT MAY contain characters from character sets other than ISO-8859-1 [22] only when encoded according to the rules of RFC 2047 [14].
因此 HTTP header 在不使用編碼的情況下,預設是以 ISO-8859-1 編碼。
而要放入 ISO-8859-1 不支援的字元時,必須使用 MIME 編碼才行。

MIME 編碼其實有很多函式庫都有實作 Encoder 和 Decoder,想要使用時可以直接找其中一個來使用。
例如在我的開發環境中,可以直接找到以下幾個 MIME 相關的工具:
com.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimeUtility
org.apache.tomcat.util.http.fileupload.util.mime.MimeUtility
org.apache.commons.fileupload.util.mime.MimeUtility
javax.mail.internet.MimeUtility

在 REST 那邊要做 Header 的擷取時,可以加入以下的內容做 MIME 解碼。
protected String getParamFromHeader (HttpHeaders headers, String headerName) {
  // Get the path which is going to be accessed.
  List<String> headerList = headers.getRequestHeader(headerName);
  
  String value = headerList.get(0);
  
  // Decode MIME encoding for supporting characters out of ISO-8859-1.
  try {
    value = javax.mail.internet.MimeUtility.decodeText(value);
  } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
  }
  return value;
}

而要做測試時,比如說使用瀏覽器的 RestClient plugin 來送 HTTP Request,可以透過以下的小程式做 MIME 的轉換。
import java.util.Scanner;

import javax.mail.internet.MimeUtility;

public class MimeMain {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    String text = null;
    
    do {
      System.out.print("Please input the string for MIME encoding: ");
      text = scanner.next();
      try {
        String encode = MimeUtility.encodeText(text);
        System.out.println("Encode '" + text + "' to " + encode);
        String decode = MimeUtility.decodeText(encode);
        System.out.println("Decode '" + text + "' to " + decode);
      } catch (Exception e) {
        e.printStackTrace();
      }
    } while(text.compareTo("exit") != 0);
    
    System.exit(0);
  }
}
小程式輸出的字串會是類似這樣:
Please input the string for MIME encoding: 輸入繁體中文
Encode '輸入繁體中文' to =?Big5?B?v+mkSsFjxemkpKTl?=
Decode '輸入繁體中文' to 輸入繁體中文
以上述的例子來說,就可以把 =?Big5?B?v+mkSsFjxemkpKTl?= 這串字放到 header 上
送到伺服器時,使用上面第一段程式碼就可以正確的解碼了。

參考資料:
1、HTTP header should use what character encoding?

沒有留言: