gzip 和 x-gzip 内容之间的区别?如果是这样,我该如何解压 x-gzip? zlib 令人窒息

Difference between gzip and x-gzip content? If so, how to I decompress x-gzip? zlib is choking

我有一个库,通过 npm 作为“按请求”发布,除其他外,它可以自动解压缩 Web 内容。处理这种情况的部分代码如下所示:

        if (!options.dontDecompress || !binary) {
          if (contentEncoding === 'gzip' || (options.autoDecompress && /\b(gzip|gzipped|gunzip)\b/.test(contentType))) {
            source = zlib.createGunzip();
            res.pipe(source);
          }
          // *** start of temporary new code ***
          else if (contentEncoding === 'x-gzip' && options.autoDecompress) {
            source = zlib.createGunzip(); // zlib.createUnzip() doesn't work either
            res.pipe(source);
          }
          // *** end of temporary new code ***
          else if (contentEncoding === 'deflate' || (options.autoDecompress && /\bdeflate\b/.test(contentType))) {
            source = zlib.createInflate();
            res.pipe(source);
          }
          else if (contentEncoding === 'br') {
            source = zlib.createBrotliDecompress();
            res.pipe(source);
          }
          else if (contentEncoding && contentEncoding !== 'identity') {
            reject(UNSUPPORTED_MEDIA_TYPE);
            return;
          }
        }

在我尝试从这里读取天文信息文件之前,代码一直运行良好:https://cdsarc.cds.unistra.fr/viz-bin/nph-Cat/txt.gz?VII/118/names.dat

我遇到了 reject(UNSUPPORTED_MEDIA_TYPE) 错误处理程序,因为我没有专门处理 x-gzipContent-Type。然而,简单地添加对 x-gzip 的检查并没有解决问题。

zlib 正在处理数据,返回时出现此错误:

Error: incorrect header check
at Zlib.zlibOnError [as onerror] (node:zlib:190:17)

我需要不同的解压库吗?我四处搜寻,但还没有找到好的解决方案。根据之前的 Stack Overflow 答案:Difference between "x-gzip" and "gzip" for content-encoding

...gzip 和 x-gzip 应该是一样的。它不是那样工作的。另一方面,我试过的网络浏览器在获取和显示 cdsarc.cds.unistra.fr URL.

中的文本时没有任何问题

以下解决方案对我有用,用 shell gzip 解压操作代替 zlib 和 createGunzip() 提供的解压操作。我能想到的使此修复起作用的唯一原因可能是导致失败的特定网站提供的压缩数据流有些古怪,shell 命令可以容忍这种情况,但 zlib 不是。

  if (!checkedGzipShell) {
    checkedGzipShell = true;
    hasGzipShell = true;

    const gzipProc = spawn('gzip', ['-L']);

    await new Promise<void>(resolve => {
      gzipProc.once('error', () => { hasGzipShell = false; resolve(); });
      gzipProc.stdout.once('end', resolve);
    });
  }
          if (contentEncoding === 'gzip' || contentEncoding === 'x-gzip' ||
              (options.autoDecompress && /\b(gzip|gzipped|gunzip)\b/.test(contentType))) {
            if (hasGzipShell) {
              const gzipProc = spawn('gzip', ['-dc']);

              source = gzipProc.stdout;
              res.pipe(gzipProc.stdin);
            }
            else {
              source = zlib.createGunzip();
              res.pipe(source);
            }
          }