OverviewFilesCommitsIssuesDocsReleasesPeers

pear-git-v3 / lib / web / compress.js

68 lines · javascript ref:
/**
 * Response compression for the SSR surface.
 *
 * WHY THIS EXISTS: the daemon had no compression of any kind. That was
 * invisible on localhost, but 7rnx.net/git reverse-proxies to it across a
 * ~96ms / ~0.8MB/s VPN hop. Apache on the VPS runs mod_deflate, so the
 * browser did receive a gzipped page — but mod_deflate only compresses the
 * VPS->browser leg. Apache still had to pull the full uncompressed response
 * across the VPN first, which measured 1.27-1.66s for the /repos page.
 *
 * Compressing here is what shrinks the leg that actually costs: Apache
 * forwards the client's Accept-Encoding upstream, and mod_deflate will not
 * re-compress a response that already carries Content-Encoding.
 *
 * Content-Length is deliberately never set alongside a body — bare-http1
 * derives it from res.end(body), and setting it explicitly makes it emit a
 * second Content-Length header that its (stricter-than-node) parser rejects.
 * See the same note in static.js.
 */

import zlib from '#node:zlib'

/**
 * Don't bother below this. Gzip adds ~20 bytes of header, and anything
 * that already fits in a single MTU is one packet either way — the round
 * trip dominates, not the bytes.
 */
const MIN_COMPRESS_BYTES = 1024

/**
 * Does the client actually accept gzip?
 *
 * Matches gzip as a full token so `x-gzip` or a hypothetical `notgzip`
 * can't false-positive. `identity;q=0` style qvalues are not honoured —
 * a client that advertises gzip at all is assumed to accept it, which is
 * true of every browser and of Apache's upstream request.
 */
export function acceptsGzip (req) {
  const raw = req && req.headers && req.headers['accept-encoding']
  if (!raw) return false
  return /(?:^|,)\s*(?:gzip|\*)\s*(?:;[^,]*)?(?:,|$)/i.test(String(raw))
}

/**
 * Gzip a response body if it's worth it.
 *
 * @param {string|Uint8Array} body
 * @returns {Uint8Array|null} the compressed body, or null to send as-is
 */
export function gzipIfWorthIt (body) {
  if (body == null) return null

  const buf = typeof body === 'string' ? Buffer.from(body) : body
  if (buf.byteLength < MIN_COMPRESS_BYTES) return null

  try {
    const out = zlib.gzipSync(buf)
    // A compressor that made things bigger (already-compressed input)
    // means we should just send the original.
    return out.byteLength < buf.byteLength ? out : null
  } catch {
    // Never fail a page because compression failed.
    return null
  }
}

export const __test = { MIN_COMPRESS_BYTES }