17 lines · 728 B
/**
 * RFC 6266 / RFC 5987 disposition. Branch, tag and upload names may contain `"`, `;` and non-ASCII,
 * so the quoted `filename` only carries a sanitized ASCII fallback and the real name goes in `filename*`.
 */
export function contentDisposition(type: "inline" | "attachment", filename: string): string {
  const ascii = filename.replace(/[^\x20-\x7e]/g, "_").replace(/["\\;]/g, "_");
  const encoded = encodeURIComponent(filename).replace(
    /[!'()*]/g,
    (char) => `%${char.charCodeAt(0).toString(16).toUpperCase()}`,
  );
  return `${type}; filename="${ascii}"; filename*=UTF-8''${encoded}`;
}

export function attachmentDisposition(filename: string): string {
  return contentDisposition("attachment", filename);
}