export function compressionNegotiate()

in packages/dubbo/src/protocol/compression.ts [60:107]


export function compressionNegotiate(
  available: Compression[],
  requested: string | null, // e.g. the value of the Grpc-Encoding header
  accepted: string | null, // e.g. the value of the Grpc-Accept-Encoding header
  headerNameAcceptEncoding: string // e.g. the name of the Grpc-Accept-Encoding header
): {
  request: Compression | null;
  response: Compression | null;
  error?: ConnectError;
} {
  let request = null;
  let response = null;
  let error = undefined;
  if (requested !== null && requested !== "identity") {
    const found = available.find((c) => c.name === requested);
    if (found) {
      request = found;
    } else {
      // To comply with https://github.com/grpc/grpc/blob/master/doc/compression.md
      // and the Connect protocol, we return code "unimplemented" and specify
      // acceptable compression(s).
      const acceptable = available.map((c) => c.name).join(",");
      error = new ConnectError(
        `unknown compression "${requested}": supported encodings are ${acceptable}`,
        Code.Unimplemented,
        {
          [headerNameAcceptEncoding]: acceptable,
        }
      );
    }
  }
  if (accepted === null || accepted === "") {
    // Support asymmetric compression. This logic follows
    // https://github.com/grpc/grpc/blob/master/doc/compression.md and common
    // sense.
    response = request;
  } else {
    const acceptNames = accepted.split(",").map((n) => n.trim());
    for (const name of acceptNames) {
      const found = available.find((c) => c.name === name);
      if (found) {
        response = found;
        break;
      }
    }
  }
  return { request, response, error };
}