Is embedding a directory supported for cross-compilation? - go

Summary of the problem: access to embedded files in directories work for a native compilation but not for cross-compiled code
I have the following code that embeds a file (static/index.html) in a directory and exposes it via HTTP:
package main
import (
"embed"
"net/http"
"os"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
"github.com/rs/cors"
"github.com/rs/zerolog/log"
)
//go:embed static
var content embed.FS
func main() {
// API and static site
r := mux.NewRouter()
r.Use(mux.CORSMethodMiddleware(r))
r.Use(func(next http.Handler) http.Handler {
return handlers.LoggingHandler(os.Stdout, next)
})
c := cors.New(cors.Options{
AllowCredentials: true,
//Debug: true,
})
handler := c.Handler(r)
r.PathPrefix("/").Handler(http.FileServer(http.Dir("./static/")))
log.Info().Msg("starting dash webserver at port 1495")
_ = http.ListenAndServe("0.0.0.0:1495", handler)
}
I compiled this code (go1.16.7) in Windows 10 WSL2 (EDIT: and in native Windows 10) via go build -o goembed.wsl2. When started, running curl localhost:1495 gives the right result (the text in index.html).
I then compiled it (still in WSL2/Win10) via env GOOS=linux GOARCH=amd64 go build -o goembed.linux (or the relevant incantation in Windows 10 to set the environment variables) and started goembed.linux on an Ubuntu 18.04 server.
The program started but the output of curl localhost:1495 was 404 File Not Found.
Why is it so?
Interestingly, embedding a single file (the variable containing it is then of type []byte) exposes it correctly via the HTTP server in both binaries (the native WSL one, and the amd64).
EDIT: I have the same behaviour when compiling in native Windows 10, I updated the references above

It is a mistake from my side: I embed static but serve ./static/ which is the local (OS) directory, instead of the embedded one. It should be:
r.PathPrefix("/").Handler(http.FileServer(http.FS(content)))

Related

Simple golang server script not working as exe

I found a golang script to run a localhost server. This is it,
server.go
package main
import (
"log"
"net/http"
)
func main() {
http.Handle("/", http.FileServer(http.Dir("G:/build")))
log.Fatal(http.ListenAndServe(":8080", nil))
}
It works fine serving "G:/build" folder, but I want to build it as an exe file. I read that I have to use os.Args[1] to get the first command line argument, so I added it like this -
package main
import (
"log"
"net/http"
)
func main() {
http.Handle("/", http.FileServer(http.Dir("os.Args[1]")))
log.Fatal(http.ListenAndServe(":8080", nil))
}
When I build the exe it builds fine with no errors. If I run the exe with the only argument as "g:/build" I get no errors and no webpage on my browser at localhost:8080. Sort of stuck now. Anything obviously wrong? I'm on Windows (had to use front slashes in the folder path as shown). I also tried importing "os" but it would not even build (said I'm not using it), which seems strange since I'm using "os.Args[1]" in the code??

Flutter web with Golang Server

Is it possible to run flutter web build using golang server? Golang has facility to serve html file and flutter web gives output as index.html and js files.
if it is possible then how golang code should look like?
as the friendly doc mentions it, i believe you got to build your app.
https://flutter.dev/docs/get-started/web#build
Run the following command to generate a release build:
flutter build web
This populates a build/web directory with built files, including an assets directory, which need to be served together.
how golang code should look like?
like any other regular HTTP golang server.
http.Handle("/build/web/", http.StripPrefix("/build/web/", http.FileServer(http.Dir("build/web"))))
http.ListenAndServe(":8080", nil)
package main
import (
"flag"
"log"
"net/http"
)
func main() {
port := flag.String("p", "8181", "port to serve on")
directory := flag.String("d", "web", "the directory of static file to host")
flag.Parse()
http.Handle("/", http.FileServer(http.Dir(*directory)))
log.Printf("Serving %s on HTTP port: %s\n", *directory, *port)
log.Fatal(http.ListenAndServe(":"+*port, nil))
}
Just copy web folder to your's go app.

Go web server 404 page not found

I am new to web assembly
I write a web.go to server index.html wasm_exec.js main.wasm under directory Hello_WebAssembly
Then I go run web.go in terminal
Then i go to localhost:8080 it reports 404 page not found
I am following the instructions https://github.com/golang/go/wiki/WebAssembly
Here is my web.go code
package main
import (
"log"
"net/http"
)
func main() {
fs := http.FileServer(http.Dir("Hello_WebAssembly"))
http.Handle("/", fs)
log.Println("Listening...")
http.ListenAndServe(":8080", nil)
}
I don't know why
Hope someone can help me out
Thanks in advance
By the way my OS is win10
I presume your project is called Hello_WebAssembly and you are running the go run command from within the folder.
If this is the case, then your http.Dirinvocation should be http.Dir(".") as you want to serve resources from your current directory (the Project).

How do I set GODEBUG environment variables in Golang so I can use godebug with net/http

I want to step through my program using Godebug. However because I'm using net/http I get errors such as:
/home/heath/go/src/net/http/h2_bundle.go:45:2: could not import golang_org/x/net/http2/hpack (cannot find package "golang_org/x/net/http2/hpack" in any of:
/home/heath/go/src/golang_org/x/net/http2/hpack (from $GOROOT)
/x/net/http2/hpack does exist in my GOPATH but in ~heath/go/src/golang.org ... not golang_org (not sure what's happening there)
I have read that this error occurs because godebug doesn't support http2 yet (can't find source).
I have tried to disable http2server and http2client by setting the GODEBUG env both in init() and on the command line. I have also confirmed that these settings are being set by doing a fmt.Println("GODEBUG", os.Getenv("GODEBUG"). As per instructions located here
GODEBUG=http2client=0 # disable HTTP/2 client support
GODEBUG=http2server=0 # disable HTTP/2 server support
My simple code example to replicate the error is:
package main
import "fmt"
import "net/http"
import "os"
func init() {
os.Setenv("GODEBUG", "http2server=0,http2client=0")
}
func main() {
fmt.Println("GODEBUG", os.Getenv("GODEBUG"))
_ = "breakpoint"
fmt.Println("Hello, World!")
http.ListenAndServe(":8080", nil)
}
godebug run example.go
I am running Go version:
go version go1.7 linux/amd64
This is probably not the correct way to do things. But I copied the http2 package from my vendor directory under $GOROOT/src/vendor to the src directory under my $GOPATH/src.
If anyone has any further input on the correct way to reference vendor directories please add your thoughts. Just putting my workaround here in case someone else comes across the same issue.
Edit: Actually a 'nicer' way to do things was to do an ln -s ..src/vender/github_org to ../src/github_org

"go run" but notice me missing .a file (I have run "go get")

I want to run a go file, main package imported a local package which imported a github package. and get an error (missing .a file)
ENV:
$GOROOT=/usr/local/go
$GOPATH=/gopath
go version 1.6.3 (same problem in 1.6.2)
I tried to run a go file like this:
/gopath/src/myproj/main/app.go
package main
import (
"../http/server"
)
func main() {
server.Run()
}
/gopath/src/myproj/http/server/route.go
package server
import (
"github.com/gorilla/mux"
"net/http"
)
func Run(){
router := mux.NewRouter()
router.HandleFunc("/", handler)
http.Handle("/", router)
http.ListenAndServe("9090", nil)
}
func handler(res http.ResponseWriter, req *http.Request) {
res.Write([]byte("Hello"))
}
then,I run go get github.com/gorilla/mux and I can see there are files
/gopath/pkg/linux_amd64/github.com/gorilla/mux (there are context.a and mux.a)
/gopath/src/github.com/gorilla/mux
/gopath/src/github.com/gorilla/context
Yes, src file and pkg file(.a) has downloaded form github,
BUT , I run "go run main/app.go" , get
# command-line-arguments
/usr/local/go/pkg/tool/linux_amd64/link: cannot open file /usr/local/go/pkg/linux_amd64/github.com/gorilla/mux.a: open /usr/local/go/pkg/linux_amd64/github.com/gorilla/mux.a: no such file or directory
compiler does not find file in GOPATH, but GOROOT
if I copy $GOPATH/pkg files to $GOROOT/pkg was good.
And, if I import github.com/gorilla/mux in main package directly was fine too.
As JimB said don't use relative paths for imports
if you change "../http/server" to myproj/http/server it shouldn't have the linking problems anymore

Resources