Skip to content
This repository has been archived by the owner on Oct 21, 2024. It is now read-only.

Commit

Permalink
fix: file content type (#1038)
Browse files Browse the repository at this point in the history
* fix: prefer user-defined content type

* sync

---------

Co-authored-by: Frank <[email protected]>
  • Loading branch information
artufimtcev and fwang authored Oct 16, 2024
1 parent 6ea6828 commit ed7b080
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 185 deletions.
48 changes: 1 addition & 47 deletions platform/src/components/aws/ssr-site.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@ import { Input } from "../input.js";
import { transform, type Prettify, type Transform } from "../component.js";
import { VisibleError } from "../error.js";
import { Cron } from "./cron.js";
import { BaseSiteFileOptions } from "../base/base-site.js";
import { BaseSiteFileOptions, getContentType } from "../base/base-site.js";
import { BaseSsrSiteArgs } from "../base/base-ssr-site.js";
import {
cloudfront,
getPartitionOutput,
getRegionOutput,
iam,
lambda,
types,
} from "@pulumi/aws";
Expand Down Expand Up @@ -564,51 +563,6 @@ export function createServersAndDistribution(
});
}

function getContentType(filename: string, textEncoding: string) {
const ext = filename.endsWith(".well-known/site-association-json")
? ".json"
: path.extname(filename);
const extensions = {
[".txt"]: { mime: "text/plain", isText: true },
[".htm"]: { mime: "text/html", isText: true },
[".html"]: { mime: "text/html", isText: true },
[".xhtml"]: { mime: "application/xhtml+xml", isText: true },
[".css"]: { mime: "text/css", isText: true },
[".js"]: { mime: "text/javascript", isText: true },
[".mjs"]: { mime: "text/javascript", isText: true },
[".apng"]: { mime: "image/apng", isText: false },
[".avif"]: { mime: "image/avif", isText: false },
[".gif"]: { mime: "image/gif", isText: false },
[".jpeg"]: { mime: "image/jpeg", isText: false },
[".jpg"]: { mime: "image/jpeg", isText: false },
[".png"]: { mime: "image/png", isText: false },
[".svg"]: { mime: "image/svg+xml", isText: true },
[".bmp"]: { mime: "image/bmp", isText: false },
[".tiff"]: { mime: "image/tiff", isText: false },
[".webp"]: { mime: "image/webp", isText: false },
[".ico"]: { mime: "image/vnd.microsoft.icon", isText: false },
[".eot"]: { mime: "application/vnd.ms-fontobject", isText: false },
[".ttf"]: { mime: "font/ttf", isText: false },
[".otf"]: { mime: "font/otf", isText: false },
[".woff"]: { mime: "font/woff", isText: false },
[".woff2"]: { mime: "font/woff2", isText: false },
[".json"]: { mime: "application/json", isText: true },
[".jsonld"]: { mime: "application/ld+json", isText: true },
[".xml"]: { mime: "application/xml", isText: true },
[".pdf"]: { mime: "application/pdf", isText: false },
[".zip"]: { mime: "application/zip", isText: false },
[".wasm"]: { mime: "application/wasm", isText: false },
[".webmanifest"]: { mime: "application/manifest+json", isText: true },
};
const extensionData = extensions[ext as keyof typeof extensions];
const mime = extensionData?.mime ?? "application/octet-stream";
const charset =
extensionData?.isText && textEncoding !== "none"
? `;charset=${textEncoding}`
: "";
return `${mime}${charset}`;
}

function createEdgeFunctions() {
const functions: Record<string, Function> = {};

Expand Down
50 changes: 4 additions & 46 deletions platform/src/components/aws/static-site.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ import { Link } from "../link.js";
import { Input } from "../input.js";
import { globSync } from "glob";
import { BucketFile, BucketFiles } from "./providers/bucket-files.js";
import { getContentType } from "../base/base-site.js";
import {
BaseStaticSiteArgs,
BaseStaticSiteAssets,
buildApp,
prepare,
} from "../base/base-static-site.js";
import { cloudfront, iam, s3 } from "@pulumi/aws";
import { cloudfront, s3 } from "@pulumi/aws";
import { URL_UNAVAILABLE } from "./linkable.js";
import { DevArgs } from "../dev.js";
import { OriginAccessControl } from "./providers/origin-access-control.js";
Expand Down Expand Up @@ -775,7 +776,8 @@ export class StaticSite extends Component implements Link.Linkable {
key: path.posix.join(assets.path ?? "", file),
hash,
cacheControl: fileOption.cacheControl,
contentType: getContentType(file, "UTF-8"),
contentType:
fileOption.contentType ?? getContentType(file, "UTF-8"),
};
}),
)),
Expand All @@ -795,50 +797,6 @@ export class StaticSite extends Component implements Link.Linkable {
});
}

function getContentType(filename: string, textEncoding: string) {
const ext = filename.endsWith(".well-known/site-association-json")
? ".json"
: path.extname(filename);
const extensions = {
[".txt"]: { mime: "text/plain", isText: true },
[".htm"]: { mime: "text/html", isText: true },
[".html"]: { mime: "text/html", isText: true },
[".xhtml"]: { mime: "application/xhtml+xml", isText: true },
[".css"]: { mime: "text/css", isText: true },
[".js"]: { mime: "text/javascript", isText: true },
[".mjs"]: { mime: "text/javascript", isText: true },
[".apng"]: { mime: "image/apng", isText: false },
[".avif"]: { mime: "image/avif", isText: false },
[".gif"]: { mime: "image/gif", isText: false },
[".jpeg"]: { mime: "image/jpeg", isText: false },
[".jpg"]: { mime: "image/jpeg", isText: false },
[".png"]: { mime: "image/png", isText: false },
[".svg"]: { mime: "image/svg+xml", isText: true },
[".bmp"]: { mime: "image/bmp", isText: false },
[".tiff"]: { mime: "image/tiff", isText: false },
[".webp"]: { mime: "image/webp", isText: false },
[".ico"]: { mime: "image/vnd.microsoft.icon", isText: false },
[".eot"]: { mime: "application/vnd.ms-fontobject", isText: false },
[".ttf"]: { mime: "font/ttf", isText: false },
[".otf"]: { mime: "font/otf", isText: false },
[".woff"]: { mime: "font/woff", isText: false },
[".woff2"]: { mime: "font/woff2", isText: false },
[".json"]: { mime: "application/json", isText: true },
[".jsonld"]: { mime: "application/ld+json", isText: true },
[".xml"]: { mime: "application/xml", isText: true },
[".pdf"]: { mime: "application/pdf", isText: false },
[".zip"]: { mime: "application/zip", isText: false },
[".wasm"]: { mime: "application/wasm", isText: false },
};
const extensionData = extensions[ext as keyof typeof extensions];
const mime = extensionData?.mime ?? "application/octet-stream";
const charset =
extensionData?.isText && textEncoding !== "none"
? `;charset=${textEncoding}`
: "";
return `${mime}${charset}`;
}

function createDistribution() {
return new Cdn(
...transform(
Expand Down
46 changes: 46 additions & 0 deletions platform/src/components/base/base-site.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import path from "path";
import { Semaphore } from "../../util/semaphore";

export interface BaseSiteFileOptions {
Expand All @@ -23,3 +24,48 @@ export interface BaseSiteFileOptions {
export const limiter = new Semaphore(
parseInt(process.env.SST_SITE_BUILD_CONCURRENCY || "4"),
);

export function getContentType(filename: string, textEncoding: string) {
const ext = filename.endsWith(".well-known/site-association-json")
? ".json"
: path.extname(filename);
const extensions = {
[".txt"]: { mime: "text/plain", isText: true },
[".htm"]: { mime: "text/html", isText: true },
[".html"]: { mime: "text/html", isText: true },
[".xhtml"]: { mime: "application/xhtml+xml", isText: true },
[".css"]: { mime: "text/css", isText: true },
[".js"]: { mime: "text/javascript", isText: true },
[".mjs"]: { mime: "text/javascript", isText: true },
[".apng"]: { mime: "image/apng", isText: false },
[".avif"]: { mime: "image/avif", isText: false },
[".gif"]: { mime: "image/gif", isText: false },
[".jpeg"]: { mime: "image/jpeg", isText: false },
[".jpg"]: { mime: "image/jpeg", isText: false },
[".png"]: { mime: "image/png", isText: false },
[".svg"]: { mime: "image/svg+xml", isText: true },
[".bmp"]: { mime: "image/bmp", isText: false },
[".tiff"]: { mime: "image/tiff", isText: false },
[".webp"]: { mime: "image/webp", isText: false },
[".ico"]: { mime: "image/vnd.microsoft.icon", isText: false },
[".eot"]: { mime: "application/vnd.ms-fontobject", isText: false },
[".ttf"]: { mime: "font/ttf", isText: false },
[".otf"]: { mime: "font/otf", isText: false },
[".woff"]: { mime: "font/woff", isText: false },
[".woff2"]: { mime: "font/woff2", isText: false },
[".json"]: { mime: "application/json", isText: true },
[".jsonld"]: { mime: "application/ld+json", isText: true },
[".xml"]: { mime: "application/xml", isText: true },
[".pdf"]: { mime: "application/pdf", isText: false },
[".zip"]: { mime: "application/zip", isText: false },
[".wasm"]: { mime: "application/wasm", isText: false },
[".webmanifest"]: { mime: "application/manifest+json", isText: true },
};
const extensionData = extensions[ext as keyof typeof extensions];
const mime = extensionData?.mime ?? "application/octet-stream";
const charset =
extensionData?.isText && textEncoding !== "none"
? `;charset=${textEncoding}`
: "";
return `${mime}${charset}`;
}
49 changes: 3 additions & 46 deletions platform/src/components/cloudflare/ssr-site.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Output, Unwrap, output, all, ComponentResource } from "@pulumi/pulumi";
import { Input } from "../input.js";
import { transform, type Transform } from "../component.js";
import { VisibleError } from "../error.js";
import { BaseSiteFileOptions } from "../base/base-site.js";
import { BaseSiteFileOptions, getContentType } from "../base/base-site.js";
import { BaseSsrSiteArgs } from "../base/base-ssr-site.js";
import { Kv, KvArgs } from "./kv.js";
import { Worker, WorkerArgs } from "./worker.js";
Expand Down Expand Up @@ -142,7 +142,8 @@ export function createRouter(
key: path.posix.join(copy.to, file),
hash,
cacheControl: fileOption.cacheControl,
contentType: getContentType(file, "UTF-8"),
contentType:
fileOption.contentType ?? getContentType(file, "UTF-8"),
};
}),
)),
Expand Down Expand Up @@ -173,50 +174,6 @@ export function createRouter(
);
}

function getContentType(filename: string, textEncoding: string) {
const ext = filename.endsWith(".well-known/site-association-json")
? ".json"
: path.extname(filename);
const extensions = {
[".txt"]: { mime: "text/plain", isText: true },
[".htm"]: { mime: "text/html", isText: true },
[".html"]: { mime: "text/html", isText: true },
[".xhtml"]: { mime: "application/xhtml+xml", isText: true },
[".css"]: { mime: "text/css", isText: true },
[".js"]: { mime: "text/javascript", isText: true },
[".mjs"]: { mime: "text/javascript", isText: true },
[".apng"]: { mime: "image/apng", isText: false },
[".avif"]: { mime: "image/avif", isText: false },
[".gif"]: { mime: "image/gif", isText: false },
[".jpeg"]: { mime: "image/jpeg", isText: false },
[".jpg"]: { mime: "image/jpeg", isText: false },
[".png"]: { mime: "image/png", isText: false },
[".svg"]: { mime: "image/svg+xml", isText: true },
[".bmp"]: { mime: "image/bmp", isText: false },
[".tiff"]: { mime: "image/tiff", isText: false },
[".webp"]: { mime: "image/webp", isText: false },
[".ico"]: { mime: "image/vnd.microsoft.icon", isText: false },
[".eot"]: { mime: "application/vnd.ms-fontobject", isText: false },
[".ttf"]: { mime: "font/ttf", isText: false },
[".otf"]: { mime: "font/otf", isText: false },
[".woff"]: { mime: "font/woff", isText: false },
[".woff2"]: { mime: "font/woff2", isText: false },
[".json"]: { mime: "application/json", isText: true },
[".jsonld"]: { mime: "application/ld+json", isText: true },
[".xml"]: { mime: "application/xml", isText: true },
[".pdf"]: { mime: "application/pdf", isText: false },
[".zip"]: { mime: "application/zip", isText: false },
[".wasm"]: { mime: "application/wasm", isText: false },
};
const extensionData = extensions[ext as keyof typeof extensions];
const mime = extensionData?.mime ?? "application/octet-stream";
const charset =
extensionData?.isText && textEncoding !== "none"
? `;charset=${textEncoding}`
: "";
return `${mime}${charset}`;
}

function createServerWorker() {
return new Worker(
`${name}Server`,
Expand Down
50 changes: 4 additions & 46 deletions platform/src/components/cloudflare/static-site.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import fs from "fs";
import path from "path";
import crypto from "crypto";
import { ComponentResourceOptions, Output, all } from "@pulumi/pulumi";
import { ComponentResourceOptions, all } from "@pulumi/pulumi";
import { Kv, KvArgs } from "./kv.js";
import { Component, Transform, transform } from "../component.js";
import { Link } from "../link.js";
import { Input } from "../input.js";
import { globSync } from "glob";
import { KvData } from "./providers/kv-data.js";
import { Worker } from "./worker.js";
import { getContentType } from "../base/base-site.js";
import {
BaseStaticSiteArgs,
BaseStaticSiteAssets,
Expand Down Expand Up @@ -339,7 +340,8 @@ export class StaticSite extends Component implements Link.Linkable {
key: file,
hash,
cacheControl: fileOption.cacheControl,
contentType: getContentType(file, "UTF-8"),
contentType:
fileOption.contentType ?? getContentType(file, "UTF-8"),
};
}),
)),
Expand Down Expand Up @@ -371,50 +373,6 @@ export class StaticSite extends Component implements Link.Linkable {
);
}

function getContentType(filename: string, textEncoding: string) {
const ext = filename.endsWith(".well-known/site-association-json")
? ".json"
: path.extname(filename);
const extensions = {
[".txt"]: { mime: "text/plain", isText: true },
[".htm"]: { mime: "text/html", isText: true },
[".html"]: { mime: "text/html", isText: true },
[".xhtml"]: { mime: "application/xhtml+xml", isText: true },
[".css"]: { mime: "text/css", isText: true },
[".js"]: { mime: "text/javascript", isText: true },
[".mjs"]: { mime: "text/javascript", isText: true },
[".apng"]: { mime: "image/apng", isText: false },
[".avif"]: { mime: "image/avif", isText: false },
[".gif"]: { mime: "image/gif", isText: false },
[".jpeg"]: { mime: "image/jpeg", isText: false },
[".jpg"]: { mime: "image/jpeg", isText: false },
[".png"]: { mime: "image/png", isText: false },
[".svg"]: { mime: "image/svg+xml", isText: true },
[".bmp"]: { mime: "image/bmp", isText: false },
[".tiff"]: { mime: "image/tiff", isText: false },
[".webp"]: { mime: "image/webp", isText: false },
[".ico"]: { mime: "image/vnd.microsoft.icon", isText: false },
[".eot"]: { mime: "application/vnd.ms-fontobject", isText: false },
[".ttf"]: { mime: "font/ttf", isText: false },
[".otf"]: { mime: "font/otf", isText: false },
[".woff"]: { mime: "font/woff", isText: false },
[".woff2"]: { mime: "font/woff2", isText: false },
[".json"]: { mime: "application/json", isText: true },
[".jsonld"]: { mime: "application/ld+json", isText: true },
[".xml"]: { mime: "application/xml", isText: true },
[".pdf"]: { mime: "application/pdf", isText: false },
[".zip"]: { mime: "application/zip", isText: false },
[".wasm"]: { mime: "application/wasm", isText: false },
};
const extensionData = extensions[ext as keyof typeof extensions];
const mime = extensionData?.mime ?? "application/octet-stream";
const charset =
extensionData?.isText && textEncoding !== "none"
? `;charset=${textEncoding}`
: "";
return `${mime}${charset}`;
}

function createRouter() {
return new Worker(
`${name}Router`,
Expand Down

0 comments on commit ed7b080

Please sign in to comment.