diff --git a/conf/frps.ini b/conf/frps.ini index 91b06297..e252b533 100644 --- a/conf/frps.ini +++ b/conf/frps.ini @@ -2,8 +2,10 @@ [common] bind_addr = 0.0.0.0 bind_port = 7000 -# optional +# if you want to support virtual host, you must set the http port for listening (optional) vhost_http_port = 80 +# if you want to configure or reload frps by dashboard, dashboard_port is needed +dashboard_port = 7500 # console or real logFile path like ./frps.log log_file = ./frps.log # debug, info, warn, error diff --git a/src/frp/cmd/frps/main.go b/src/frp/cmd/frps/main.go index a23f3fb9..97ba737e 100644 --- a/src/frp/cmd/frps/main.go +++ b/src/frp/cmd/frps/main.go @@ -111,6 +111,15 @@ func main() { } } + // create dashboard web server if DashboardPort != 0 + if server.DashboardPort != 0 { + err := server.RunDashboardServer(server.BindAddr, server.DashboardPort) + if err != nil { + log.Error("Create dashboard web server error, %v", err) + os.Exit(1) + } + } + log.Info("Start frps success") ProcessControlConn(l) } diff --git a/src/frp/models/server/config.go b/src/frp/models/server/config.go index 28e096cd..b5684117 100644 --- a/src/frp/models/server/config.go +++ b/src/frp/models/server/config.go @@ -28,7 +28,8 @@ import ( var ( BindAddr string = "0.0.0.0" BindPort int64 = 7000 - VhostHttpPort int64 = 0 // if VhostHttpPort equals 0, do not listen a public port for http + VhostHttpPort int64 = 0 // if VhostHttpPort equals 0, don't listen a public port for http + DashboardPort int64 = 0 // if DashboardPort equals 0, dashboard is not available LogFile string = "console" LogWay string = "console" // console or file LogLevel string = "info" @@ -68,6 +69,13 @@ func LoadConf(confFile string) (err error) { VhostHttpPort = 0 } + tmpStr, ok = conf.Get("common", "dashboard_port") + if ok { + DashboardPort, _ = strconv.ParseInt(tmpStr, 10, 64) + } else { + DashboardPort = 0 + } + tmpStr, ok = conf.Get("common", "log_file") if ok { LogFile = tmpStr diff --git a/src/frp/models/server/dashboard.go b/src/frp/models/server/dashboard.go new file mode 100644 index 00000000..e8dd8323 --- /dev/null +++ b/src/frp/models/server/dashboard.go @@ -0,0 +1,35 @@ +// Copyright 2016 fatedier, fatedier@gmail.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package server + +import ( + "fmt" + + "github.com/gin-gonic/gin" +) + +func RunDashboardServer(addr string, port int64) (err error) { + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("%v", r) + } + }() + gin.SetMode(gin.ReleaseMode) + router := gin.New() + router.LoadHTMLGlob("assets/*") + router.GET("/api/reload", apiReload) + go router.Run(fmt.Sprintf("%s:%d", addr, port)) + return +} diff --git a/src/frp/models/server/dashboard_api.go b/src/frp/models/server/dashboard_api.go new file mode 100644 index 00000000..8332adaf --- /dev/null +++ b/src/frp/models/server/dashboard_api.go @@ -0,0 +1,26 @@ +// Copyright 2016 fatedier, fatedier@gmail.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package server + +import ( + "github.com/gin-gonic/gin" +) + +func apiReload(c *gin.Context) { + c.JSON(200, gin.H{ + "code": 0, + "msg": "ok", + }) +}