From 9903cf1090c95ebf53d6dbb991e63af6d098559a Mon Sep 17 00:00:00 2001
From: Zachary Skalko <zskalko@gmail.com>
Date: Wed, 15 May 2024 08:07:07 -0500
Subject: [PATCH] fix: Add appropriate response headers to SPA entry point HTML
 response (#6992)

## About the changes

Current state, when returning the HTML entry point from the server,
there are no headers attached. We encountered an issue with a deployment
and this had an impact for us.

A brief description:

1. We deployed the most recent version. Noticed an unrelated issue.
2. Users tried to use the most recent version and due to their client
cache, requested assets that did not exist in the newest version.
3. Our cache layer cached the assets that were not there with the HTML
response. It had to infer the type based on the filename because there
was no attached `Content-Type` header. This cache was very sticky.
4. After rolling back we saw the HTML response (from the cache) instead
of the appropriate response from the upstream Unleash application.

This PR does a few things.

1. When responding with the HTML entry point, it adds header
(`Content-Type: text/html`).
2. When the client is requesting an asset (a path that ends with an
extension), it also instructs the resource not to be cached
(`Cache-Control: no-cache`) and returns a 404. This will prevent misses
from getting cached.


## Discussion points

To me, there doesn't seem to be a lot of test infra on serving the SPA
application. If that is an error, please indicate where that is and an
appropriate test can be added.
---
 src/lib/app.ts | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/lib/app.ts b/src/lib/app.ts
index fad34a65f2..a49f979296 100644
--- a/src/lib/app.ts
+++ b/src/lib/app.ts
@@ -201,6 +201,7 @@ export default async function getApp(
     }
 
     app.get(`${baseUriPath}`, (req, res) => {
+        res.set('Content-Type', 'text/html');
         res.send(indexHTML);
     });
 
@@ -214,6 +215,14 @@ export default async function getApp(
     });
 
     app.get(`${baseUriPath}/*`, (req, res) => {
+        res.set('Content-Type', 'text/html');
+        const requestPath = path.parse(req.url);
+        // appropriately return 404 requests for assets with an extension (js, css, etc)
+        if (requestPath.ext !== '' && requestPath.ext !== 'html') {
+            res.set('Cache-Control', 'no-cache');
+            res.status(404).send(indexHTML);
+            return;
+        }
         res.send(indexHTML);
     });