웹서비스와 utf-8

한국의 웹사이트들을 돌아다니다 보면 “파일이 보이지 않는 경우 ‘URL 을 항상 UTF-8 로 보냄’ 옵션을 꺼주시기 바랍니다.” 라는 메시지를 쉽게 볼 수 있다. 하지만 소위 웹프로그래머라는 사람들 중 저런 문제가 생기는 이유에 대해 관심 있는 사람들은 별로 없는 듯 싶다.

URIs

Internationalization of URIs is important because URIs may contain all kinds of information from all kinds of protocols or formats that use characters beyond ASCII. The URI syntax defined in RFC 2396 currently only allows as subset of ASCII, about 60 characters. It also defines a way to encode arbitrary bytes into URI characters: a % followed by two hexadecimal digits (%HH-escaping). However, for historical reasons, it does not define how arbitrary characters are encoded into bytes before using %HH-escaping.

Among various solutions discussed a few years ago, the use of UTF-8 as the preferred character encoding for URIs was judged best. This is in line with the IRI-to-URI conversion, which uses encoding as UTF-8 and then escaping with %hh:

Guidelines for new URL Schemes, RFC 2718, proposes to base URIs on UTF-8 unless there is some compelling reason for a particular scheme to do otherwise.
URI schemes or components already based on UTF-8:
URN syntax : RFC 2141 (syntactically, URNs look like a URI scheme, but semantically, they are not)
IMAP: RFC 2192 (the IMAP protocol uses a modified version of UTF-7, but its URIs use UTF-8)
FTP ( RFC 2640 uses UTF-8, but tolerates legacy encodings)
XPointer (W3C Working Draft)

From: http://www.w3.org/International/O-URL-and-ident

위에서 보다시피 RFC2718 에서는 URL 을 UTF-8 로 보내라고 제안하고 있으며, FTP 관련해서는 RFC2640 에서 path name 을 UTF-8 로 넘겨주라고 되어 있다. 그러므로 Internet Explore 에서 ‘URL 을 항상 UTF-8 로 보냄’ 을 해제시키는 것은 올바른 해결법이 아니라고 생각된다.

현재 까지의 대부분의 ftp client 에서 i18n 관련해서 별다른 고려를 하지 않고 있었기 때문에 path name 을 client 의 legacy charset 을 이용해서 넘겨주도록 구현되어 있다. 그렇기 때문에 (한글 기준으로) euc-kr 로 된 path name 이 사용되어 왔고 결국 server 측에도 euc-kr 로 저장되고 있는 실정이다.

그런 상황이다 보니 위의 권고안 대로 URL 을 UTF-8 로 넘겨주는 경우 실제 파일을 찾지 못하고 ‘404 Page Not Found’ 를 만나게 될 수 밖에 없는 것이다.

해결책은 간단하다고 생각한다. RFC2640 이 구현된 FTP server/client 를 사용하게 될 경우 자동으로 path name 에 UTF-8 을 사용하게 되므로 server 측에서 path name 에 별다른 조작을 가하지 않는 이상 filename 에 UTF-8 로 사용하게 될테고… 결국 UTF-8 로 된 URL 을 아무 문제없이 파일을 처리할 수 있게 된다.

얼른 이런 것들이 흥보가 되고 널리 쓰이게 되서 ‘URL 을 항상 UTF-8 로 보냄’ 을 체크해제 하라는 말을 안볼 수 있는 세상이 왔음 좋겠다 -_-;;

p.s) 현재 RFC2640 이 구현되어 있는 건 filezilla 밖에 모르겠네요. proftpd 의 경우 1.3.1rc 버젼부터 rfc2640 을 지원합니다.

Published by

3 thoughts on “웹서비스와 utf-8”

  1. 윈도우 사용자는 파일 인코딩을 결정하는 일에 대해서 유리되어 있잖아요? 어쩔 수 없는 일 아닌가.. 싶기도 합니다.

  2. 안녕하세요
    UTF-8관련 해서 자료를 찾다가 여기까지 왔습니다.
    좋은 글 감사합니다.
    허나 제가 찾고있는 내용은 없어서 좀 아쉽네요.
    혹시 여쭤 볼수 있을까요?

    CSV 파일을 아래와 같은 방법을 이용해서 인코딩을 판단하고 있습니다
    그런데 LOCAL PC(WINDOW) 에서는 정상적으로 찾아주는데
    서버 (LINUX)에서는 알아내지를 못하네요.
    혹시 원인 및 방법을 아시는지요?

    초면에 무례한 질문 죄송합니다.


    public String Check_CharSet(MultipartFile file) {
    {
    String CharSet = "";
    try {
    InputStreamReader in = new InputStreamReader(file.getInputStream());
    CSVReader reader = new CSVReader(in, ',', '\"', 0);
    String [] nextLine;
    nextLine = reader.readNext();

    byte[] BOM = new byte[4];
    BOM = nextLine[0].getBytes();

    log.debug("Check_CharSet ============= BOM[0] ["+BOM[0]+"] ===============");
    if ((BOM[0] & 0xFF) == 0xEF && (BOM[1] & 0xFF) == 0xBB && (BOM[2] & 0xFF) == 0xBF) {
    CharSet = "UTF-8";
    log.debug("Check_CharSet ============= UTF-8 ===============");
    } else {
    CharSet = "EUC-KR";
    log.debug("Check_CharSet ============= EUC-KR ===============");
    }

    } catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
    }

    return CharSet;
    }

    1. 자바랑 친하진 않아서 구글링을 해봤는데, InputStreamReader는 이미 encoding을 고려하도록 되어 있는 것 같네요.

      Raw byte로 접근하려면 InputStreamReader 대신 InputStream을 사용해야 한다고 합니다.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">