0

I have the following directory structure for my static web site:

│   infinote.exe
└───spa
    │   favicon.ico
    │   index.html
    │
    ├───css
    │       app.f99f51d4.css
    │       vendor.d9e2261d.css
    │
    ├───fonts
    │       flUhRq6tzZclQEJ-Vdg-IuiaDsNa.40fa1be9.woff
    │       flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.cf9862e8.woff2
    │       KFOkCnqEu92Fr1MmgVxIIzQ.9391e6e2.woff
    │       KFOlCnqEu92Fr1MmEU9fBBc-.ddd11dab.woff
    │       KFOlCnqEu92Fr1MmSU5fBBc-.877b9231.woff
    │       KFOlCnqEu92Fr1MmWUlfBBc-.0344cc3c.woff
    │       KFOlCnqEu92Fr1MmYUtfBBc-.b555d228.woff
    │       KFOmCnqEu92Fr1Mu4mxM.9b78ea3b.woff
    │       PatuaOne-Regular.ttf
    │       Poppins-Regular.ttf
    │
    ├───icons
    │       apple-icon-120x120.png
    │       apple-launch-828x1792.png
    │       favicon-128x128.png
    │       favicon-16x16.png
    │       favicon-32x32.png
    │       favicon-96x96.png
    │       icon-128x128.png
    │       safari-pinned-tab.svg
    │
    └───js
            app.3a5b0240.js
            vendor.a9a3886c.js

infinote.exe is a binary compiled from Go and the line where I define how to serve the web site is

r.Handle("/spa/", http.StripPrefix("/spa/", http.FileServer(http.Dir("./spa"))))

I use chi as the router, and r := chi.NewRouter().

I expect http://example.com/spa/ to:

  • first request http://example.com/spa/ → this is ./spa/index.html
  • and then after parsing index.html, to request other files in ./spa
    • An example would be http://example.com/spa/js/vendor.a9a3886c.js./spa/js/vendor.a9a3886c.js

What happens is that index.html is retrieved correctly, and then all the referenced files return a 404 Not Found.

To be frank I do not exactly understand the mechanics (and need) of http.StripPrefix. Is this because the files in spa are relative to the full URL, in other words to ./spa/spa/...- which is not correct (and thus the need to strip app first)?

If so, why is only index.html retrieved correctly? Even favicon.ico is a 404 despite being in the same directory as index.html.

WoJ
  • 27,165
  • 48
  • 180
  • 345

1 Answers1

0

All credit goes to @mkopriva and @Zombo whose comments were, for some reason, deleted

After several iterations and tests, I managed to find a working version:

r.Handle("/spa/*",http.StripPrefix("/spa/", ttp.FileServer(http.Dir("spa"))))

The key part was the * in the first "pattern". I did not find anything about wildcards in the documentation but with a * it works - and without it does not (I get the 404`).

I would be delighted to have an answer that is better than that

WoJ
  • 27,165
  • 48
  • 180
  • 345
  • `*` is not a wildcard in the standard library's [`net/http.ServeMux`](https://pkg.go.dev/net/http@go1.18.1#ServeMux). It has no special meaning. So if you say it works with `*` but not without, then that means you're not using the `net/http` package for *routing*. You're using something else. What is `r`? – mkopriva May 11 '22 at 14:58
  • When you use `net/http.ServeMux` then using `"/spa/"` will match requests to `/spa/` but also any requests that begin with `/spa/`, e.g. `/spa/js/vendor.a9a3886c.js`. And when you use `/spa` then only requests to `/spa` will be matched (and `/spa/` will automatically be redirected to `/spa` I believe), requests to other paths will not be handled. – mkopriva May 11 '22 at 15:04
  • Thi sis a good point, I completely forgot to mention it. I use [`chi`](https://github.com/go-chi/chi) and `r := chi.NewRouter()`. I do not see anything special about patterns in the docs, though. I updated the question as well – WoJ May 11 '22 at 15:27
  • Right there in the package's [overview](https://pkg.go.dev/github.com/go-chi/chi@v1.5.4#pkg-overview) it mentions patterns, named placeholders, placeholders with regexp, and placeholders with asterisks. Examples are also included. Also at the bottom of the "Router Interface" section of the README, just above the ["Middleware handlers"](https://pkg.go.dev/github.com/go-chi/chi@v1.5.4#readme-middleware-handlers) section, you can see patterns and wildcards mentioned. – mkopriva May 11 '22 at 15:58
  • @mkopriva: thank you very much. I am new to Go and I realize now that the way the language and libraries are documented is different from what I know (as an amateur developer). The documentation in pkg.go.dev is really the reference, including discussions on usage, examples etc - I was rather relying on it as a kind of "API reference" with limited information outside of the technical usage. Thanks for pointing out the references as you did - I will from now on navigate all the docs for such libraries as what I am looking for is there, and not in the github repository . That was really useful. – WoJ May 12 '22 at 06:44