본문 바로가기

푸로그래밍

JAVA, .NET, PHP, JS(NodeJS, ES5, ES6) 에서 UTF-8 파일 다운로드 인코딩, RFC2231

반응형

1. 개요

각 언어별로 RFC2231 인코딩을 해보자.

 

브라우저로 하여금 현재 응답이 파일 다운로드라는것을 알려주기 위해서 우리는 Header에 ContentType과 ContentDispotion등을 이용한다.

 

보통 다운로드를 제공할때 Header에 Content-Dispostion: attachment; filename="파일명.html"

의 형식으로 많이들 사용하지만, 사실 이는 표준을 준수한것이 아니다.

 

표준을 준수하기 위해서는 RFC2231표준에 맞게 인코딩된 파일명을 아래와 같은 형식으로 보내줘야한다.

 

파일명을

Content-Disposition: attachment; filename*=UTF-8''foo-a%cc%88.html

위의 형식으로 보내줘야 한다.

이상해보이긴 하지만 이게 표준이다.

 

각 언어(JAVA, .NET, PHP, NodeJS)별로 RFC2231표준의 문자열로 converting 하는 코드를 알아보자.

 

1. JAVA

public static String toRFC2231(String str) {
    try {
        byte[] bytes = str.getBytes("UTF-8");
        StringBuilder sb = new StringBuilder();
        sb.append("utf-8''");

        for (int i = 0; i < bytes.length; i++) {
            byte b = bytes[i];

            if (b >= 0x20 && b <= 0x7E) {
                if (b == '"' || b == '%' || b == '\\') {
                    sb.append('\\');
                }
                sb.append((char)b);
            } else {
                sb.append('%');
                sb.append(String.format("%02X", b));
            }
        }

        return sb.toString();
    } catch (UnsupportedEncodingException e) {
        return null;
    }
}

 

2. .NET(C#)

public static string ToRFC2231(string str)
{
    var bytes = Encoding.UTF8.GetBytes(str);
    var sb = new StringBuilder("utf-8''");
    
    foreach (var b in bytes)
    {
        if (b >= 0x20 && b <= 0x7E)
        {
            if (b == '"' || b == '%' || b == '\\')
            {
                sb.Append('\\');
            }
            sb.Append((char)b);
        }
        else
        {
            sb.Append('%');
            sb.Append(b.ToString("X2"));
        }
    }
    
    return sb.ToString();
}

 

3. PHP

function toRFC2231($str) {
    $bytes = mb_convert_encoding($str, 'UTF-8');
    $sb = "utf-8''";

    for ($i = 0; $i < strlen($bytes); $i++) {
        $b = ord($bytes[$i]);

        if ($b >= 0x20 && $b <= 0x7E) {
            if ($b == 0x22 || $b == 0x25 || $b == 0x5C) {
                $sb .= '\\';
            }
            $sb .= $bytes[$i];
        } else {
            $sb .= '%' . strtoupper(dechex($b));
        }
    }

    return $sb;
}

 

4. NodeJS

function toRFC2231(str) {
  const bytes = Buffer.from(str, 'utf-8');
  let sb = 'utf-8\'\'';

  for (let i = 0; i < bytes.length; i++) {
    const b = bytes[i];

    if (b >= 0x20 && b <= 0x7E) {
      if (b === 0x22 || b === 0x25 || b === 0x5C) {
        sb += '\\';
      }
      sb += String.fromCharCode(b);
    } else {
      sb += '%' + b.toString(16).toUpperCase();
    }
  }

  return sb;
}

 

5. JavaScript (ES6)

function toRFC2231(str) {
  const bytes = new TextEncoder().encode(str);
  let sb = 'utf-8\'\'';

  for (let i = 0; i < bytes.length; i++) {
    const b = bytes[i];

    if (b >= 0x20 && b <= 0x7E) {
      if (b === 0x22 || b === 0x25 || b === 0x5C) {
        sb += '\\';
      }
      sb += String.fromCharCode(b);
    } else {
      sb += '%' + b.toString(16).toUpperCase();
    }
  }

  return sb;
}

 

6. JavaScript (ES5)

function toRFC2231(str) {
  var bytes = [];
  for (var i = 0; i < str.length; i++) {
    bytes.push(str.charCodeAt(i));
  }
  var sb = 'utf-8\'\'';

  for (var i = 0; i < bytes.length; i++) {
    var b = bytes[i];

    if (b >= 0x20 && b <= 0x7E) {
      if (b === 0x22 || b === 0x25 || b === 0x5C) {
        sb += '\\';
      }
      sb += String.fromCharCode(b);
    } else {
      sb += '%' + b.toString(16).toUpperCase();
    }
  }

  return sb;
}

 

이상이다.

반응형

'푸로그래밍' 카테고리의 다른 글

OpenCV GPU  (0) 2024.03.19