90 lines
2.0 KiB
Go
90 lines
2.0 KiB
Go
package web
|
|
|
|
import (
|
|
"fmt"
|
|
"html/template"
|
|
"net"
|
|
"os"
|
|
"strings"
|
|
|
|
"speedtest/config"
|
|
"speedtest/internal/store"
|
|
"speedtest/internal/web/handlers"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// WebServer wraps the Gin engine and its dependencies.
|
|
type WebServer struct {
|
|
engine *gin.Engine
|
|
stores *store.Stores
|
|
cfg config.Config
|
|
}
|
|
|
|
// NewWebServer creates a new WebServer, initializes the Gin engine and registers routes.
|
|
func NewWebServer(cfg config.Config, stores *store.Stores) (*WebServer, error) {
|
|
gin.SetMode(gin.ReleaseMode)
|
|
engine := gin.New()
|
|
engine.Use(gin.Logger())
|
|
engine.Use(gin.Recovery())
|
|
|
|
// 不信任默认代理(真实 IP 通过 X-Real-IP 头由 Caddy 注入,自行解析)
|
|
_ = engine.SetTrustedProxies(nil)
|
|
|
|
// 加载 HTML 模板
|
|
tmpl := template.Must(template.New("").ParseGlob("internal/web/templates/*.html"))
|
|
engine.SetHTMLTemplate(tmpl)
|
|
|
|
handler, err := handlers.NewHandler(stores, cfg.Speedtest)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
ws := &WebServer{
|
|
engine: engine,
|
|
stores: stores,
|
|
cfg: cfg,
|
|
}
|
|
|
|
// 页面
|
|
engine.GET("/", func(c *gin.Context) {
|
|
c.HTML(200, "index.html", gin.H{})
|
|
})
|
|
|
|
// 测速 API
|
|
api := engine.Group("/api")
|
|
{
|
|
api.GET("/ping", handler.Ping)
|
|
api.GET("/download", handler.Download)
|
|
api.POST("/upload", handler.Upload)
|
|
api.POST("/result", handler.Result)
|
|
api.GET("/rankings", handler.Rankings)
|
|
}
|
|
|
|
return ws, nil
|
|
}
|
|
|
|
// Start launches the HTTP server on the configured address.
|
|
// Supports both TCP (e.g. ":8080") and Unix socket (e.g. "/opt/speedtest/web.sock").
|
|
func (ws *WebServer) Start() error {
|
|
addr := ws.cfg.Web.Addr
|
|
|
|
// Unix socket:地址以 / 开头
|
|
if strings.HasPrefix(addr, "/") {
|
|
// 清理旧的 socket 文件
|
|
os.Remove(addr)
|
|
|
|
listener, err := net.Listen("unix", addr)
|
|
if err != nil {
|
|
return fmt.Errorf("监听 Unix socket 失败 %s: %w", addr, err)
|
|
}
|
|
// 允许 caddy 等外部进程连接
|
|
os.Chmod(addr, 0666)
|
|
|
|
return ws.engine.RunListener(listener)
|
|
}
|
|
|
|
// TCP 端口
|
|
return ws.engine.Run(addr)
|
|
}
|