HTTPQUERY
한국어

Content-Encoding

사용법

Content-Encoding 헤더는 표현 데이터에 적용된 인코딩을 적용된 순서대로 나열합니다. 클라이언트는 이 인코딩 연쇄를 역순으로 되돌려 원래 콘텐츠를 복원합니다. 가장 흔한 용도는 압축으로, 서버와 클라이언트 양쪽의 CPU 시간을 대가로 전송 크기를 줄입니다.

Accept-Encoding 요청 헤더는 클라이언트가 지원하는 인코딩을 알립니다. 서버는 그 목록에서 인코딩을 선택하고 Content-Encoding 응답 헤더로 그 선택을 알립니다. 받아들일 수 있는 인코딩이 없으면 서버는 응답을 압축하지 않고 보냅니다.

Content-Encoding이 있을 때 Content-Length 같은 메타데이터 헤더는 원래 리소스가 아니라 인코딩된 형태를 가리킵니다. JPEG, PNG, ZIP처럼 미리 압축된 미디어 형식은 이미 내부 압축을 담고 있어 추가 인코딩으로 얻는 이득이 거의 없습니다. 이런 형식에 콘텐츠 인코딩을 적용하면 CPU를 낭비하고 때로는 전송 크기를 오히려 키웁니다.

Content-Encoding 헤더는 표현 인코딩을 기술하며, 이는 리소스의 종단 간 속성입니다. 이는 각 네트워크 중간 노드에서 적용되고 제거되는 홉 단위 속성인 Transfer-Encoding과 다릅니다.

참고

gzip은 여전히 가장 널리 배포된 인코딩입니다. Brotli는 정적 텍스트 콘텐츠에서 최고의 압축률을 제공합니다. Zstandard는 빠른 압축과 높은 압축률의 균형을 제공하며 브라우저 지원도 넓습니다.

참고

리소스의 원래 미디어 타입은 Content-Type 헤더가 기술합니다. Content-Encoding은 기반 콘텐츠의 형식이 아니라 현재 표현의 압축 상태를 반영합니다.

gzip

32비트 CRC를 포함한 Lempel-Ziv 코딩(LZ77) 알고리즘입니다. 1996년에 도입된 gzip은 여전히 웹에서 가장 널리 지원되는 인코딩입니다. 서버는 x-gzip도 별칭으로 인식합니다.

compress

원래 UNIX compress 프로그램에서 유래한 Lempel-Ziv-Welch(LZW) 알고리즘입니다. 특허 문제로 이 알고리즘은 쇠퇴했으며 현대의 어떤 브라우저도 compress를 지원하지 않습니다.

deflate

deflate 알고리즘을 감싼 zlib 구조입니다. 모든 브라우저가 지원하지만 대체로 gzip과 더 새로운 알고리즘에 밀려났습니다.

br

Brotli 알고리즘입니다. Brotli는 흔한 웹 용어로 이루어진 내장 정적 사전을 사용하여, 특히 텍스트 기반 웹 콘텐츠에서 gzip보다 높은 압축률을 달성합니다. Brotli에는 HTTPS가 필요합니다. 모든 주요 브라우저가 지원합니다.

zstd

Zstandard 알고리즘입니다. Zstandard는 gzip에 견줄 만한 속도로 압축하면서 Brotli에 가까운 압축률을 달성합니다. 이 알고리즘은 1(가장 빠름)부터 22(가장 높은 압축률)까지 설정 가능한 압축 레벨을 지원하여, 서버가 CPU 시간과 페이로드 크기를 저울질할 수 있게 합니다. 압축 해제 속도는 사용한 압축 레벨과 무관하게 일관되게 빠릅니다.

Zstandard는 사전 기반 압축도 지원합니다. 대표적인 콘텐츠로 학습된 사전을 미리 공유하면 페이로드 크기를 더 줄일 수 있습니다. Use-As-Dictionary 헤더와 Compression Dictionary Transport 메커니즘이 이 기능 위에 세워져 있습니다.

Chromium 기반 브라우저, Firefox, 최신 Safari가 지원합니다.

dcb

사전으로 압축한 Brotli입니다. Compression Dictionary Transport 명세의 일부로 정의되었습니다. 클라이언트와 서버는 Use-As-Dictionary와 Available-Dictionary 헤더로 공유 사전을 협상합니다. 서버는 공유 사전을 사용해 Brotli로 응답을 압축하고 인코딩을 dcb로 알립니다.

dcz

사전으로 압축한 Zstandard입니다. dcb와 같은 사전 전송 메커니즘을 쓰되 Brotli 대신 Zstandard 알고리즘을 사용합니다. 서버는 협상된 사전으로 압축하고 인코딩을 dcz로 알립니다.

예시

gzip으로 압축된 응답입니다. 웹에서 가장 흔한 인코딩이며 모든 브라우저가 지원합니다.

Content-Encoding: gzip

Brotli로 압축된 응답입니다. Brotli는 HTML, CSS, JavaScript 리소스에서 보통 gzip보다 작은 페이로드를 만듭니다.

Content-Encoding: br

Zstandard로 압축된 응답입니다. Zstandard를 선택한 서버는 Brotli에 견줄 만한 압축률과 빠른 압축 속도를 함께 누립니다.

Content-Encoding: zstd

여러 인코딩을 순차적으로 적용했습니다. 리소스는 먼저 deflate로, 그다음 gzip으로 인코딩되었습니다. 클라이언트는 역순으로 디코딩합니다. gzip을 먼저, 그다음 deflate입니다.

Content-Encoding: deflate, gzip

사전으로 압축한 Zstandard를 사용하는 응답입니다. 클라이언트는 앞서 Use-As-Dictionary 헤더로 사전을 받았고 Available-Dictionary 요청 헤더로 그 사전을 알렸습니다. 서버는 공유 사전을 기준으로 응답을 압축했습니다.

Content-Encoding: dcz

문제 해결

압축 관련 실패는 브라우저 디코딩 오류, 손상된 다운로드, 또는 압축되지 않은 채 도착하는 응답으로 드러납니다.

이중 압축이 손상된 응답을 만듭니다. 리버스 프록시나 CDN이 오리진에서 이미 압축된 응답을 다시 압축하여, 클라이언트가 디코딩할 수 없는 잘못된 페이로드가 만들어집니다. Content-Encoding 헤더에 gzip, gzip 처럼 값이 겹쳐 있는지 확인하십시오. nginx에서는 오리진이 이미 압축한다면 프록시 압축을 비활성화하십시오.

proxy_set_header Accept-Encoding "";

Cloudflare에서는 오리진이 미리 압축된 응답을 보낼 때 Speed 설정에서 “Brotli”를 끄십시오.

브라우저에 ERR_CONTENT_DECODING_FAILED가 표시됩니다. 이 오류는 Content-Encoding 헤더가 선언한 인코딩이 실제 본문 콘텐츠와 맞지 않을 때 나타납니다. 흔한 원인은 오리진이 Content-Encoding: gzip과 함께 압축되지 않은 본문을 보내거나, 미들웨어가 인코딩은 제거하면서 헤더는 그대로 남겨 두는 경우입니다. curl -v -H “Accept-Encoding: gzip” https://example.re 를 실행해 원시 본문이 선언된 인코딩과 맞는지 살펴보십시오. gunzip으로 흘려보내 확인하십시오. curl -s —compressed https://example.re | head 처럼 씁니다.

압축 후 Content-Length 불일치. Content-Length 값은 원래 크기가 아니라 압축된 본문 크기를 반영해야 합니다. 불일치하면 브라우저가 응답을 잘라 내거나 거부합니다. nginx의 gzip on을 사용할 때 nginx는 Content-Length를 자동으로 다시 계산합니다. 압축이 실행되기 전에 Content-Length를 설정하는 미들웨어가 이 문제를 일으킵니다. Content-Length 할당을 압축 이후로 옮기거나, 헤더를 제거하고 서버가 chunked Transfer-Encoding을 쓰도록 하십시오.

서버를 설정했는데도 압축이 적용되지 않습니다. 서버는 압축하기 전에 Accept-Encoding 요청 헤더를 확인합니다. Accept-Encoding이 없거나 비어 있으면 압축하지 않습니다. 일부 프록시는 전달하는 요청에서 Accept-Encoding을 제거합니다. nginx에서는 gzip on 이 설정되어 있고 MIME 타입이 맞는지 확인하십시오.

gzip on;
gzip_types text/plain application/json
           text/css application/javascript;

Apache에서는 mod_deflate를 활성화하고 필터가 적용되는지 확인하십시오.

AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE application/json

성능 향상을 위해 미리 압축한 파일 제공하기. 요청마다 압축하면 CPU가 낭비됩니다. 대신 미리 압축해 둔 정적 파일을 디스크에서 제공하십시오. nginx에서는 gzip_static on 을 켜서 원본과 나란히 둔 .gz 파일을 제공하십시오. Apache에서는 MultiViews를 켜거나 mod_rewrite로 요청을 .gz 또는 .br 변형에 대응시키십시오. 배포 과정에서 미리 압축된 파일이 원본과 계속 동기화되도록 하십시오.