멀티파트 문자열 파라미터 깨지는 문제 (트러블 슈팅 기록)

멀티파트 문자열 파라미터 깨지는 문제 (트러블 슈팅 기록)

어떤 메일연동 시스템이 있다.
특정 페이지에 제목, 내용, 첨부파일들을 멀티파트 형태(enctype=”multipart/form-data”)로 쏘면, 메일을 생성하고 발송까지 해주는 메일연동이다.

기존에 이 페이지를 잘 쓰고 있었는데, 새로운 업체가 들어와서 사용해보니 글자가 깨져나온다고 했다.
새 업체는 문자열을 왜 이런 문제가 생기는지 알 수 없다고 했다.
문제는 문자열을 UTF-8로 인코딩해서 보냈기 때문이었다.

몇 가지 테스트를 통해 확인한 결과는 다음과 같다.

1. 원래 한글을 그냥 넘겨도, WAS 설정이 잘되어 있다면 와스가 알아서 UTF-8로 만들어준다.

예를 들어 window.open(“http://test.co.kr/test.jsp?param=한글“); 식으로 웹페이지를 열었을 때,
받는 쪽인 test.jsp 페이지에서
String param = request.getParameter(“param”);
System.out.println(“param : ” + param);
해보면 콘솔에 “param : 한글” 과 같이 잘 찍힌다.

WAS 설정이 잘 안되어 있다면 (그리고 WAS 설정과 무관하게 잘 돌게 코딩하려면),
클라이언트에서 쏠 때
var param = encodeURIComponent(“한글”);
var targetUrl = “http://test.co.kr/test.jsp?param=” + param;
window.open(targetUrl);
위와 같이 코딩할텐데, 이 역시 콘솔에 “param : 한글” 과 같이 잘 찍힌다.

2. 그런데 해당 페이지는 멀티파트 형태로 submit 해야 동작하도록 설계되어 있었다.

따라서 request.getParameter() 코드로 파라미터를 가져오지 않는 상태였다.

이 경우 파라미터는, 서버에서 request 객체 안에 있는 InputStream 을 readLine() 해서 얻어오게 되는데,
살펴보니 얻어온 파라미터 값을 항상 UTF-8 로 바꾸도록 코딩되어 있었다.
cf) String newStr = new String(oldStr.getBytes(“8859_1”), “UTF-8”);

테스트 결과 form 내 input 태그의 value 를 pure한 한글로 지정했을 때,
서버에서 UTF-8로 잘 바꿔주는 것을 확인할 수 있었다.

그런데 문제가 된 경우는, form 내 input 태그의 value 를 미리 UTF-8로 변환한 경우였다.
예를 들어 input1.value = encodeURIComponent(“한글”); 이라고 코딩한 경우 서버에서 깨져버리는 것을 확인할 수 있었다.
UTF-8로 넘어온 값을 ISO-8859-1로 getBytes하고, 다시 UTF-8로 인코딩하기 때문으로 보인다.

3. 아마 보내는 쪽에서 파라미터마다 encodeURIComponent() 로 감싸주었거나,
<form … enctype=”multipart/form-data”> 가 아닌
<form … enctype=”multipart/form-data” accept-charset=”UTF-8″> 와 같이 코딩한 것으로 추측된다.

cf) accept-charset 에는 서버로 전송할 인코딩을 쓴다. 자바스크립트에서는 아래와 같이 코딩하기도 한다.
form.acceptCharset = “UTF-8”;
document.charset = form.acceptCharset;

파라미터를 UTF-8로 보내는 일이 잘못된 일은 아니지만 (오히려 코딩을 잘했다고 볼 수 있지만)
멀티파트를 받아 처리하는 서버 쪽이 무조건 ISO-8859-1 로 getBytes 해서 UTF-8 로 인코딩하게 코딩되어 있으므로,
pure하게 파라미터를 보내달라고 요청하였다.