압축

현행 표준 — 마지막 업데이트

참여하기:
GitHub whatwg/compression (새 이슈, 열린 이슈)
Matrix에서 채팅하기
커밋:
GitHub whatwg/compression/commits
이 커밋 기준 스냅샷
@compressionapi
테스트:
web-platform-tests compression/ (진행 중 작업)
번역 (비규범적):
简体中文

요약

이 문서는 이진 데이터 스트림을 압축하고 해제하는 JavaScript API 집합을 정의합니다.

1. 소개

이 섹션은 비규범적입니다.

이 명세서에서 정의된 API는 데이터 스트림을 압축 및 해제하는 데 사용됩니다. 이들은 "deflate", "deflate-raw" 그리고 "gzip" 압축 알고리즘을 지원합니다. 이들은 웹 개발자들에 의해 널리 사용되고 있습니다.

2. 인프라스트럭처

이 명세서는 Infra에 의존합니다. [INFRA]

청크는 데이터의 한 조각입니다. CompressionStream과 DecompressionStream의 경우, 출력 청크 타입은 Uint8Array입니다. 입력으로는 어떤 BufferSource 타입도 허용합니다.

스트림은 청크들의 순서가 지정된 시퀀스를 나타냅니다. ReadableStreamWritableStream 용어는 Streams에서 정의됩니다. [STREAMS]

압축 컨텍스트는 압축 또는 해제 알고리즘이 내부적으로 유지하는 상태입니다. 압축 컨텍스트의 내용은 사용 중인 형식, 알고리즘, 구현에 따라 달라집니다. 이 명세서의 관점에서, 이는 불투명 객체입니다. 압축 컨텍스트는 입력의 첫 바이트를 기대하는 시작 상태에 있습니다.

3. 지원되는 형식

deflate

"ZLIB 압축 데이터 형식" [RFC1950]

참고: 이 형식은 HTTP Content-Encodings와의 일관성을 위해 "deflate"로 불립니다. [RFC7230] 4.2.2절을 참고하세요.

  • 구현체는 [RFC1950] 2.3절에 설명된 "준수"해야 합니다.

  • [RFC1950]에서 잘못된 것으로 설명된 필드 값은 CompressionStream에서 생성되어서는 안 되며, DecompressionStream에서는 오류로 간주됩니다.

  • CMF 필드의 CM (압축 방식) 부분의 유효한 값은 8뿐입니다.

  • FDICT 플래그는 이 API에서 지원되지 않으며, 설정된 경우 스트림에 오류를 발생시킵니다.

  • FLEVEL 플래그는 DecompressionStream에서 무시됩니다.

  • ADLER32 체크섬이 올바르지 않은 경우 DecompressionStream에서는 오류입니다.

  • ADLER32 체크섬 이후에 추가 입력 데이터가 있으면 오류입니다.

deflate-raw

"DEFLATE 알고리즘" [RFC1951]

  • 구현체는 [RFC1951] 1.4절에 설명된 "준수"해야 합니다.

  • [RFC1951]를 준수하지 않는 블록은 CompressionStream에서 생성되어서는 안 되며, DecompressionStream에서는 오류입니다.

  • BFINAL 플래그로 표시된 마지막 블록 이후에 추가 입력 데이터가 있으면 오류입니다.

gzip

"GZIP 파일 형식" [RFC1952]

  • 구현체는 [RFC1952] 2.3.1.2절에 설명된 "준수"해야 합니다.

  • [RFC1952]에서 잘못된 것으로 설명된 필드 값은 CompressionStream에서 생성되어서는 안 되며, DecompressionStream에서는 오류입니다.

  • CM (압축 방식) 필드의 유효한 값은 8뿐입니다.

  • FTEXT 플래그는 DecompressionStream에서 무시되어야 합니다.

  • FHCRC 필드가 존재한다면, 올바르지 않으면 오류입니다.

  • DecompressionStream은 FEXTRA, FNAME, FCOMMENT 필드의 내용을 무시해야 하며, 단 올바르게 종료되었는지 확인만 해야 합니다.

  • MTIME, XFL, OS 필드의 내용은 DecompressionStream에서 무시되어야 합니다.

  • CRC32 또는 ISIZE가 압축 해제된 데이터와 일치하지 않으면 오류입니다.

  • gzip 스트림은 하나의 "멤버"만 포함해야 합니다.

  • "멤버"의 끝 이후에 추가 입력 데이터가 있으면 오류입니다.

4. 인터페이스 CompressionStream

enum CompressionFormat {
  "deflate",
  "deflate-raw",
  "gzip",
};

[Exposed=*]
interface CompressionStream {
  constructor(CompressionFormat format);
};
CompressionStream includes GenericTransformStream;

CompressionStream 은(는) format압축 컨텍스트 context를 가집니다.

new CompressionStream(format) 단계는 다음과 같습니다:
  1. formatCompressionStream에서 지원되지 않으면, TypeError를 throw합니다.

  2. thisformatformat으로 설정합니다.

  3. transformAlgorithmchunk 인자를 받아 청크 압축 및 큐잉 알고리즘을 thischunk로 실행하는 알고리즘으로 둡니다.

  4. flushAlgorithm을 인자를 받지 않고 압축 플러시 및 큐잉 알고리즘을 this로 실행하는 알고리즘으로 둡니다.

  5. thistransformnew TransformStream으로 설정합니다.

  6. thistransformtransformAlgorithmtransformAlgorithm으로, flushAlgorithmflushAlgorithm으로 설정하여 초기화합니다.

청크 압축 및 큐잉 알고리즘은 CompressionStream 객체 cschunk를 받아 다음 단계를 수행합니다:
  1. chunkBufferSource 타입이 아니면 TypeError를 throw합니다.

  2. buffercsformatcontextchunk를 압축한 결과로 둡니다.

  3. buffer가 비어 있으면 return합니다.

  4. arraysbuffer를 하나 이상의 비어 있지 않은 조각으로 나누고 각각을 Uint8Array로 변환한 결과로 둡니다.

  5. Uint8Array array에 대해, arraycstransform에 큐잉합니다.

압축 플러시 및 큐잉 알고리즘은 입력 ReadableStream 객체의 데이터가 끝날 때 CompressionStream 객체 cs를 받아 다음 단계를 수행합니다:
  1. buffercsformatcontext로, finish 플래그와 함께, 빈 입력을 압축한 결과로 둡니다.

  2. buffer가 비어 있으면 return합니다.

  3. arraysbuffer를 하나 이상의 비어 있지 않은 조각으로 나누고 각각을 Uint8Array로 변환한 결과로 둡니다.

  4. Uint8Array array에 대해, arraycstransform에 큐잉합니다.

5. 인터페이스 DecompressionStream

[Exposed=*]
interface DecompressionStream {
  constructor(CompressionFormat format);
};
DecompressionStream includes GenericTransformStream;

DecompressionStream 은(는) format압축 컨텍스트 context를 가집니다.

new DecompressionStream(format) 단계는 다음과 같습니다:
  1. formatDecompressionStream에서 지원되지 않으면, TypeError를 throw합니다.

  2. thisformatformat으로 설정합니다.

  3. transformAlgorithmchunk 인자를 받아 청크 해제 및 큐잉 알고리즘을 thischunk로 실행하는 알고리즘으로 둡니다.

  4. flushAlgorithm을 인자를 받지 않고 해제 플러시 및 큐잉 알고리즘을 this로 실행하는 알고리즘으로 둡니다.

  5. thistransformnew TransformStream으로 설정합니다.

  6. thistransformtransformAlgorithmtransformAlgorithm으로, flushAlgorithmflushAlgorithm으로 설정하여 초기화합니다.

청크 해제 및 큐잉 알고리즘은 DecompressionStream 객체 dschunk를 받아 다음 단계를 수행합니다:
  1. chunkBufferSource 타입이 아니면 TypeError를 throw합니다.

  2. bufferdsformatcontextchunk를 해제한 결과로 둡니다. 이 과정에서 오류가 발생하면 TypeError를 throw합니다.

  3. buffer가 비어 있으면 return합니다.

  4. arraysbuffer를 하나 이상의 비어 있지 않은 조각으로 나누고 각각을 Uint8Array로 변환한 결과로 둡니다.

  5. Uint8Array array에 대해, arraydstransform에 큐잉합니다.

해제 플러시 및 큐잉 알고리즘은 입력 ReadableStream 객체의 데이터가 끝날 때 DecompressionStream 객체 ds를 받아 다음 단계를 수행합니다:
  1. bufferdsformatcontext로, finish 플래그와 함께, 빈 입력을 해제한 결과로 둡니다.

  2. 압축 입력의 끝에 도달하지 않은 경우 TypeError를 throw합니다.

  3. buffer가 비어 있으면 return합니다.

  4. arraysbuffer를 하나 이상의 비어 있지 않은 조각으로 나누고 각각을 Uint8Array로 변환한 결과로 둡니다.

  5. Uint8Array array에 대해, arraydstransform에 큐잉합니다.

6. 프라이버시 및 보안 고려사항

이 API는 웹 플랫폼에 새로운 권한을 추가하지 않습니다.

그러나 공격자가 데이터의 길이를 알 수 있는 상황에서는 웹 개발자가 주의를 기울여야 합니다. 이 경우, 공격자가 데이터의 내용을 추측할 수 있습니다.

7. 예시

7.1. 스트림을 Gzip 압축

const compressedReadableStream
    = inputReadableStream.pipeThrough(new CompressionStream('gzip'));

7.2. ArrayBuffer를 Uint8Array로 Deflate 압축

async function compressArrayBuffer(input) {
  const cs = new CompressionStream('deflate');

  const writer = cs.writable.getWriter();
  writer.write(input);
  writer.close();

  const output = [];
  let totalSize = 0;
  for (const chunk of cs.readable) {
    output.push(value);
    totalSize += value.byteLength;
  }

  const concatenated = new Uint8Array(totalSize);
  let offset = 0;
  for (const array of output) {
    concatenated.set(array, offset);
    offset += array.byteLength;
  }

  return concatenated;
}

7.3. Blob을 Blob으로 Gzip 압축 해제

function decompressBlob(blob) {
  const ds = new DecompressionStream('gzip');
  const decompressionStream = blob.stream().pipeThrough(ds);
  return new Response(decompressionStream).blob();
}

감사의 글

Canon Mukai, Domenic Denicola, Yutaka Hirano에게 감사드립니다.

이 표준은 Adam Rice (Google, ricea@chromium.org)가 작성했습니다.

지적 재산권

이 현행 표준은 W3C WICG에서 처음 개발되었으며, W3C 소프트웨어 및 문서 라이선스 하에 제공되었습니다.

저작권 © WHATWG (Apple, Google, Mozilla, Microsoft). 이 저작물은 크리에이티브 커먼즈 저작자표시 4.0 국제 라이선스 하에 이용할 수 있습니다. 일부가 소스 코드에 통합된 경우, 해당 부분은 BSD 3-절 라이선스 하에 소스 코드로 이용할 수 있습니다.

이 문서는 현행 표준입니다. 특허 검토 버전에 관심이 있는 분은 현행 표준 검토 초안을 참조하세요.

색인

이 명세서에서 정의한 용어

참조로 정의된 용어

참고 문헌

규범적 참고문헌

[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. 현행 표준. URL: https://infra.spec.whatwg.org/
[RFC1950]
P. Deutsch; J-L. Gailly. ZLIB 압축 데이터 형식 명세 버전 3.3. 1996년 5월. 정보용. URL: https://www.rfc-editor.org/rfc/rfc1950
[RFC1951]
P. Deutsch. DEFLATE 압축 데이터 형식 명세 버전 1.3. 1996년 5월. 정보용. URL: https://www.rfc-editor.org/rfc/rfc1951
[RFC1952]
P. Deutsch. GZIP 파일 형식 명세 버전 4.3. 1996년 5월. 정보용. URL: https://www.rfc-editor.org/rfc/rfc1952
[STREAMS]
Adam Rice; et al. Streams Standard. 현행 표준. URL: https://streams.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. 현행 표준. URL: https://webidl.spec.whatwg.org/

비규범적 참고문헌

[RFC7230]
R. Fielding, Ed.; J. Reschke, Ed.. Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing. 2014년 6월. 제안 표준. URL: https://httpwg.org/specs/rfc7230.html

IDL 색인

enum CompressionFormat {
  "deflate",
  "deflate-raw",
  "gzip",
};

[Exposed=*]
interface CompressionStream {
  constructor(CompressionFormat format);
};
CompressionStream includes GenericTransformStream;

[Exposed=*]
interface DecompressionStream {
  constructor(CompressionFormat format);
};
DecompressionStream includes GenericTransformStream;

MDN

CompressionStream/CompressionStream

In all current engines.

Firefox113+Safari16.4+Chrome80+
Opera?Edge80+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js17.0.0+
MDN

CompressionStream

In all current engines.

Firefox113+Safari16.4+Chrome80+
Opera?Edge80+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js18.0.0+
MDN

DecompressionStream/DecompressionStream

In all current engines.

Firefox113+Safari16.4+Chrome80+
Opera?Edge80+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js17.0.0+
MDN

DecompressionStream

In all current engines.

Firefox113+Safari16.4+Chrome80+
Opera?Edge80+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
Node.js18.0.0+