1. 소개
이 섹션은 비규범적입니다.
이 명세서에서 정의된 API는 데이터 스트림을 압축 및 해제하는 데 사용됩니다. 이들은 "deflate", "deflate-raw" 그리고 "gzip" 압축 알고리즘을 지원합니다. 이들은 웹 개발자들에 의해 널리 사용되고 있습니다.
2. 인프라스트럭처
이 명세서는 Infra에 의존합니다. [INFRA]
청크는 데이터의 한 조각입니다. CompressionStream과 DecompressionStream의 경우, 출력 청크 타입은 Uint8Array입니다. 입력으로는 어떤 BufferSource
타입도 허용합니다.
스트림은 청크들의 순서가 지정된 시퀀스를 나타냅니다. ReadableStream
과 WritableStream
용어는 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]
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" , }; [Exposed=*]
"gzip" interface {
CompressionStream constructor (CompressionFormat ); };
format CompressionStream includes GenericTransformStream ;
CompressionStream
은(는) format과 압축 컨텍스트 context를 가집니다.
new CompressionStream(format)
단계는 다음과 같습니다:
-
format이
CompressionStream
에서 지원되지 않으면,TypeError
를 throw합니다. -
transformAlgorithm을 chunk 인자를 받아 청크 압축 및 큐잉 알고리즘을 this와 chunk로 실행하는 알고리즘으로 둡니다.
-
flushAlgorithm을 인자를 받지 않고 압축 플러시 및 큐잉 알고리즘을 this로 실행하는 알고리즘으로 둡니다.
-
this의 transform을 new
TransformStream
으로 설정합니다. -
this의 transform을 transformAlgorithm을 transformAlgorithm으로, flushAlgorithm을 flushAlgorithm으로 설정하여 초기화합니다.
CompressionStream
객체 cs와 chunk를 받아 다음 단계를 수행합니다:
-
chunk가
BufferSource
타입이 아니면TypeError
를 throw합니다. -
buffer가 비어 있으면 return합니다.
-
arrays를 buffer를 하나 이상의 비어 있지 않은 조각으로 나누고 각각을
Uint8Array
로 변환한 결과로 둡니다. -
각
Uint8Array
array에 대해, array를 cs의 transform에 큐잉합니다.
ReadableStream
객체의 데이터가 끝날 때 CompressionStream
객체 cs를 받아 다음 단계를 수행합니다:
-
buffer를 cs의 format과 context로, finish 플래그와 함께, 빈 입력을 압축한 결과로 둡니다.
-
buffer가 비어 있으면 return합니다.
-
arrays를 buffer를 하나 이상의 비어 있지 않은 조각으로 나누고 각각을
Uint8Array
로 변환한 결과로 둡니다. -
각
Uint8Array
array에 대해, array를 cs의 transform에 큐잉합니다.
5. 인터페이스 DecompressionStream
[Exposed=*]interface {
DecompressionStream constructor (CompressionFormat ); };
format DecompressionStream includes GenericTransformStream ;
DecompressionStream
은(는) format과 압축 컨텍스트 context를 가집니다.
new DecompressionStream(format)
단계는 다음과 같습니다:
-
format이
DecompressionStream
에서 지원되지 않으면,TypeError
를 throw합니다. -
transformAlgorithm을 chunk 인자를 받아 청크 해제 및 큐잉 알고리즘을 this와 chunk로 실행하는 알고리즘으로 둡니다.
-
flushAlgorithm을 인자를 받지 않고 해제 플러시 및 큐잉 알고리즘을 this로 실행하는 알고리즘으로 둡니다.
-
this의 transform을 new
TransformStream
으로 설정합니다. -
this의 transform을 transformAlgorithm을 transformAlgorithm으로, flushAlgorithm을 flushAlgorithm으로 설정하여 초기화합니다.
DecompressionStream
객체 ds와 chunk를 받아 다음 단계를 수행합니다:
-
chunk가
BufferSource
타입이 아니면TypeError
를 throw합니다. -
buffer를 ds의 format과 context로 chunk를 해제한 결과로 둡니다. 이 과정에서 오류가 발생하면
TypeError
를 throw합니다. -
buffer가 비어 있으면 return합니다.
-
arrays를 buffer를 하나 이상의 비어 있지 않은 조각으로 나누고 각각을
Uint8Array
로 변환한 결과로 둡니다. -
각
Uint8Array
array에 대해, array를 ds의 transform에 큐잉합니다.
ReadableStream
객체의 데이터가 끝날 때 DecompressionStream
객체 ds를 받아 다음 단계를 수행합니다:
-
buffer를 ds의 format과 context로, finish 플래그와 함께, 빈 입력을 해제한 결과로 둡니다.
-
압축 입력의 끝에 도달하지 않은 경우
TypeError
를 throw합니다. -
buffer가 비어 있으면 return합니다.
-
arrays를 buffer를 하나 이상의 비어 있지 않은 조각으로 나누고 각각을
Uint8Array
로 변환한 결과로 둡니다. -
각
Uint8Array
array에 대해, array를 ds의 transform에 큐잉합니다.
6. 프라이버시 및 보안 고려사항
이 API는 웹 플랫폼에 새로운 권한을 추가하지 않습니다.
그러나 공격자가 데이터의 길이를 알 수 있는 상황에서는 웹 개발자가 주의를 기울여야 합니다. 이 경우, 공격자가 데이터의 내용을 추측할 수 있습니다.
7. 예시
7.1. 스트림을 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 chunkof cs. readable) { output. push( value); totalSize+= value. byteLength; } const concatenated= new Uint8Array( totalSize); let offset= 0 ; for ( const arrayof 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)가 작성했습니다.
지적 재산권
저작권 © WHATWG (Apple, Google, Mozilla, Microsoft). 이 저작물은 크리에이티브 커먼즈 저작자표시 4.0 국제 라이선스 하에 이용할 수 있습니다. 일부가 소스 코드에 통합된 경우, 해당 부분은 BSD 3-절 라이선스 하에 소스 코드로 이용할 수 있습니다.
이 문서는 현행 표준입니다. 특허 검토 버전에 관심이 있는 분은 현행 표준 검토 초안을 참조하세요.