package controller import ( "fmt" "log" "net/http" "time" jwt "github.com/appleboy/gin-jwt/v2" "github.com/gin-contrib/pprof" "github.com/gin-gonic/gin" "github.com/hashicorp/go-uuid" swaggerfiles "github.com/swaggo/files" ginSwagger "github.com/swaggo/gin-swagger" docs "github.com/naiba/nezha/cmd/dashboard/docs" "github.com/naiba/nezha/model" "github.com/naiba/nezha/pkg/mygin" "github.com/naiba/nezha/pkg/utils" "github.com/naiba/nezha/proto" "github.com/naiba/nezha/service/rpc" "github.com/naiba/nezha/service/singleton" ) // @title Swagger Example API // @version 1.0 // @description This is a sample server celler server. // @termsOfService http://swagger.io/terms/ // @contact.name API Support // @contact.url http://www.swagger.io/support // @contact.email support@swagger.io // @license.name Apache 2.0 // @license.url http://www.apache.org/licenses/LICENSE-2.0.html // @host localhost:8080 // @BasePath /api/v1 // @securityDefinitions.basic BasicAuth // @externalDocs.description OpenAPI // @externalDocs.url https://swagger.io/resources/open-api/ func ServeWeb(port uint) *http.Server { gin.SetMode(gin.ReleaseMode) r := gin.Default() docs.SwaggerInfo.BasePath = "/api/v1" if singleton.Conf.Debug { gin.SetMode(gin.DebugMode) pprof.Register(r) } r.Use(natGateway) r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler)) r.Use(mygin.RecordPath) routers(r) page404 := func(c *gin.Context) { mygin.ShowErrorPage(c, mygin.ErrInfo{ Code: http.StatusNotFound, Title: "该页面不存在", Msg: "该页面内容可能已着陆火星", Link: "/", Btn: "返回首页", }, true) } r.NoRoute(page404) r.NoMethod(page404) srv := &http.Server{ Addr: fmt.Sprintf(":%d", port), ReadHeaderTimeout: time.Second * 5, Handler: r, } return srv } func routers(r *gin.Engine) { authMiddleware, err := jwt.New(initParams()) if err != nil { log.Fatal("JWT Error:" + err.Error()) } // register middleware r.Use(handlerMiddleWare(authMiddleware)) r.POST("/login", authMiddleware.LoginHandler) auth := r.Group("/auth", authMiddleware.MiddlewareFunc()) auth.GET("/refresh_token", authMiddleware.RefreshHandler) // 通用页面 cp := commonPage{r: r} cp.serve() // 游客页面 gp := guestPage{r} gp.serve() // 会员页面 mp := &memberPage{r} mp.serve() // API api := r.Group("api") { ma := &memberAPI{api} ma.serve() } } func natGateway(c *gin.Context) { natConfig := singleton.GetNATConfigByDomain(c.Request.Host) if natConfig == nil { return } singleton.ServerLock.RLock() server := singleton.ServerList[natConfig.ServerID] singleton.ServerLock.RUnlock() if server == nil || server.TaskStream == nil { c.Writer.WriteString("server not found or not connected") c.Abort() return } streamId, err := uuid.GenerateUUID() if err != nil { c.Writer.WriteString(fmt.Sprintf("stream id error: %v", err)) c.Abort() return } rpc.NezhaHandlerSingleton.CreateStream(streamId) defer rpc.NezhaHandlerSingleton.CloseStream(streamId) taskData, err := utils.Json.Marshal(model.TaskNAT{ StreamID: streamId, Host: natConfig.Host, }) if err != nil { c.Writer.WriteString(fmt.Sprintf("task data error: %v", err)) c.Abort() return } if err := server.TaskStream.Send(&proto.Task{ Type: model.TaskTypeNAT, Data: string(taskData), }); err != nil { c.Writer.WriteString(fmt.Sprintf("send task error: %v", err)) c.Abort() return } w, err := utils.NewRequestWrapper(c.Request, c.Writer) if err != nil { c.Writer.WriteString(fmt.Sprintf("request wrapper error: %v", err)) c.Abort() return } if err := rpc.NezhaHandlerSingleton.UserConnected(streamId, w); err != nil { c.Writer.WriteString(fmt.Sprintf("user connected error: %v", err)) c.Abort() return } rpc.NezhaHandlerSingleton.StartStream(streamId, time.Second*10) c.Abort() }