更换日志组件为logrus,修改资产的账号和密码不再为必填选项
This commit is contained in:
@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/sirupsen/logrus"
|
||||
"next-terminal/pkg/global"
|
||||
"strings"
|
||||
"time"
|
||||
@ -35,7 +36,7 @@ func Auth(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
token := GetToken(c)
|
||||
user, found := global.Cache.Get(token)
|
||||
if !found {
|
||||
c.Logger().Error("您的登录信息已失效,请重新登录后再试。")
|
||||
logrus.Debugf("您的登录信息已失效,请重新登录后再试。")
|
||||
return Fail(c, 403, "您的登录信息已失效,请重新登录后再试。")
|
||||
}
|
||||
global.Cache.Set(token, user, time.Minute*time.Duration(30))
|
||||
|
@ -19,9 +19,6 @@ func SetupRoutes() *echo.Echo {
|
||||
e.File("/favicon.ico", "web/build/favicon.ico")
|
||||
e.Static("/static", "web/build/static")
|
||||
|
||||
// Middleware
|
||||
e.Use(middleware.Logger())
|
||||
|
||||
//fd, _ := os.OpenFile(
|
||||
// "next-terminal.log",
|
||||
// os.O_RDWR|os.O_APPEND,
|
||||
|
@ -4,8 +4,9 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/gommon/log"
|
||||
"github.com/sirupsen/logrus"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@ -16,6 +17,7 @@ import (
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func SessionPagingEndpoint(c echo.Context) error {
|
||||
@ -38,10 +40,10 @@ func SessionPagingEndpoint(c echo.Context) error {
|
||||
recording := items[i].Recording + "/recording"
|
||||
|
||||
if utils.FileExists(recording) {
|
||||
log.Infof("检测到录屏文件[%v]存在", recording)
|
||||
logrus.Debugf("检测到录屏文件[%v]存在", recording)
|
||||
items[i].Recording = "1"
|
||||
} else {
|
||||
log.Warnf("检测到录屏文件[%v]不存在", recording)
|
||||
logrus.Warnf("检测到录屏文件[%v]不存在", recording)
|
||||
items[i].Recording = "0"
|
||||
}
|
||||
} else {
|
||||
@ -89,16 +91,18 @@ func SessionDiscontentEndpoint(c echo.Context) error {
|
||||
|
||||
split := strings.Split(sessionIds, ",")
|
||||
for i := range split {
|
||||
tun, ok := global.Store.Get(split[i])
|
||||
if ok {
|
||||
CloseSession(split[i], tun)
|
||||
}
|
||||
CloseSessionById(split[i], 2001, "管理员强制关闭了此次接入。")
|
||||
}
|
||||
return Success(c, nil)
|
||||
}
|
||||
|
||||
func CloseSession(sessionId string, tun global.Tun) {
|
||||
_ = tun.Tun.Close()
|
||||
func CloseSessionById(sessionId string, code int, reason string) {
|
||||
tun, _ := global.Store.Get(sessionId)
|
||||
if tun != nil {
|
||||
_ = tun.Tun.Close()
|
||||
CloseSessionByWebSocket(tun.WebSocket, code, reason)
|
||||
}
|
||||
|
||||
global.Store.Del(sessionId)
|
||||
|
||||
session := model.Session{}
|
||||
@ -109,6 +113,21 @@ func CloseSession(sessionId string, tun global.Tun) {
|
||||
model.UpdateSessionById(&session, sessionId)
|
||||
}
|
||||
|
||||
func CloseSessionByWebSocket(ws *websocket.Conn, c int, t string) {
|
||||
if ws == nil {
|
||||
return
|
||||
}
|
||||
ws.SetCloseHandler(func(code int, text string) error {
|
||||
var message []byte
|
||||
if code != websocket.CloseNoStatusReceived {
|
||||
message = websocket.FormatCloseMessage(c, t)
|
||||
}
|
||||
_ = ws.WriteControl(websocket.CloseMessage, message, time.Now().Add(time.Second))
|
||||
return nil
|
||||
})
|
||||
defer ws.Close()
|
||||
}
|
||||
|
||||
func SessionResizeEndpoint(c echo.Context) error {
|
||||
width := c.QueryParam("width")
|
||||
height := c.QueryParam("height")
|
||||
@ -457,6 +476,6 @@ func SessionRecordingEndpoint(c echo.Context) error {
|
||||
return err
|
||||
}
|
||||
recording := path.Join(session.Recording, "recording")
|
||||
log.Printf("读取录屏文件:%s", recording)
|
||||
logrus.Debugf("读取录屏文件:%s", recording)
|
||||
return c.File(recording)
|
||||
}
|
||||
|
@ -6,8 +6,8 @@ import (
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/pkg/sftp"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/crypto/ssh"
|
||||
"log"
|
||||
"net/http"
|
||||
"next-terminal/pkg/model"
|
||||
"strconv"
|
||||
@ -111,7 +111,7 @@ func SSHEndpoint(c echo.Context) error {
|
||||
}
|
||||
_, err = stdinPipe.Write(message)
|
||||
if err != nil {
|
||||
log.Println("Tunnel write:", err)
|
||||
logrus.Debugf("Tunnel write: %v", err)
|
||||
}
|
||||
}
|
||||
return err
|
||||
@ -173,7 +173,7 @@ func WriteMessage(ws *websocket.Conn, message string) {
|
||||
func WriteByteMessage(ws *websocket.Conn, p []byte) {
|
||||
err := ws.WriteMessage(websocket.TextMessage, p)
|
||||
if err != nil {
|
||||
log.Println("write:", err)
|
||||
logrus.Debugf("write: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,9 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/pkg/sftp"
|
||||
"log"
|
||||
"github.com/sirupsen/logrus"
|
||||
"next-terminal/pkg/global"
|
||||
"next-terminal/pkg/guacd"
|
||||
"next-terminal/pkg/model"
|
||||
@ -17,6 +15,7 @@ func TunEndpoint(c echo.Context) error {
|
||||
|
||||
ws, err := UpGrader.Upgrade(c.Response().Writer, c.Request(), nil)
|
||||
if err != nil {
|
||||
logrus.Errorf("升级为WebSocket协议失败:%v", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
@ -35,7 +34,6 @@ func TunEndpoint(c echo.Context) error {
|
||||
propertyMap := model.FindAllPropertiesMap()
|
||||
|
||||
var session model.Session
|
||||
var sftpClient *sftp.Client
|
||||
|
||||
if len(connectionId) > 0 {
|
||||
session, err = model.FindSessionByConnectionId(connectionId)
|
||||
@ -95,11 +93,6 @@ func TunEndpoint(c echo.Context) error {
|
||||
configuration.SetParameter(guacd.FontSize, strconv.Itoa(fontSize))
|
||||
configuration.SetParameter(guacd.FontName, propertyMap[guacd.FontName])
|
||||
configuration.SetParameter(guacd.ColorScheme, propertyMap[guacd.ColorScheme])
|
||||
|
||||
sftpClient, err = CreateSftpClient(session.AssetId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
break
|
||||
case "vnc":
|
||||
configuration.SetParameter("password", session.Password)
|
||||
@ -117,21 +110,20 @@ func TunEndpoint(c echo.Context) error {
|
||||
}
|
||||
|
||||
addr := propertyMap[guacd.Host] + ":" + propertyMap[guacd.Port]
|
||||
|
||||
logrus.Infof("connect to %v with global: %+v", addr, configuration)
|
||||
|
||||
tunnel, err := guacd.NewTunnel(addr, configuration)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("=====================================================\n")
|
||||
fmt.Printf("connect to %v with global: %+v\n", addr, configuration)
|
||||
fmt.Printf("=====================================================\n")
|
||||
|
||||
tun := global.Tun{
|
||||
Tun: tunnel,
|
||||
SftpClient: sftpClient,
|
||||
Tun: tunnel,
|
||||
WebSocket: ws,
|
||||
}
|
||||
|
||||
global.Store.Set(sessionId, tun)
|
||||
global.Store.Set(sessionId, &tun)
|
||||
|
||||
if len(session.ConnectionId) == 0 {
|
||||
session.ConnectionId = tunnel.UUID
|
||||
@ -142,19 +134,30 @@ func TunEndpoint(c echo.Context) error {
|
||||
model.UpdateSessionById(&session, sessionId)
|
||||
}
|
||||
|
||||
go func() {
|
||||
sftpClient, err := CreateSftpClient(session.AssetId)
|
||||
if err != nil {
|
||||
CloseSessionById(sessionId, 2002, err.Error())
|
||||
logrus.Errorf("创建sftp客户端失败:%v", err.Error())
|
||||
}
|
||||
item, ok := global.Store.Get(sessionId)
|
||||
if ok {
|
||||
item.SftpClient = sftpClient
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
for true {
|
||||
instruction, err := tunnel.Read()
|
||||
if err != nil {
|
||||
CloseSession(sessionId, tun)
|
||||
log.Printf("WS读取异常: %v", err)
|
||||
CloseSessionById(sessionId, 523, err.Error())
|
||||
logrus.Printf("WebSocket读取错误: %v", err)
|
||||
break
|
||||
}
|
||||
//fmt.Printf("<= %v \n", string(instruction))
|
||||
err = ws.WriteMessage(websocket.TextMessage, instruction)
|
||||
if err != nil {
|
||||
CloseSession(sessionId, tun)
|
||||
log.Printf("WS写入异常: %v", err)
|
||||
CloseSessionById(sessionId, 523, err.Error())
|
||||
logrus.Printf("WebSocket写入错误: %v", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
@ -163,14 +166,14 @@ func TunEndpoint(c echo.Context) error {
|
||||
for true {
|
||||
_, message, err := ws.ReadMessage()
|
||||
if err != nil {
|
||||
CloseSession(sessionId, tun)
|
||||
log.Printf("Tunnel读取异常: %v", err)
|
||||
CloseSessionById(sessionId, 523, err.Error())
|
||||
logrus.Printf("隧道读取错误: %v", err)
|
||||
break
|
||||
}
|
||||
_, err = tunnel.WriteAndFlush(message)
|
||||
if err != nil {
|
||||
CloseSession(sessionId, tun)
|
||||
log.Printf("Tunnel写入异常: %v", err)
|
||||
CloseSessionById(sessionId, 523, err.Error())
|
||||
logrus.Printf("隧道写入错误: %v", err)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/spf13/pflag"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
@ -39,10 +40,19 @@ func SetupConfig() (*Config, error) {
|
||||
viper.AutomaticEnv()
|
||||
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||
|
||||
err := viper.ReadInConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pflag.String("db", "sqlite", "db mode")
|
||||
pflag.String("sqlite.file", "next-terminal.db", "sqlite db file")
|
||||
pflag.String("mysql.hostname", "127.0.0.1", "mysql hostname")
|
||||
pflag.Int("mysql.port", 3306, "mysql port")
|
||||
pflag.String("mysql.username", "mysql", "mysql username")
|
||||
pflag.String("mysql.password", "mysql", "mysql password")
|
||||
pflag.String("mysql.database", "next_terminal", "mysql database")
|
||||
|
||||
pflag.String("server.addr", "0.0.0.0:8088", "server listen addr")
|
||||
|
||||
pflag.Parse()
|
||||
_ = viper.BindPFlags(pflag.CommandLine)
|
||||
_ = viper.ReadInConfig()
|
||||
|
||||
var config = &Config{
|
||||
DB: viper.GetString("db"),
|
||||
|
@ -1,21 +1,23 @@
|
||||
package global
|
||||
|
||||
import (
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/pkg/sftp"
|
||||
"next-terminal/pkg/guacd"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Tun struct {
|
||||
Tun guacd.Tunnel
|
||||
Tun *guacd.Tunnel
|
||||
SftpClient *sftp.Client
|
||||
WebSocket *websocket.Conn
|
||||
}
|
||||
|
||||
type TunStore struct {
|
||||
m sync.Map
|
||||
}
|
||||
|
||||
func (s *TunStore) Set(k string, v Tun) {
|
||||
func (s *TunStore) Set(k string, v *Tun) {
|
||||
s.m.Store(k, v)
|
||||
}
|
||||
|
||||
@ -23,10 +25,10 @@ func (s *TunStore) Del(k string) {
|
||||
s.m.Delete(k)
|
||||
}
|
||||
|
||||
func (s *TunStore) Get(k string) (item Tun, ok bool) {
|
||||
func (s *TunStore) Get(k string) (item *Tun, ok bool) {
|
||||
value, ok := s.m.Load(k)
|
||||
if ok {
|
||||
return value.(Tun), true
|
||||
return value.(*Tun), true
|
||||
}
|
||||
return item, false
|
||||
}
|
||||
|
@ -106,13 +106,14 @@ type Tunnel struct {
|
||||
IsOpen bool
|
||||
}
|
||||
|
||||
func NewTunnel(address string, config Configuration) (ret Tunnel, err error) {
|
||||
func NewTunnel(address string, config Configuration) (ret *Tunnel, err error) {
|
||||
|
||||
conn, err := net.Dial("tcp", address)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ret = &Tunnel{}
|
||||
ret.conn = conn
|
||||
ret.rw = bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn))
|
||||
ret.Config = config
|
||||
@ -123,7 +124,7 @@ func NewTunnel(address string, config Configuration) (ret Tunnel, err error) {
|
||||
}
|
||||
|
||||
if err := ret.WriteInstructionAndFlush(NewInstruction("select", selectArg)); err != nil {
|
||||
return Tunnel{}, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
args, err := ret.expect("args")
|
||||
@ -135,21 +136,21 @@ func NewTunnel(address string, config Configuration) (ret Tunnel, err error) {
|
||||
height := config.GetParameter("height")
|
||||
// send size
|
||||
if err := ret.WriteInstructionAndFlush(NewInstruction("size", width, height, "96")); err != nil {
|
||||
return Tunnel{}, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := ret.WriteInstructionAndFlush(NewInstruction("audio")); err != nil {
|
||||
return Tunnel{}, err
|
||||
return nil, err
|
||||
}
|
||||
if err := ret.WriteInstructionAndFlush(NewInstruction("video")); err != nil {
|
||||
return Tunnel{}, err
|
||||
return nil, err
|
||||
}
|
||||
if err := ret.WriteInstructionAndFlush(NewInstruction("image")); err != nil {
|
||||
return Tunnel{}, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := ret.WriteInstructionAndFlush(NewInstruction("timezone", "Asia/Shanghai")); err != nil {
|
||||
return Tunnel{}, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
parameters := make([]string, len(args.Args))
|
||||
@ -163,7 +164,7 @@ func NewTunnel(address string, config Configuration) (ret Tunnel, err error) {
|
||||
}
|
||||
// send connect
|
||||
if err := ret.WriteInstructionAndFlush(NewInstruction("connect", parameters...)); err != nil {
|
||||
return Tunnel{}, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ready, err := ret.expect("ready")
|
||||
@ -172,7 +173,7 @@ func NewTunnel(address string, config Configuration) (ret Tunnel, err error) {
|
||||
}
|
||||
|
||||
if len(ready.Args) == 0 {
|
||||
return ret, errors.New("no connection id received")
|
||||
return nil, errors.New("no connection id received")
|
||||
}
|
||||
|
||||
ret.UUID = ready.Args[0]
|
||||
@ -225,7 +226,6 @@ func (opt *Tunnel) ReadInstruction() (instruction Instruction, err error) {
|
||||
if err != nil {
|
||||
return instruction, err
|
||||
}
|
||||
fmt.Printf("<- %v \n", msg)
|
||||
return instruction.Parse(msg), err
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user