Skip to main content
Glama
useCachedBinaryUrl.ts2.59 kB
// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors // SPDX-License-Identifier: Apache-2.0 import { useMemo } from 'react'; // Maintain a cache of urls to avoid unnecessary re-download of attachments // The following is a workaround for the fact that each request to a resource containing a Binary data reference // returns a NEW signed S3 URL for each bypassing the native browser caching mechanism // resulting in unnecessary bandwidth consumption. // https://www.medplum.com/docs/fhir-datastore/binary-data#consuming-a-fhir-binary-in-an-application // https://github.com/medplum/medplum/issues/3815 // The S3 presigned URLs expire after 1 hour with the default configuration and hard refreshes are not uncommon even in SPAs so this // could be a good way to get additional cache hits // This would require additional logic for initialization, saving, and purging of expired keys const urls = new Map<string, string>(); export const useCachedBinaryUrl = (binaryUrl: string | undefined): string | undefined => { return useMemo(() => { if (!binaryUrl) { return undefined; } const binaryResourceUrl = binaryUrl.split('?')[0]; if (!binaryResourceUrl) { return binaryUrl; } // Check if the binaryUrl is a presigned S3 URL let binaryUrlSearchParams: URLSearchParams; try { binaryUrlSearchParams = new URLSearchParams(new URL(binaryUrl).search); } catch (_err) { return binaryUrl; } if (!binaryUrlSearchParams.has('Key-Pair-Id') || !binaryUrlSearchParams.has('Signature')) { return binaryUrl; } // https://stackoverflow.com/questions/23929145/how-to-test-if-a-given-time-stamp-is-in-seconds-or-milliseconds const binaryUrlExpires = binaryUrlSearchParams.get('Expires'); if (!binaryUrlExpires || binaryUrlExpires.length > 13) { // Expires is expected to be in seconds, not milliseconds return binaryUrl; } const cachedUrl = urls.get(binaryResourceUrl); if (cachedUrl) { const searchParams = new URLSearchParams(new URL(cachedUrl).search); // This is fairly brittle as it relies on the current structure of the Medplum returned URL const expires = searchParams.get('Expires'); // `expires` is in seconds, Date.now() is in ms // Add padding to mitigate expiration between time of check and time of use if (expires && Number.parseInt(expires, 10) * 1000 - 5_000 > Date.now()) { return cachedUrl; } } urls.set(binaryResourceUrl, binaryUrl); return binaryUrl; }, [binaryUrl]); };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/medplum/medplum'

If you have feedback or need assistance with the MCP directory API, please join our Discord server