Skip to content

Commit

Permalink
Merge pull request #881 from posit-dev/mm-fallback-handler
Browse files Browse the repository at this point in the history
Add fallback handler for 404s
  • Loading branch information
mmarchetti authored Jan 26, 2024
2 parents b9250cc + bfa0662 commit 20c87e0
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 4 deletions.
61 changes: 61 additions & 0 deletions internal/services/middleware/404_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package middleware

// Copyright (C) 2023 by Posit Software, PBC.

import "net/http"

type notFoundWriter struct {
writer http.ResponseWriter
header http.Header
StatusCode int
}

func newNotFoundWriter(w http.ResponseWriter) *notFoundWriter {
return &notFoundWriter{
writer: w,
header: http.Header{},
}
}

func (w *notFoundWriter) Header() http.Header {
// Capture the header sent by the underlying handler,
// and decide later whether to send it.
return w.header
}

func (w *notFoundWriter) Write(data []byte) (int, error) {
if w.StatusCode != http.StatusNotFound {
// We have a valid response, send it.
return w.writer.Write(data)
} else {
// Eat this response and we'll serve up a better one
return len(data), nil
}
}

func (w *notFoundWriter) WriteHeader(statusCode int) {
w.StatusCode = statusCode
if statusCode != http.StatusNotFound {
// Valid response from the underlying handler.
// Respond with the headers that handler provided.
realHeader := w.writer.Header()
for k, v := range w.header {
realHeader[k] = v
}
w.writer.WriteHeader(statusCode)
}
}

func ServeIndexOn404(h http.Handler, location string) http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
writer := newNotFoundWriter(w)
h.ServeHTTP(writer, req)

if writer.StatusCode == http.StatusNotFound {
// Serve the index.html page and let the frontend handle routing
req.URL.Path = "/"
req.URL.RawPath = "/"
h.ServeHTTP(w, req)
}
}
}
10 changes: 7 additions & 3 deletions internal/services/ui/ui_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,17 @@ func RouterHandlerFunc(base util.Path, lister accounts.AccountList, log logging.
r.Handle(ToPath("deployments", "{name}"), api.DeleteDeploymentHandlerFunc(base, log)).
Methods(http.MethodDelete)

// GET /
// Handle any frontend paths that leak out (for example, on a refresh)
// by redirecting to the SPA at "/".

// GET /<anything>
// Serves static files from /web/dist.
fileHandler := middleware.InsertPrefix(web.Handler, web.Prefix)
r.PathPrefix("/").
Handler(middleware.InsertPrefix(web.Handler, web.Prefix)).
Handler(middleware.ServeIndexOn404(fileHandler, "/")).
Methods("GET")

c := cors.AllowAll().Handler(r)

return c.ServeHTTP
}

Expand Down
2 changes: 1 addition & 1 deletion web/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { quasar, transformAssetUrls } from '@quasar/vite-plugin';
// https://vitejs.dev/config/
// eslint-disable-next-line no-restricted-syntax
export default defineConfig({
base: './',
base: '/',
build: {
rollupOptions: {
output: {
Expand Down

0 comments on commit 20c87e0

Please sign in to comment.