2024-03-15 21:38:13 +00:00
|
|
|
// Package web defines the HTTP web server for static files and endpoints.
|
|
|
|
package web
|
2023-12-12 05:16:57 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"embed"
|
2023-12-30 15:37:04 +00:00
|
|
|
"io"
|
|
|
|
"io/fs"
|
2023-12-12 05:16:57 +00:00
|
|
|
"net"
|
|
|
|
"net/http"
|
2023-12-20 00:58:55 +00:00
|
|
|
"os"
|
2023-12-30 15:37:04 +00:00
|
|
|
"path"
|
2023-12-12 05:16:57 +00:00
|
|
|
"strings"
|
2023-12-20 00:58:55 +00:00
|
|
|
"time"
|
2023-12-12 05:16:57 +00:00
|
|
|
|
2023-12-19 15:12:45 +00:00
|
|
|
"github.com/gorilla/mux"
|
|
|
|
"go.opencensus.io/tag"
|
|
|
|
|
2024-03-15 21:38:13 +00:00
|
|
|
"github.com/filecoin-project/lotus/cmd/curio/deps"
|
|
|
|
"github.com/filecoin-project/lotus/curiosrc/web/api"
|
|
|
|
"github.com/filecoin-project/lotus/curiosrc/web/hapi"
|
2023-12-12 05:16:57 +00:00
|
|
|
"github.com/filecoin-project/lotus/metrics"
|
|
|
|
)
|
|
|
|
|
2023-12-30 15:37:04 +00:00
|
|
|
//go:embed static
|
2023-12-12 05:16:57 +00:00
|
|
|
var static embed.FS
|
|
|
|
|
2023-12-30 15:37:04 +00:00
|
|
|
var basePath = "/static/"
|
|
|
|
|
2023-12-20 00:58:55 +00:00
|
|
|
// An dev mode hack for no-restart changes to static and templates.
|
|
|
|
// You still need to recomplie the binary for changes to go code.
|
|
|
|
var webDev = os.Getenv("LOTUS_WEB_DEV") == "1"
|
|
|
|
|
2023-12-12 05:16:57 +00:00
|
|
|
func GetSrv(ctx context.Context, deps *deps.Deps) (*http.Server, error) {
|
2023-12-30 15:37:04 +00:00
|
|
|
mx := mux.NewRouter()
|
|
|
|
err := hapi.Routes(mx.PathPrefix("/hapi").Subrouter(), deps)
|
2023-12-19 01:23:40 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-12-30 15:37:04 +00:00
|
|
|
api.Routes(mx.PathPrefix("/api").Subrouter(), deps)
|
|
|
|
|
|
|
|
var static fs.FS = static
|
2023-12-20 00:58:55 +00:00
|
|
|
if webDev {
|
2024-03-15 21:38:13 +00:00
|
|
|
basePath = "cmd/curio/web/static"
|
|
|
|
static = os.DirFS(basePath)
|
2023-12-20 00:58:55 +00:00
|
|
|
}
|
2023-12-12 05:16:57 +00:00
|
|
|
|
2023-12-30 15:37:04 +00:00
|
|
|
mx.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
// If the request is for a directory, redirect to the index file.
|
|
|
|
if strings.HasSuffix(r.URL.Path, "/") {
|
|
|
|
r.URL.Path += "index.html"
|
|
|
|
}
|
|
|
|
|
|
|
|
file, err := static.Open(path.Join(basePath, r.URL.Path)[1:])
|
|
|
|
if err != nil {
|
|
|
|
w.WriteHeader(http.StatusNotFound)
|
2024-01-02 17:29:55 +00:00
|
|
|
_, _ = w.Write([]byte("404 Not Found"))
|
2023-12-30 15:37:04 +00:00
|
|
|
return
|
|
|
|
}
|
2024-01-02 17:29:55 +00:00
|
|
|
defer func() { _ = file.Close() }()
|
2023-12-30 15:37:04 +00:00
|
|
|
|
|
|
|
fileInfo, err := file.Stat()
|
|
|
|
if err != nil {
|
|
|
|
w.WriteHeader(http.StatusInternalServerError)
|
2024-01-02 17:29:55 +00:00
|
|
|
_, _ = w.Write([]byte("500 Internal Server Error"))
|
2023-12-30 15:37:04 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
http.ServeContent(w, r, fileInfo.Name(), fileInfo.ModTime(), file.(io.ReadSeeker))
|
|
|
|
})
|
|
|
|
|
2023-12-12 05:16:57 +00:00
|
|
|
return &http.Server{
|
2023-12-30 15:37:04 +00:00
|
|
|
Handler: http.HandlerFunc(mx.ServeHTTP),
|
2023-12-12 05:16:57 +00:00
|
|
|
BaseContext: func(listener net.Listener) context.Context {
|
2024-03-15 21:38:13 +00:00
|
|
|
ctx, _ := tag.New(context.Background(), tag.Upsert(metrics.APIInterface, "curio"))
|
2023-12-12 05:16:57 +00:00
|
|
|
return ctx
|
|
|
|
},
|
2023-12-20 00:58:55 +00:00
|
|
|
Addr: deps.Cfg.Subsystems.GuiAddress,
|
|
|
|
ReadTimeout: time.Minute * 3,
|
|
|
|
ReadHeaderTimeout: time.Minute * 3, // lint
|
2023-12-12 05:16:57 +00:00
|
|
|
}, nil
|
|
|
|
}
|