Does go:embed embed.FS embeds directories or possible confusion with how it works

452 views
Skip to first unread message

Tajmeet Singh

unread,
Jul 5, 2021, 1:28:54 AM7/5/21
to golang-nuts
Hi there,

I have been testing the (relatively) new go:embed feature for a few days and I came across this situation which I wasn't quite sure what was causing it so I thought asking here would help.

Consider the following code:

```golang
package main

import (
"embed"
"fmt"
"log"
"net/http"
)

//go:embed files/static
var static embed.FS

func main() {
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(static))))
log.Fatal(http.ListenAndServe(":8000", nil))
}

```

Now the files in directory files/static are very much accessible but the issue I seem to have is that it was accessible under the url /static/files/static/filename instead of just being accessible through /static/filename where filename exists inside the directory files/static/

I tried looking up some examples online and it seems that I have to use the fs.FS and fs.Sub and only expose (not sure if this is correct terminology) the new fs.Sub which would mitigate the issue I was having.
 
My question is about the reason why the Go team went with this implementation? Because in the above program I wasn't able to access the files in files/ directory even though there were files in it and was only able to access files inside the files/static files directory. So there doesn't seem to be a point in this implementation unless I'm missing something, and I'm sure its the latter case haha. If anyone knows about why they went with this implementation, I would be very grateful.

Best wishes
Taj


Amnon

unread,
Jul 5, 2021, 2:30:37 PM7/5/21
to golang-nuts
What does

go list -f '{{ .EmbedFiles }}'

display?

Sean Liao

unread,
Jul 5, 2021, 3:56:28 PM7/5/21
to golang-nuts
`embed` embeds the files with the path you specified, so if you look into your `static` variable, the files will be available as `files/static/yourfile`.
This means there won't be issues with filename collisions etc... if you specify multiple patterns

If you want to serve your files in your `files/static` directory under the `/static/` url, your handler should be : `http.Handle("/static/", http.FileServer(http.FS(static.Sub("files"))))`
That is, for everything under the `/static` url, serve from the embedded filesystem, skipping over the `files/` prefix in the embedded fs.

Tajmeet Singh

unread,
Jul 9, 2021, 2:28:43 PM7/9/21
to golang-nuts
Ah okay, thanks seank. I was missing the fact that we can embed multiple files by specifying multiple patterns and assign it to a single `embed.FS`. Now it all makes sense. Thanks!

Shammi Shailaj

unread,
Jan 23, 2023, 2:51:08 PM1/23/23
to golang-nuts
There is no function named Sub() for the variable static of type embed.FS. Hence, the handler: http.Handle("/static/", http.FileServer(http.FS(static. Sub("files")))) shall not work and throw an error like:

static.Sub undefined (type embed.FS has no field or method Sub)

Can anyone provide a solution to this? I am looking for the same

Ian Lance Taylor

unread,
Jan 23, 2023, 3:22:40 PM1/23/23
to Shammi Shailaj, golang-nuts
On Mon, Jan 23, 2023 at 11:51 AM Shammi Shailaj <shammi...@gmail.com> wrote:
>
> There is no function named Sub() for the variable static of type embed.FS. Hence, the handler: http.Handle("/static/", http.FileServer(http.FS(static. Sub("files")))) shall not work and throw an error like:
>
> static.Sub undefined (type embed.FS has no field or method Sub)
>
> Can anyone provide a solution to this? I am looking for the same

Where it says static.Sub it should probably say fs.Sub(static, "files").

Ian
> --
> You received this message because you are subscribed to the Google Groups "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/ce27a16e-b4dc-46b2-8911-4c70f483c20bn%40googlegroups.com.

Shammi Shailaj

unread,
Jan 25, 2023, 2:42:35 AM1/25/23
to golang-nuts

Thanks Ian.

changing it to 

http.Handle("/static/", http.FileServer(http.FS(fs.Sub(static,"files"))))

did work.
Reply all
Reply to author
Forward
0 new messages