From c32a19f9fbf63744a9c469da91ce988f7241b802 Mon Sep 17 00:00:00 2001 From: Rahul Mishra Date: Sun, 1 Sep 2024 14:55:53 +0530 Subject: [PATCH] chore: add cache headers to storage proxies (#762) --- .../trpc/routers/convoRouter/convoRouter.ts | 2 +- apps/storage/proxy/attachment.ts | 6 ++++-- apps/storage/proxy/avatars.ts | 9 +++++++-- apps/storage/proxy/inline-proxy.ts | 6 ++++-- .../[convoId]/_components/messages-panel.tsx | 5 +---- apps/web/src/components/editor/index.tsx | 2 -- packages/tiptap/extensions/index.ts | 18 ------------------ 7 files changed, 17 insertions(+), 31 deletions(-) diff --git a/apps/platform/trpc/routers/convoRouter/convoRouter.ts b/apps/platform/trpc/routers/convoRouter/convoRouter.ts index e1693cf8..fd719827 100644 --- a/apps/platform/trpc/routers/convoRouter/convoRouter.ts +++ b/apps/platform/trpc/routers/convoRouter/convoRouter.ts @@ -53,7 +53,7 @@ import { TRPCError } from '@trpc/server'; import { env } from '~platform/env'; import { z } from 'zod'; -const tipTapExtensions = createExtensionSet({ storageUrl: env.STORAGE_URL }); +const tipTapExtensions = createExtensionSet(); type Attachment = { orgPublicId: TypeId<'org'>; diff --git a/apps/storage/proxy/attachment.ts b/apps/storage/proxy/attachment.ts index b12e4d9a..8fdce595 100644 --- a/apps/storage/proxy/attachment.ts +++ b/apps/storage/proxy/attachment.ts @@ -75,13 +75,15 @@ export const attachmentProxy = createHonoApp().get( Key: `${attachmentQueryResponse.org.publicId}/${attachmentId}/${filename}` }); const url = await getSignedUrl(s3Client, command, { expiresIn: 3600 }); - const res = await fetch(url).then((res) => c.body(res.body, res)); + const res = await fetch(url); if (!res.ok) { return c.json( { error: 'Error while fetching attachment' }, { status: 500 } ); } - return res; + // Cache for 1 hour + c.header('Cache-Control', 'private, max-age=3600'); + return c.body(res.body); } ); diff --git a/apps/storage/proxy/avatars.ts b/apps/storage/proxy/avatars.ts index aca6257d..fb8131dc 100644 --- a/apps/storage/proxy/avatars.ts +++ b/apps/storage/proxy/avatars.ts @@ -9,10 +9,15 @@ export const avatarProxy = createHonoApp().get( const proxy = c.req.param('proxy'); const res = await fetch( `${env.STORAGE_S3_ENDPOINT}/${env.STORAGE_S3_BUCKET_AVATARS}/${proxy}` - ).then((res) => c.body(res.body, res)); + ); if (res.status === 404) { return c.json({ error: 'Not Found' }, 404); } - return res; + // Avatars are immutable so we can cache them for a long time + c.header( + 'Cache-Control', + 'public, immutable, max-age=86400, stale-while-revalidate=604800' + ); + return c.body(res.body, res); } ); diff --git a/apps/storage/proxy/inline-proxy.ts b/apps/storage/proxy/inline-proxy.ts index 29d67026..3727455b 100644 --- a/apps/storage/proxy/inline-proxy.ts +++ b/apps/storage/proxy/inline-proxy.ts @@ -69,13 +69,15 @@ export const inlineProxy = createHonoApp() Key: `${attachmentQueryResponse.org.publicId}/${attachmentId}/${filename}` }); const url = await getSignedUrl(s3Client, command, { expiresIn: 3600 }); - const res = await fetch(url).then((res) => c.body(res.body, res)); + const res = await fetch(url); if (!res.ok) { return c.json( { error: 'Error while fetching attachment' }, { status: 500 } ); } - return res; + // Cache for 1 hour + c.header('Cache-Control', 'private, max-age=3600'); + return c.body(res.body, res); } ); diff --git a/apps/web/src/app/[orgShortcode]/convo/[convoId]/_components/messages-panel.tsx b/apps/web/src/app/[orgShortcode]/convo/[convoId]/_components/messages-panel.tsx index 888284e7..85635966 100644 --- a/apps/web/src/app/[orgShortcode]/convo/[convoId]/_components/messages-panel.tsx +++ b/apps/web/src/app/[orgShortcode]/convo/[convoId]/_components/messages-panel.tsx @@ -35,7 +35,6 @@ import { type TypeId } from '@u22n/utils/typeid'; import { cva } from 'class-variance-authority'; import { cn } from '@/src/lib/utils'; import { ms } from '@u22n/utils/ms'; -import { env } from '@/src/env'; import { useAtom } from 'jotai'; import { toast } from 'sonner'; @@ -209,9 +208,7 @@ export const MessagesPanel = memo( MessagesPanel.displayName = 'MessagesPanel'; -const tipTapExtensions = createExtensionSet({ - storageUrl: env.NEXT_PUBLIC_STORAGE_URL -}); +const tipTapExtensions = createExtensionSet(); const MessageItem = memo( function MessageItem({ diff --git a/apps/web/src/components/editor/index.tsx b/apps/web/src/components/editor/index.tsx index 24d35387..52107952 100644 --- a/apps/web/src/components/editor/index.tsx +++ b/apps/web/src/components/editor/index.tsx @@ -27,10 +27,8 @@ import { slashCommand, suggestionItems } from './slash-commands'; import { createExtensionSet } from '@u22n/tiptap/extensions'; import { useIsMobile } from '@/src/hooks/use-is-mobile'; import { forwardRef, memo, useState } from 'react'; -import { env } from '@/src/env'; const tipTapExtensions = createExtensionSet({ - storageUrl: env.NEXT_PUBLIC_STORAGE_URL, className: { placeholderImage: 'rounded-md border opacity-50' } diff --git a/packages/tiptap/extensions/index.ts b/packages/tiptap/extensions/index.ts index a8cf7168..d66cb27a 100644 --- a/packages/tiptap/extensions/index.ts +++ b/packages/tiptap/extensions/index.ts @@ -12,7 +12,6 @@ import _ExtensionLink from '@tiptap/extension-link'; import { type AnyExtension } from '@tiptap/react'; type CreateExtensionSetOptions = { - storageUrl?: string; className?: { link?: string; image?: string; @@ -21,7 +20,6 @@ type CreateExtensionSetOptions = { }; export const createExtensionSet = ({ - storageUrl, className }: CreateExtensionSetOptions = {}) => { const ExtensionImage = ExtensionImageResize.extend({ @@ -36,22 +34,6 @@ export const createExtensionSet = ({ } }; }, - renderHTML: ({ HTMLAttributes, node }) => { - const isInternalImage = - storageUrl && - typeof node.attrs.src === 'string' && - node.attrs.src.startsWith(storageUrl); - return [ - 'img', - isInternalImage - ? { - ...node.attrs, - ...HTMLAttributes, - crossorigin: 'use-credentials' - } - : { ...node.attrs, ...HTMLAttributes } - ]; - }, addProseMirrorPlugins: () => { return [ UploadImagesPlugin({