1. 개요
Apache - JBoss 구조에서 2GB 이상 파일을 요청할 때 응답 헤더에 Content-Length가 표시되지 않는 이슈가 있다. 정확히 어느 구간의 문제인지 확인하기 위해 여러 지점에 직접 요청을 보내 보았다.
2. 테스트
테스트는 각 구간에 같은 파일을 요청한 뒤 응답 헤더에 Content-Length가 포함되는지 확인하는 방식으로 진행했다. 아래 결과에서 핵심은 Content-Length 또는 Transfer-Encoding: chunked 헤더의 유무다.
2-1. Apache (2.2.27)
Accept-Ranges:bytes Connection:Keep-Alive Content-Length:2482044928 Content-Type:application/x-gzip Date:Fri, 12 Sep 2014 01:07:48 GMT ETag:"140032-93f10000-500e216017f6d" Keep-Alive:timeout=3, max=100 Last-Modified:Mon, 18 Aug 2014 07:11:55 GMT Server:Apache
2-2. JBoss EAP (6.2)
Accept-Ranges:bytes Content-Length:2482044928 Content-Type:application/x-gzip Date:Fri, 12 Sep 2014 01:04:24 GMT ETag:W/"2482044928-1410483441000" Last-Modified:Fri, 12 Sep 2014 00:57:21 GMT Server:Apache-Coyote/1.1
2-3. Tomcat (7.0.55)
Accept-Ranges:bytes Content-Length:2482044928 Content-Type:application/x-gzip Date:Fri, 12 Sep 2014 01:15:06 GMT ETag:W/"2482044928-1410483441000" Last-Modified:Fri, 12 Sep 2014 00:57:21 GMT Server:Apache-Coyote/1.1
2-4. Apache (2.2.27) - JBoss EAP (6.2)
Accept-Ranges:bytes Connection:Keep-Alive Content-Type:application/x-gzip Date:Fri, 12 Sep 2014 01:00:25 GMT ETag:W/"2482044928-1410483441000" Keep-Alive:timeout=3, max=100 Last-Modified:Fri, 12 Sep 2014 00:57:21 GMT Server:Apache Transfer-Encoding:chunked
Content-Length 정보가 포함되지 않았다. 다만 요청 시 파일 처리, 즉 다운로드 자체는 정상적으로 동작한다.
2-5. Apache (2.2.27) - Tomcat (7.0.55)
Accept-Ranges:bytes Connection:Keep-Alive Content-Length:2482044928 Content-Type:application/x-gzip Date:Fri, 12 Sep 2014 01:13:21 GMT ETag:W/"2482044928-1410483441000" Keep-Alive:timeout=3, max=100 Last-Modified:Fri, 12 Sep 2014 00:57:21 GMT Server:Apache
3. 결과
위 테스트 결과를 보면, 2GB 이상 파일을 Apache - JBoss 연동 구조로 처리할 때만 Content-Length가 포함되어 있지 않다. 즉, 해당 파일을 JBoss에서 처리하는 경우에만 발생한다.
물론 다운로드는 잘 되지만, Content-Length가 없어서 브라우저에서 다운로드할 때 총 파일 용량이 표시되지 않고 현재 다운로드한 크기만 표시된다. 예를 들어 15MB/2.3GB처럼 나오지 않고 15MB만 표시된다.
추가로 Apache - JBoss 연동에서 2GB 이하 파일도 테스트해 보았다.
Accept-Ranges:bytes Connection:Keep-Alive Content-Length:938882272 Content-Type:application/x-gzip Date:Fri, 12 Sep 2014 01:32:36 GMT ETag:W/"938882272-1410485435000" Keep-Alive:timeout=3, max=100 Last-Modified:Fri, 12 Sep 2014 01:30:35 GMT Server:Apache
이 경우에는 정상적으로 Content-Length가 표시되었다. 결론적으로 Apache - JBoss 연동 시에만, 그리고 2GB 이상일 때 Content-Length가 빠진다.
Apache - Tomcat일 때는 정상적으로 표시되므로, 이 결과만 놓고 보면 단순히 mod_jk 문제라고 보기는 어렵다.
4. Content-Length와 chunked 방식의 차이
4-1. Content-Length 방식
Content-Length에 본문의 길이를 기록하므로 수신자가 본문의 전체 길이를 알 수 있게 하는 방식이다.- 정적 콘텐츠처럼 헤더 생성 시점에 본문의 길이를 알 수 있을 때 사용한다.
- 클라이언트는 이 값을 기준으로 다운로드 진행률이나 전체 파일 크기를 표시할 수 있다.
4-2. chunked 방식
- HTTP 헤더 중
Transfer-Encoding의 값이chunked인 방식이다. - 헤더 생성 시점에 본문의 전체 길이를 알 수 없을 때 사용한다.
- 동적 콘텐츠의 경우 애플리케이션 수행이 시작되면서 HTTP 응답도 함께 시작될 수 있다.
- 이때 송신 버퍼가 8K를 넘으면 응답을 먼저 보내기 시작하는데, 아직 애플리케이션 처리가 끝나지 않았다면 이후 응답 본문이 추가로 생성된다.
이번 테스트에서 Apache - JBoss 조합의 2GB 이상 파일 응답은 Content-Length 대신 Transfer-Encoding: chunked로 내려왔다. 따라서 파일 다운로드 자체는 가능하지만, 클라이언트 입장에서는 응답 시작 시점에 전체 크기를 알 수 없어 진행률 표시가 제한될 수 있다.