deflate.js 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. import { JOSENotSupported, JWEInvalid } from '../util/errors.js';
  2. import { concat } from './buffer_utils.js';
  3. function supported(name) {
  4. if (typeof globalThis[name] === 'undefined') {
  5. throw new JOSENotSupported(`JWE "zip" (Compression Algorithm) Header Parameter requires the ${name} API.`);
  6. }
  7. }
  8. export async function compress(input) {
  9. supported('CompressionStream');
  10. const cs = new CompressionStream('deflate-raw');
  11. const writer = cs.writable.getWriter();
  12. writer.write(input).catch(() => { });
  13. writer.close().catch(() => { });
  14. const chunks = [];
  15. const reader = cs.readable.getReader();
  16. for (;;) {
  17. const { value, done } = await reader.read();
  18. if (done)
  19. break;
  20. chunks.push(value);
  21. }
  22. return concat(...chunks);
  23. }
  24. export async function decompress(input, maxLength) {
  25. supported('DecompressionStream');
  26. const ds = new DecompressionStream('deflate-raw');
  27. const writer = ds.writable.getWriter();
  28. writer.write(input).catch(() => { });
  29. writer.close().catch(() => { });
  30. const chunks = [];
  31. let length = 0;
  32. const reader = ds.readable.getReader();
  33. for (;;) {
  34. const { value, done } = await reader.read();
  35. if (done)
  36. break;
  37. chunks.push(value);
  38. length += value.byteLength;
  39. if (maxLength !== Infinity && length > maxLength) {
  40. throw new JWEInvalid('Decompressed plaintext exceeded the configured limit');
  41. }
  42. }
  43. return concat(...chunks);
  44. }