Browse Source

Db file change

刘河 6 years ago
parent
commit
5fd335f330

+ 18 - 18
bridge/bridge.go

@@ -90,7 +90,7 @@ func (s *Bridge) GetHealthFromClient(id int, c *conn.Conn) {
 		if info, status, err := c.GetHealthInfo(); err != nil {
 		if info, status, err := c.GetHealthInfo(); err != nil {
 			break
 			break
 		} else if !status { //the status is true , return target to the targetArr
 		} else if !status { //the status is true , return target to the targetArr
-			file.GetCsvDb().Tasks.Range(func(key, value interface{}) bool {
+			file.GetDb().JsonDb.Tasks.Range(func(key, value interface{}) bool {
 				v := value.(*file.Tunnel)
 				v := value.(*file.Tunnel)
 				if v.Client.Id == id && v.Mode == "tcp" && strings.Contains(v.Target.TargetStr, info) {
 				if v.Client.Id == id && v.Mode == "tcp" && strings.Contains(v.Target.TargetStr, info) {
 					v.Lock()
 					v.Lock()
@@ -106,7 +106,7 @@ func (s *Bridge) GetHealthFromClient(id int, c *conn.Conn) {
 				}
 				}
 				return true
 				return true
 			})
 			})
-			file.GetCsvDb().Hosts.Range(func(key, value interface{}) bool {
+			file.GetDb().JsonDb.Hosts.Range(func(key, value interface{}) bool {
 				v := value.(*file.Host)
 				v := value.(*file.Host)
 				if v.Client.Id == id && strings.Contains(v.Target.TargetStr, info) {
 				if v.Client.Id == id && strings.Contains(v.Target.TargetStr, info) {
 					v.Lock()
 					v.Lock()
@@ -123,7 +123,7 @@ func (s *Bridge) GetHealthFromClient(id int, c *conn.Conn) {
 				return true
 				return true
 			})
 			})
 		} else { //the status is false,remove target from the targetArr
 		} else { //the status is false,remove target from the targetArr
-			file.GetCsvDb().Tasks.Range(func(key, value interface{}) bool {
+			file.GetDb().JsonDb.Tasks.Range(func(key, value interface{}) bool {
 				v := value.(*file.Tunnel)
 				v := value.(*file.Tunnel)
 				if v.Client.Id == id && v.Mode == "tcp" && common.IsArrContains(v.HealthRemoveArr, info) && !common.IsArrContains(v.Target.TargetArr, info) {
 				if v.Client.Id == id && v.Mode == "tcp" && common.IsArrContains(v.HealthRemoveArr, info) && !common.IsArrContains(v.Target.TargetArr, info) {
 					v.Lock()
 					v.Lock()
@@ -134,7 +134,7 @@ func (s *Bridge) GetHealthFromClient(id int, c *conn.Conn) {
 				return true
 				return true
 			})
 			})
 
 
-			file.GetCsvDb().Hosts.Range(func(key, value interface{}) bool {
+			file.GetDb().JsonDb.Hosts.Range(func(key, value interface{}) bool {
 				v := value.(*file.Host)
 				v := value.(*file.Host)
 				if v.Client.Id == id && common.IsArrContains(v.HealthRemoveArr, info) && !common.IsArrContains(v.Target.TargetArr, info) {
 				if v.Client.Id == id && common.IsArrContains(v.HealthRemoveArr, info) && !common.IsArrContains(v.Target.TargetArr, info) {
 					v.Lock()
 					v.Lock()
@@ -182,7 +182,7 @@ func (s *Bridge) cliProcess(c *conn.Conn) {
 		return
 		return
 	}
 	}
 	//verify
 	//verify
-	id, err := file.GetCsvDb().GetIdByVerifyKey(string(buf), c.Conn.RemoteAddr().String())
+	id, err := file.GetDb().GetIdByVerifyKey(string(buf), c.Conn.RemoteAddr().String())
 	if err != nil {
 	if err != nil {
 		logs.Info("Current client connection validation error, close this client:", c.Conn.RemoteAddr())
 		logs.Info("Current client connection validation error, close this client:", c.Conn.RemoteAddr())
 		s.verifyError(c)
 		s.verifyError(c)
@@ -204,10 +204,10 @@ func (s *Bridge) DelClient(id int) {
 			v.(*Client).signal.Close()
 			v.(*Client).signal.Close()
 		}
 		}
 		s.Client.Delete(id)
 		s.Client.Delete(id)
-		if file.GetCsvDb().IsPubClient(id) {
+		if file.GetDb().IsPubClient(id) {
 			return
 			return
 		}
 		}
-		if c, err := file.GetCsvDb().GetClient(id); err == nil {
+		if c, err := file.GetDb().GetClient(id); err == nil {
 			s.CloseClient <- c.Id
 			s.CloseClient <- c.Id
 		}
 		}
 	}
 	}
@@ -215,7 +215,7 @@ func (s *Bridge) DelClient(id int) {
 
 
 //use different
 //use different
 func (s *Bridge) typeDeal(typeVal string, c *conn.Conn, id int) {
 func (s *Bridge) typeDeal(typeVal string, c *conn.Conn, id int) {
-	isPub := file.GetCsvDb().IsPubClient(id)
+	isPub := file.GetDb().IsPubClient(id)
 	switch typeVal {
 	switch typeVal {
 	case common.WORK_MAIN:
 	case common.WORK_MAIN:
 		if isPub {
 		if isPub {
@@ -237,7 +237,7 @@ func (s *Bridge) typeDeal(typeVal string, c *conn.Conn, id int) {
 			v.(*Client).tunnel = muxConn
 			v.(*Client).tunnel = muxConn
 		}
 		}
 	case common.WORK_CONFIG:
 	case common.WORK_CONFIG:
-		client, err := file.GetCsvDb().GetClient(id)
+		client, err := file.GetDb().GetClient(id)
 		if err != nil || (!isPub && !client.ConfigConnAllow) {
 		if err != nil || (!isPub && !client.ConfigConnAllow) {
 			c.Close()
 			c.Close()
 			return
 			return
@@ -259,7 +259,7 @@ func (s *Bridge) typeDeal(typeVal string, c *conn.Conn, id int) {
 		//read md5 secret
 		//read md5 secret
 		if b, err := c.GetShortContent(32); err != nil {
 		if b, err := c.GetShortContent(32); err != nil {
 			return
 			return
-		} else if t := file.GetCsvDb().GetTaskByMd5Password(string(b)); t == nil {
+		} else if t := file.GetDb().GetTaskByMd5Password(string(b)); t == nil {
 			return
 			return
 		} else {
 		} else {
 			if v, ok := s.Client.Load(t.Client.Id); !ok {
 			if v, ok := s.Client.Load(t.Client.Id); !ok {
@@ -373,18 +373,18 @@ loop:
 				break loop
 				break loop
 			} else {
 			} else {
 				var str string
 				var str string
-				id, err := file.GetCsvDb().GetClientIdByVkey(string(b))
+				id, err := file.GetDb().GetClientIdByVkey(string(b))
 				if err != nil {
 				if err != nil {
 					break loop
 					break loop
 				}
 				}
-				file.GetCsvDb().Hosts.Range(func(key, value interface{}) bool {
+				file.GetDb().JsonDb.Hosts.Range(func(key, value interface{}) bool {
 					v := value.(*file.Host)
 					v := value.(*file.Host)
 					if v.Client.Id == id {
 					if v.Client.Id == id {
 						str += v.Remark + common.CONN_DATA_SEQ
 						str += v.Remark + common.CONN_DATA_SEQ
 					}
 					}
 					return true
 					return true
 				})
 				})
-				file.GetCsvDb().Tasks.Range(func(key, value interface{}) bool {
+				file.GetDb().JsonDb.Tasks.Range(func(key, value interface{}) bool {
 					v := value.(*file.Tunnel)
 					v := value.(*file.Tunnel)
 					if _, ok := s.runList[v.Id]; ok && v.Client.Id == id {
 					if _, ok := s.runList[v.Id]; ok && v.Client.Id == id {
 						str += v.Remark + common.CONN_DATA_SEQ
 						str += v.Remark + common.CONN_DATA_SEQ
@@ -401,7 +401,7 @@ loop:
 				c.WriteAddFail()
 				c.WriteAddFail()
 				break loop
 				break loop
 			} else {
 			} else {
-				if err = file.GetCsvDb().NewClient(client); err != nil {
+				if err = file.GetDb().NewClient(client); err != nil {
 					fail = true
 					fail = true
 					c.WriteAddFail()
 					c.WriteAddFail()
 					break loop
 					break loop
@@ -422,12 +422,12 @@ loop:
 				h.Location = "/"
 				h.Location = "/"
 			}
 			}
 			if !client.HasHost(h) {
 			if !client.HasHost(h) {
-				if file.GetCsvDb().IsHostExist(h) {
+				if file.GetDb().IsHostExist(h) {
 					fail = true
 					fail = true
 					c.WriteAddFail()
 					c.WriteAddFail()
 					break loop
 					break loop
 				} else {
 				} else {
-					file.GetCsvDb().NewHost(h)
+					file.GetDb().NewHost(h)
 					c.WriteAddOk()
 					c.WriteAddOk()
 				}
 				}
 			} else {
 			} else {
@@ -469,7 +469,7 @@ loop:
 							tl.Target.TargetStr = strconv.Itoa(targets[i])
 							tl.Target.TargetStr = strconv.Itoa(targets[i])
 						}
 						}
 					}
 					}
-					tl.Id = int(file.GetCsvDb().GetTaskId())
+					tl.Id = int(file.GetDb().JsonDb.GetTaskId())
 					tl.Status = true
 					tl.Status = true
 					tl.Flow = new(file.Flow)
 					tl.Flow = new(file.Flow)
 					tl.NoStore = true
 					tl.NoStore = true
@@ -478,7 +478,7 @@ loop:
 					tl.LocalPath = t.LocalPath
 					tl.LocalPath = t.LocalPath
 					tl.StripPre = t.StripPre
 					tl.StripPre = t.StripPre
 					if !client.HasTunnel(tl) {
 					if !client.HasTunnel(tl) {
-						if err := file.GetCsvDb().NewTask(tl); err != nil {
+						if err := file.GetDb().NewTask(tl); err != nil {
 							logs.Notice("Add task error ", err.Error())
 							logs.Notice("Add task error ", err.Error())
 							fail = true
 							fail = true
 							c.WriteAddFail()
 							c.WriteAddFail()

+ 10 - 0
lib/common/util.go

@@ -15,6 +15,7 @@ import (
 	"regexp"
 	"regexp"
 	"strconv"
 	"strconv"
 	"strings"
 	"strings"
+	"sync"
 )
 )
 
 
 //Get the corresponding IP address through domain name
 //Get the corresponding IP address through domain name
@@ -344,3 +345,12 @@ func BytesToNum(b []byte) int {
 	x, _ := strconv.Atoi(str)
 	x, _ := strconv.Atoi(str)
 	return int(x)
 	return int(x)
 }
 }
+
+func GeSynctMapLen(m sync.Map) int {
+	var c int
+	m.Range(func(key, value interface{}) bool {
+		c++
+		return true
+	})
+	return c
+}

+ 0 - 1
lib/config/config.go

@@ -93,7 +93,6 @@ func NewConfig(path string) (c *Config, err error) {
 				}
 				}
 			}
 			}
 		}
 		}
-
 	}
 	}
 	return
 	return
 }
 }

+ 17 - 17
lib/conn/conn.go

@@ -210,21 +210,6 @@ func (s *Conn) SendHostInfo(h *file.Host) (int, error) {
 	return s.Write(raw.Bytes())
 	return s.Write(raw.Bytes())
 }
 }
 
 
-//get task or host result of add
-func (s *Conn) GetAddStatus() (b bool) {
-	binary.Read(s.Conn, binary.LittleEndian, &b)
-	return
-}
-
-func (s *Conn) WriteAddOk() error {
-	return binary.Write(s.Conn, binary.LittleEndian, true)
-}
-
-func (s *Conn) WriteAddFail() error {
-	defer s.Close()
-	return binary.Write(s.Conn, binary.LittleEndian, false)
-}
-
 //get task info
 //get task info
 func (s *Conn) GetHostInfo() (h *file.Host, err error) {
 func (s *Conn) GetHostInfo() (h *file.Host, err error) {
 	var l int
 	var l int
@@ -238,7 +223,7 @@ func (s *Conn) GetHostInfo() (h *file.Host, err error) {
 		arr := strings.Split(string(buf[:l]), common.CONN_DATA_SEQ)
 		arr := strings.Split(string(buf[:l]), common.CONN_DATA_SEQ)
 		h = new(file.Host)
 		h = new(file.Host)
 		h.Target = new(file.Target)
 		h.Target = new(file.Target)
-		h.Id = int(file.GetCsvDb().GetHostId())
+		h.Id = int(file.GetDb().JsonDb.GetHostId())
 		h.Host = arr[0]
 		h.Host = arr[0]
 		h.Target.TargetStr = arr[1]
 		h.Target.TargetStr = arr[1]
 		h.HeaderChange = arr[2]
 		h.HeaderChange = arr[2]
@@ -328,7 +313,7 @@ func (s *Conn) GetTaskInfo() (t *file.Tunnel, err error) {
 		t.Mode = arr[0]
 		t.Mode = arr[0]
 		t.Ports = arr[1]
 		t.Ports = arr[1]
 		t.Target.TargetStr = arr[2]
 		t.Target.TargetStr = arr[2]
-		t.Id = int(file.GetCsvDb().GetTaskId())
+		t.Id = int(file.GetDb().JsonDb.GetTaskId())
 		t.Status = true
 		t.Status = true
 		t.Flow = new(file.Flow)
 		t.Flow = new(file.Flow)
 		t.Remark = arr[3]
 		t.Remark = arr[3]
@@ -379,6 +364,21 @@ func (s *Conn) WriteChan() (int, error) {
 	return s.Write([]byte(common.WORK_CHAN))
 	return s.Write([]byte(common.WORK_CHAN))
 }
 }
 
 
+//get task or host result of add
+func (s *Conn) GetAddStatus() (b bool) {
+	binary.Read(s.Conn, binary.LittleEndian, &b)
+	return
+}
+
+func (s *Conn) WriteAddOk() error {
+	return binary.Write(s.Conn, binary.LittleEndian, true)
+}
+
+func (s *Conn) WriteAddFail() error {
+	defer s.Close()
+	return binary.Write(s.Conn, binary.LittleEndian, false)
+}
+
 //get the assembled amount data(len 4 and content)
 //get the assembled amount data(len 4 and content)
 func GetLenBytes(buf []byte) (b []byte, err error) {
 func GetLenBytes(buf []byte) (b []byte, err error) {
 	raw := bytes.NewBuffer([]byte{})
 	raw := bytes.NewBuffer([]byte{})

+ 0 - 4
lib/crypt/crypt.go

@@ -19,11 +19,8 @@ func AesEncrypt(origData, key []byte) ([]byte, error) {
 	}
 	}
 	blockSize := block.BlockSize()
 	blockSize := block.BlockSize()
 	origData = PKCS5Padding(origData, blockSize)
 	origData = PKCS5Padding(origData, blockSize)
-	// origData = ZeroPadding(origData, block.BlockSize())
 	blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
 	blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
 	crypted := make([]byte, len(origData))
 	crypted := make([]byte, len(origData))
-	// 根据CryptBlocks方法的说明,如下方式初始化crypted也可以
-	// crypted := origData
 	blockMode.CryptBlocks(crypted, origData)
 	blockMode.CryptBlocks(crypted, origData)
 	return crypted, nil
 	return crypted, nil
 }
 }
@@ -52,7 +49,6 @@ func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
 //Remove excess
 //Remove excess
 func PKCS5UnPadding(origData []byte) (error, []byte) {
 func PKCS5UnPadding(origData []byte) (error, []byte) {
 	length := len(origData)
 	length := len(origData)
-	// 去掉最后一个字节 unpadding 次
 	unpadding := int(origData[length-1])
 	unpadding := int(origData[length-1])
 	if (length - unpadding) < 0 {
 	if (length - unpadding) < 0 {
 		return errors.New("len error"), nil
 		return errors.New("len error"), nil

+ 0 - 35
lib/file/csv.go

@@ -1,35 +0,0 @@
-package file
-
-import (
-	"github.com/cnlh/nps/lib/common"
-	"sort"
-	"sync"
-)
-
-var (
-	CsvDb *Csv
-	once  sync.Once
-)
-
-//init csv from file
-func GetCsvDb() *Csv {
-	once.Do(func() {
-		CsvDb = NewCsv(common.GetRunPath())
-		CsvDb.LoadClientFromCsv()
-		CsvDb.LoadTaskFromCsv()
-		CsvDb.LoadHostFromCsv()
-	})
-	return CsvDb
-}
-
-func GetMapKeys(m sync.Map, isSort bool, sortKey, order string) (keys []int) {
-	if sortKey != "" && isSort {
-		return sortClientByKey(m, sortKey, order)
-	}
-	m.Range(func(key, value interface{}) bool {
-		keys = append(keys, key.(int))
-		return true
-	})
-	sort.Ints(keys)
-	return
-}

+ 356 - 0
lib/file/db.go

@@ -0,0 +1,356 @@
+package file
+
+import (
+	"errors"
+	"fmt"
+	"github.com/cnlh/nps/lib/common"
+	"github.com/cnlh/nps/lib/crypt"
+	"github.com/cnlh/nps/lib/rate"
+	"net/http"
+	"regexp"
+	"sort"
+	"strings"
+	"sync"
+)
+
+type DbUtils struct {
+	JsonDb *JsonDb
+}
+
+var (
+	Db   *DbUtils
+	once sync.Once
+)
+
+//init csv from file
+func GetDb() *DbUtils {
+	once.Do(func() {
+		jsonDb := NewJsonDb(common.GetRunPath())
+		jsonDb.LoadClientFromJsonFile()
+		jsonDb.LoadTaskFromJsonFile()
+		jsonDb.LoadHostFromJsonFile()
+		Db = &DbUtils{JsonDb: jsonDb}
+	})
+	return Db
+}
+
+func GetMapKeys(m sync.Map, isSort bool, sortKey, order string) (keys []int) {
+	if sortKey != "" && isSort {
+		return sortClientByKey(m, sortKey, order)
+	}
+	m.Range(func(key, value interface{}) bool {
+		keys = append(keys, key.(int))
+		return true
+	})
+	sort.Ints(keys)
+	return
+}
+
+func (s *DbUtils) GetClientList(start, length int, search, sort, order string, clientId int) ([]*Client, int) {
+	list := make([]*Client, 0)
+	var cnt int
+	keys := GetMapKeys(s.JsonDb.Clients, true, sort, order)
+	for _, key := range keys {
+		if value, ok := s.JsonDb.Clients.Load(key); ok {
+			v := value.(*Client)
+			if v.NoDisplay {
+				continue
+			}
+			if clientId != 0 && clientId != v.Id {
+				continue
+			}
+			if search != "" && !(v.Id == common.GetIntNoErrByStr(search) || strings.Contains(v.VerifyKey, search) || strings.Contains(v.Remark, search)) {
+				continue
+			}
+			cnt++
+			if start--; start < 0 {
+				if length--; length > 0 {
+					list = append(list, v)
+				}
+			}
+		}
+	}
+	return list, cnt
+}
+
+func (s *DbUtils) GetIdByVerifyKey(vKey string, addr string) (id int, err error) {
+	var exist bool
+	s.JsonDb.Clients.Range(func(key, value interface{}) bool {
+		v := value.(*Client)
+		if common.Getverifyval(v.VerifyKey) == vKey && v.Status {
+			v.Addr = common.GetIpByAddr(addr)
+			id = v.Id
+			exist = true
+			return false
+		}
+		return true
+	})
+	if exist {
+		return
+	}
+	return 0, errors.New("not found")
+}
+
+func (s *DbUtils) NewTask(t *Tunnel) (err error) {
+	s.JsonDb.Tasks.Range(func(key, value interface{}) bool {
+		v := value.(*Tunnel)
+		if (v.Mode == "secret" || v.Mode == "p2p") && v.Password == t.Password {
+			err = errors.New(fmt.Sprintf("secret mode keys %s must be unique", t.Password))
+			return false
+		}
+		return true
+	})
+	if err != nil {
+		return
+	}
+	t.Flow = new(Flow)
+	s.JsonDb.Tasks.Store(t.Id, t)
+	s.JsonDb.StoreTasksToJsonFile()
+	return
+}
+
+func (s *DbUtils) UpdateTask(t *Tunnel) error {
+	s.JsonDb.Tasks.Store(t.Id, t)
+	s.JsonDb.StoreTasksToJsonFile()
+	return nil
+}
+
+func (s *DbUtils) DelTask(id int) error {
+	s.JsonDb.Tasks.Delete(id)
+	s.JsonDb.StoreTasksToJsonFile()
+	return nil
+}
+
+//md5 password
+func (s *DbUtils) GetTaskByMd5Password(p string) (t *Tunnel) {
+	s.JsonDb.Tasks.Range(func(key, value interface{}) bool {
+		if crypt.Md5(value.(*Tunnel).Password) == p {
+			t = value.(*Tunnel)
+			return false
+		}
+		return true
+	})
+	return
+}
+
+func (s *DbUtils) GetTask(id int) (t *Tunnel, err error) {
+	if v, ok := s.JsonDb.Tasks.Load(id); ok {
+		t = v.(*Tunnel)
+		return
+	}
+	err = errors.New("not found")
+	return
+}
+
+func (s *DbUtils) DelHost(id int) error {
+	s.JsonDb.Hosts.Delete(id)
+	s.JsonDb.StoreHostToJsonFile()
+	return nil
+}
+
+func (s *DbUtils) IsHostExist(h *Host) bool {
+	var exist bool
+	s.JsonDb.Hosts.Range(func(key, value interface{}) bool {
+		v := value.(*Host)
+		if v.Id != h.Id && v.Host == h.Host && h.Location == v.Location && (v.Scheme == "all" || v.Scheme == h.Scheme) {
+			exist = true
+			return false
+		}
+		return true
+	})
+	return exist
+}
+
+func (s *DbUtils) NewHost(t *Host) error {
+	if t.Location == "" {
+		t.Location = "/"
+	}
+	if s.IsHostExist(t) {
+		return errors.New("host has exist")
+	}
+	t.Flow = new(Flow)
+	s.JsonDb.Hosts.Store(t.Id, t)
+	s.JsonDb.StoreHostToJsonFile()
+	return nil
+}
+
+func (s *DbUtils) GetHost(start, length int, id int, search string) ([]*Host, int) {
+	list := make([]*Host, 0)
+	var cnt int
+	keys := GetMapKeys(s.JsonDb.Hosts, false, "", "")
+	for _, key := range keys {
+		if value, ok := s.JsonDb.Hosts.Load(key); ok {
+			v := value.(*Host)
+			if search != "" && !(v.Id == common.GetIntNoErrByStr(search) || strings.Contains(v.Host, search) || strings.Contains(v.Remark, search)) {
+				continue
+			}
+			if id == 0 || v.Client.Id == id {
+				cnt++
+				if start--; start < 0 {
+					if length--; length > 0 {
+						list = append(list, v)
+					}
+				}
+			}
+		}
+	}
+	return list, cnt
+}
+
+func (s *DbUtils) DelClient(id int) error {
+	s.JsonDb.Clients.Delete(id)
+	s.JsonDb.StoreClientsToJsonFile()
+	return nil
+}
+
+func (s *DbUtils) NewClient(c *Client) error {
+	var isNotSet bool
+	if c.WebUserName != "" && !s.VerifyUserName(c.WebUserName, c.Id) {
+		return errors.New("web login username duplicate, please reset")
+	}
+reset:
+	if c.VerifyKey == "" || isNotSet {
+		isNotSet = true
+		c.VerifyKey = crypt.GetRandomString(16)
+	}
+	if c.RateLimit == 0 {
+		c.Rate = rate.NewRate(int64(2 << 23))
+		c.Rate.Start()
+	}
+	if !s.VerifyVkey(c.VerifyKey, c.Id) {
+		if isNotSet {
+			goto reset
+		}
+		return errors.New("Vkey duplicate, please reset")
+	}
+	if c.Id == 0 {
+		c.Id = int(s.JsonDb.GetClientId())
+	}
+	if c.Flow == nil {
+		c.Flow = new(Flow)
+	}
+	s.JsonDb.Clients.Store(c.Id, c)
+	s.JsonDb.StoreClientsToJsonFile()
+	return nil
+}
+
+func (s *DbUtils) VerifyVkey(vkey string, id int) (res bool) {
+	res = true
+	s.JsonDb.Clients.Range(func(key, value interface{}) bool {
+		v := value.(*Client)
+		if v.VerifyKey == vkey && v.Id != id {
+			res = false
+			return false
+		}
+		return true
+	})
+	return res
+}
+
+func (s *DbUtils) VerifyUserName(username string, id int) (res bool) {
+	res = true
+	s.JsonDb.Clients.Range(func(key, value interface{}) bool {
+		v := value.(*Client)
+		if v.WebUserName == username && v.Id != id {
+			res = false
+			return false
+		}
+		return true
+	})
+	return res
+}
+
+func (s *DbUtils) UpdateClient(t *Client) error {
+	s.JsonDb.Clients.Store(t.Id, t)
+	if t.RateLimit == 0 {
+		t.Rate = rate.NewRate(int64(2 << 23))
+		t.Rate.Start()
+	}
+	return nil
+}
+
+func (s *DbUtils) IsPubClient(id int) bool {
+	client, err := s.GetClient(id)
+	if err == nil {
+		return client.NoDisplay
+	}
+	return false
+}
+
+func (s *DbUtils) GetClient(id int) (c *Client, err error) {
+	if v, ok := s.JsonDb.Clients.Load(id); ok {
+		c = v.(*Client)
+		return
+	}
+	err = errors.New("未找到客户端")
+	return
+}
+
+func (s *DbUtils) GetClientIdByVkey(vkey string) (id int, err error) {
+	var exist bool
+	s.JsonDb.Clients.Range(func(key, value interface{}) bool {
+		v := value.(*Client)
+		if crypt.Md5(v.VerifyKey) == vkey {
+			exist = true
+			id = v.Id
+			return false
+		}
+		return true
+	})
+	if exist {
+		return
+	}
+	err = errors.New("未找到客户端")
+	return
+}
+
+func (s *DbUtils) GetHostById(id int) (h *Host, err error) {
+	if v, ok := s.JsonDb.Hosts.Load(id); ok {
+		h = v.(*Host)
+		return
+	}
+	err = errors.New("The host could not be parsed")
+	return
+}
+
+//get key by host from x
+func (s *DbUtils) GetInfoByHost(host string, r *http.Request) (h *Host, err error) {
+	var hosts []*Host
+	//Handling Ported Access
+	host = common.GetIpByAddr(host)
+	s.JsonDb.Hosts.Range(func(key, value interface{}) bool {
+		v := value.(*Host)
+		if v.IsClose {
+			return true
+		}
+		//Remove http(s) http(s)://a.proxy.com
+		//*.proxy.com *.a.proxy.com  Do some pan-parsing
+		tmp := strings.Replace(v.Host, "*", `\w+?`, -1)
+		var re *regexp.Regexp
+		if re, err = regexp.Compile(tmp); err != nil {
+			return true
+		}
+		if len(re.FindAllString(host, -1)) > 0 && (v.Scheme == "all" || v.Scheme == r.URL.Scheme) {
+			//URL routing
+			hosts = append(hosts, v)
+		}
+		return true
+	})
+
+	for _, v := range hosts {
+		//If not set, default matches all
+		if v.Location == "" {
+			v.Location = "/"
+		}
+		if strings.Index(r.RequestURI, v.Location) == 0 {
+			if h == nil || (len(v.Location) > len(h.Location)) {
+				h = v
+			}
+		}
+	}
+	if h != nil {
+		return
+	}
+	err = errors.New("The host could not be parsed")
+	return
+}

+ 26 - 338
lib/file/file.go

@@ -3,21 +3,17 @@ package file
 import (
 import (
 	"encoding/json"
 	"encoding/json"
 	"errors"
 	"errors"
-	"fmt"
 	"github.com/cnlh/nps/lib/common"
 	"github.com/cnlh/nps/lib/common"
-	"github.com/cnlh/nps/lib/crypt"
 	"github.com/cnlh/nps/lib/rate"
 	"github.com/cnlh/nps/lib/rate"
-	"net/http"
 	"os"
 	"os"
 	"path/filepath"
 	"path/filepath"
-	"regexp"
 	"strings"
 	"strings"
 	"sync"
 	"sync"
 	"sync/atomic"
 	"sync/atomic"
 )
 )
 
 
-func NewCsv(runPath string) *Csv {
-	return &Csv{
+func NewJsonDb(runPath string) *JsonDb {
+	return &JsonDb{
 		RunPath:        runPath,
 		RunPath:        runPath,
 		TaskFilePath:   filepath.Join(runPath, "conf", "tasks.json"),
 		TaskFilePath:   filepath.Join(runPath, "conf", "tasks.json"),
 		HostFilePath:   filepath.Join(runPath, "conf", "hosts.json"),
 		HostFilePath:   filepath.Join(runPath, "conf", "hosts.json"),
@@ -25,21 +21,21 @@ func NewCsv(runPath string) *Csv {
 	}
 	}
 }
 }
 
 
-type Csv struct {
+type JsonDb struct {
 	Tasks            sync.Map
 	Tasks            sync.Map
-	Hosts            sync.Map //域名列表
+	Hosts            sync.Map
 	HostsTmp         sync.Map
 	HostsTmp         sync.Map
-	Clients          sync.Map //客户端
-	RunPath          string   //存储根目录
-	ClientIncreaseId int32    //客户端id
-	TaskIncreaseId   int32    //任务自增ID
-	HostIncreaseId   int32    //host increased id
-	TaskFilePath     string
-	HostFilePath     string
-	ClientFilePath   string
+	Clients          sync.Map
+	RunPath          string
+	ClientIncreaseId int32  //client increased id
+	TaskIncreaseId   int32  //task increased id
+	HostIncreaseId   int32  //host increased id
+	TaskFilePath     string //task file path
+	HostFilePath     string //host file path
+	ClientFilePath   string //client file path
 }
 }
 
 
-func (s *Csv) LoadTaskFromCsv() {
+func (s *JsonDb) LoadTaskFromJsonFile() {
 	loadSyncMapFromFile(s.TaskFilePath, func(v string) {
 	loadSyncMapFromFile(s.TaskFilePath, func(v string) {
 		var err error
 		var err error
 		post := new(Tunnel)
 		post := new(Tunnel)
@@ -56,7 +52,7 @@ func (s *Csv) LoadTaskFromCsv() {
 	})
 	})
 }
 }
 
 
-func (s *Csv) LoadClientFromCsv() {
+func (s *JsonDb) LoadClientFromJsonFile() {
 	loadSyncMapFromFile(s.ClientFilePath, func(v string) {
 	loadSyncMapFromFile(s.ClientFilePath, func(v string) {
 		post := new(Client)
 		post := new(Client)
 		if json.Unmarshal([]byte(v), &post) != nil {
 		if json.Unmarshal([]byte(v), &post) != nil {
@@ -68,6 +64,7 @@ func (s *Csv) LoadClientFromCsv() {
 			post.Rate = rate.NewRate(int64(2 << 23))
 			post.Rate = rate.NewRate(int64(2 << 23))
 		}
 		}
 		post.Rate.Start()
 		post.Rate.Start()
+		post.NowConn = 0
 		s.Clients.Store(post.Id, post)
 		s.Clients.Store(post.Id, post)
 		if post.Id > int(s.ClientIncreaseId) {
 		if post.Id > int(s.ClientIncreaseId) {
 			s.ClientIncreaseId = int32(post.Id)
 			s.ClientIncreaseId = int32(post.Id)
@@ -75,7 +72,7 @@ func (s *Csv) LoadClientFromCsv() {
 	})
 	})
 }
 }
 
 
-func (s *Csv) LoadHostFromCsv() {
+func (s *JsonDb) LoadHostFromJsonFile() {
 	loadSyncMapFromFile(s.HostFilePath, func(v string) {
 	loadSyncMapFromFile(s.HostFilePath, func(v string) {
 		var err error
 		var err error
 		post := new(Host)
 		post := new(Host)
@@ -92,259 +89,7 @@ func (s *Csv) LoadHostFromCsv() {
 	})
 	})
 }
 }
 
 
-func (s *Csv) GetIdByVerifyKey(vKey string, addr string) (id int, err error) {
-	var exist bool
-	s.Clients.Range(func(key, value interface{}) bool {
-		v := value.(*Client)
-		if common.Getverifyval(v.VerifyKey) == vKey && v.Status {
-			v.Addr = common.GetIpByAddr(addr)
-			id = v.Id
-			exist = true
-			return false
-		}
-		return true
-	})
-	if exist {
-		return
-	}
-	return 0, errors.New("not found")
-}
-
-func (s *Csv) NewTask(t *Tunnel) (err error) {
-	s.Tasks.Range(func(key, value interface{}) bool {
-		v := value.(*Tunnel)
-		if (v.Mode == "secret" || v.Mode == "p2p") && v.Password == t.Password {
-			err = errors.New(fmt.Sprintf("Secret mode keys %s must be unique", t.Password))
-			return false
-		}
-		return true
-	})
-	if err != nil {
-		return
-	}
-	t.Flow = new(Flow)
-	s.Tasks.Store(t.Id, t)
-	s.StoreTasksToCsv()
-	return
-}
-
-func (s *Csv) UpdateTask(t *Tunnel) error {
-	s.Tasks.Store(t.Id, t)
-	s.StoreTasksToCsv()
-	return nil
-}
-
-func (s *Csv) DelTask(id int) error {
-	s.Tasks.Delete(id)
-	s.StoreTasksToCsv()
-	return nil
-}
-
-//md5 password
-func (s *Csv) GetTaskByMd5Password(p string) (t *Tunnel) {
-	s.Tasks.Range(func(key, value interface{}) bool {
-		if crypt.Md5(value.(*Tunnel).Password) == p {
-			t = value.(*Tunnel)
-			return false
-		}
-		return true
-	})
-	return
-}
-
-func (s *Csv) GetTask(id int) (t *Tunnel, err error) {
-	if v, ok := s.Tasks.Load(id); ok {
-		t = v.(*Tunnel)
-		return
-	}
-	err = errors.New("not found")
-	return
-}
-
-func (s *Csv) StoreHostToCsv() {
-	storeSyncMapToFile(s.Hosts, s.HostFilePath)
-}
-
-func (s *Csv) StoreTasksToCsv() {
-	storeSyncMapToFile(s.Tasks, s.TaskFilePath)
-}
-
-func (s *Csv) StoreClientsToCsv() {
-	storeSyncMapToFile(s.Clients, s.ClientFilePath)
-}
-
-func (s *Csv) DelHost(id int) error {
-	s.Hosts.Delete(id)
-	s.StoreHostToCsv()
-	return nil
-}
-
-func (s *Csv) GetMapLen(m sync.Map) int {
-	var c int
-	m.Range(func(key, value interface{}) bool {
-		c++
-		return true
-	})
-	return c
-}
-
-func (s *Csv) IsHostExist(h *Host) bool {
-	var exist bool
-	s.Hosts.Range(func(key, value interface{}) bool {
-		v := value.(*Host)
-		if v.Host == h.Host && h.Location == v.Location && (v.Scheme == "all" || v.Scheme == h.Scheme) {
-			exist = true
-			return false
-		}
-		return true
-	})
-	return exist
-}
-
-func (s *Csv) NewHost(t *Host) error {
-	if t.Location == "" {
-		t.Location = "/"
-	}
-	if s.IsHostExist(t) {
-		return errors.New("host has exist")
-	}
-	t.Flow = new(Flow)
-	s.Hosts.Store(t.Id, t)
-	s.StoreHostToCsv()
-	return nil
-}
-
-func (s *Csv) GetHost(start, length int, id int, search string) ([]*Host, int) {
-	list := make([]*Host, 0)
-	var cnt int
-	keys := GetMapKeys(s.Hosts, false, "", "")
-	for _, key := range keys {
-		if value, ok := s.Hosts.Load(key); ok {
-			v := value.(*Host)
-			if search != "" && !(v.Id == common.GetIntNoErrByStr(search) || strings.Contains(v.Host, search) || strings.Contains(v.Remark, search)) {
-				continue
-			}
-			if id == 0 || v.Client.Id == id {
-				cnt++
-				if start--; start < 0 {
-					if length--; length > 0 {
-						list = append(list, v)
-					}
-				}
-			}
-		}
-	}
-	return list, cnt
-}
-
-func (s *Csv) DelClient(id int) error {
-	s.Clients.Delete(id)
-	s.StoreClientsToCsv()
-	return nil
-}
-
-func (s *Csv) NewClient(c *Client) error {
-	var isNotSet bool
-	if c.WebUserName != "" && !s.VerifyUserName(c.WebUserName, c.Id) {
-		return errors.New("web login username duplicate, please reset")
-	}
-reset:
-	if c.VerifyKey == "" || isNotSet {
-		isNotSet = true
-		c.VerifyKey = crypt.GetRandomString(16)
-	}
-	if c.RateLimit == 0 {
-		c.Rate = rate.NewRate(int64(2 << 23))
-		c.Rate.Start()
-	}
-	if !s.VerifyVkey(c.VerifyKey, c.Id) {
-		if isNotSet {
-			goto reset
-		}
-		return errors.New("Vkey duplicate, please reset")
-	}
-	if c.Id == 0 {
-		c.Id = int(s.GetClientId())
-	}
-	if c.Flow == nil {
-		c.Flow = new(Flow)
-	}
-	s.Clients.Store(c.Id, c)
-	s.StoreClientsToCsv()
-	return nil
-}
-
-func (s *Csv) VerifyVkey(vkey string, id int) (res bool) {
-	res = true
-	s.Clients.Range(func(key, value interface{}) bool {
-		v := value.(*Client)
-		if v.VerifyKey == vkey && v.Id != id {
-			res = false
-			return false
-		}
-		return true
-	})
-	return res
-}
-
-func (s *Csv) VerifyUserName(username string, id int) (res bool) {
-	res = true
-	s.Clients.Range(func(key, value interface{}) bool {
-		v := value.(*Client)
-		if v.WebUserName == username && v.Id != id {
-			res = false
-			return false
-		}
-		return true
-	})
-	return res
-}
-
-func (s *Csv) UpdateClient(t *Client) error {
-	s.Clients.Store(t.Id, t)
-	if t.RateLimit == 0 {
-		t.Rate = rate.NewRate(int64(2 << 23))
-		t.Rate.Start()
-	}
-	return nil
-}
-
-func (s *Csv) GetClientList(start, length int, search, sort, order string, clientId int) ([]*Client, int) {
-	list := make([]*Client, 0)
-	var cnt int
-	keys := GetMapKeys(s.Clients, true, sort, order)
-	for _, key := range keys {
-		if value, ok := s.Clients.Load(key); ok {
-			v := value.(*Client)
-			if v.NoDisplay {
-				continue
-			}
-			if clientId != 0 && clientId != v.Id {
-				continue
-			}
-			if search != "" && !(v.Id == common.GetIntNoErrByStr(search) || strings.Contains(v.VerifyKey, search) || strings.Contains(v.Remark, search)) {
-				continue
-			}
-			cnt++
-			if start--; start < 0 {
-				if length--; length > 0 {
-					list = append(list, v)
-				}
-			}
-		}
-	}
-	return list, cnt
-}
-
-func (s *Csv) IsPubClient(id int) bool {
-	client, err := s.GetClient(id)
-	if err == nil {
-		return client.NoDisplay
-	}
-	return false
-}
-
-func (s *Csv) GetClient(id int) (c *Client, err error) {
+func (s *JsonDb) GetClient(id int) (c *Client, err error) {
 	if v, ok := s.Clients.Load(id); ok {
 	if v, ok := s.Clients.Load(id); ok {
 		c = v.(*Client)
 		c = v.(*Client)
 		return
 		return
@@ -353,84 +98,27 @@ func (s *Csv) GetClient(id int) (c *Client, err error) {
 	return
 	return
 }
 }
 
 
-func (s *Csv) GetClientIdByVkey(vkey string) (id int, err error) {
-	var exist bool
-	s.Clients.Range(func(key, value interface{}) bool {
-		v := value.(*Client)
-		if crypt.Md5(v.VerifyKey) == vkey {
-			exist = true
-			id = v.Id
-			return false
-		}
-		return true
-	})
-	if exist {
-		return
-	}
-	err = errors.New("未找到客户端")
-	return
+func (s *JsonDb) StoreHostToJsonFile() {
+	storeSyncMapToFile(s.Hosts, s.HostFilePath)
 }
 }
 
 
-func (s *Csv) GetHostById(id int) (h *Host, err error) {
-	if v, ok := s.Hosts.Load(id); ok {
-		h = v.(*Host)
-		return
-	}
-	err = errors.New("The host could not be parsed")
-	return
+func (s *JsonDb) StoreTasksToJsonFile() {
+	storeSyncMapToFile(s.Tasks, s.TaskFilePath)
 }
 }
 
 
-//get key by host from x
-func (s *Csv) GetInfoByHost(host string, r *http.Request) (h *Host, err error) {
-	var hosts []*Host
-	//Handling Ported Access
-	host = common.GetIpByAddr(host)
-	s.Hosts.Range(func(key, value interface{}) bool {
-		v := value.(*Host)
-		if v.IsClose {
-			return true
-		}
-		//Remove http(s) http(s)://a.proxy.com
-		//*.proxy.com *.a.proxy.com  Do some pan-parsing
-		tmp := strings.Replace(v.Host, "*", `\w+?`, -1)
-		var re *regexp.Regexp
-		if re, err = regexp.Compile(tmp); err != nil {
-			return true
-		}
-		if len(re.FindAllString(host, -1)) > 0 && (v.Scheme == "all" || v.Scheme == r.URL.Scheme) {
-			//URL routing
-			hosts = append(hosts, v)
-		}
-		return true
-	})
-
-	for _, v := range hosts {
-		//If not set, default matches all
-		if v.Location == "" {
-			v.Location = "/"
-		}
-		if strings.Index(r.RequestURI, v.Location) == 0 {
-			if h == nil || (len(v.Location) > len(h.Location)) {
-				h = v
-			}
-		}
-	}
-	if h != nil {
-		return
-	}
-	err = errors.New("The host could not be parsed")
-	return
+func (s *JsonDb) StoreClientsToJsonFile() {
+	storeSyncMapToFile(s.Clients, s.ClientFilePath)
 }
 }
 
 
-func (s *Csv) GetClientId() int32 {
+func (s *JsonDb) GetClientId() int32 {
 	return atomic.AddInt32(&s.ClientIncreaseId, 1)
 	return atomic.AddInt32(&s.ClientIncreaseId, 1)
 }
 }
 
 
-func (s *Csv) GetTaskId() int32 {
+func (s *JsonDb) GetTaskId() int32 {
 	return atomic.AddInt32(&s.TaskIncreaseId, 1)
 	return atomic.AddInt32(&s.TaskIncreaseId, 1)
 }
 }
 
 
-func (s *Csv) GetHostId() int32 {
+func (s *JsonDb) GetHostId() int32 {
 	return atomic.AddInt32(&s.HostIncreaseId, 1)
 	return atomic.AddInt32(&s.HostIncreaseId, 1)
 }
 }
 
 

+ 36 - 36
lib/file/obj.go

@@ -23,6 +23,13 @@ func (s *Flow) Add(in, out int64) {
 	s.ExportFlow += int64(out)
 	s.ExportFlow += int64(out)
 }
 }
 
 
+type Config struct {
+	U        string
+	P        string
+	Compress bool
+	Crypt    bool
+}
+
 type Client struct {
 type Client struct {
 	Cnf             *Config
 	Cnf             *Config
 	Id              int        //id
 	Id              int        //id
@@ -79,7 +86,7 @@ func (s *Client) GetConn() bool {
 }
 }
 
 
 func (s *Client) HasTunnel(t *Tunnel) (exist bool) {
 func (s *Client) HasTunnel(t *Tunnel) (exist bool) {
-	GetCsvDb().Tasks.Range(func(key, value interface{}) bool {
+	GetDb().JsonDb.Tasks.Range(func(key, value interface{}) bool {
 		v := value.(*Tunnel)
 		v := value.(*Tunnel)
 		if v.Client.Id == s.Id && v.Port == t.Port {
 		if v.Client.Id == s.Id && v.Port == t.Port {
 			exist = true
 			exist = true
@@ -92,7 +99,7 @@ func (s *Client) HasTunnel(t *Tunnel) (exist bool) {
 
 
 func (s *Client) HasHost(h *Host) bool {
 func (s *Client) HasHost(h *Host) bool {
 	var has bool
 	var has bool
-	GetCsvDb().Hosts.Range(func(key, value interface{}) bool {
+	GetDb().JsonDb.Hosts.Range(func(key, value interface{}) bool {
 		v := value.(*Host)
 		v := value.(*Host)
 		if v.Client.Id == s.Id && v.Host == h.Host && h.Location == v.Location {
 		if v.Client.Id == s.Id && v.Host == h.Host && h.Location == v.Location {
 			has = true
 			has = true
@@ -104,17 +111,17 @@ func (s *Client) HasHost(h *Host) bool {
 }
 }
 
 
 type Tunnel struct {
 type Tunnel struct {
-	Id         int //Id
-	Port       int //服务端监听端口
+	Id         int
+	Port       int
 	ServerIp   string
 	ServerIp   string
-	Mode       string  //启动方式
-	Status     bool    //设置是否开启
-	RunStatus  bool    //当前运行状态
-	Client     *Client //所属客户端id
-	Ports      string  //客户端与服务端传递
+	Mode       string
+	Status     bool
+	RunStatus  bool
+	Client     *Client
+	Ports      string
 	Flow       *Flow
 	Flow       *Flow
-	Password   string //私密模式密码,唯一
-	Remark     string //备注
+	Password   string
+	Remark     string
 	TargetAddr string
 	TargetAddr string
 	NoStore    bool
 	NoStore    bool
 	LocalPath  string
 	LocalPath  string
@@ -137,10 +144,27 @@ type Health struct {
 	sync.RWMutex
 	sync.RWMutex
 }
 }
 
 
+type Host struct {
+	Id           int
+	Host         string //host
+	HeaderChange string //header change
+	HostChange   string //host change
+	Location     string //url router
+	Remark       string //remark
+	Scheme       string //http https all
+	NoStore      bool
+	IsClose      bool
+	Flow         *Flow
+	Client       *Client
+	Target       *Target //目标
+	Health       `json:"-"`
+	sync.RWMutex
+}
+
 type Target struct {
 type Target struct {
 	nowIndex  int
 	nowIndex  int
 	TargetStr string
 	TargetStr string
-	TargetArr []string //目标
+	TargetArr []string
 	sync.RWMutex
 	sync.RWMutex
 }
 }
 
 
@@ -162,27 +186,3 @@ func (s *Target) GetRandomTarget() (string, error) {
 	s.nowIndex++
 	s.nowIndex++
 	return s.TargetArr[s.nowIndex], nil
 	return s.TargetArr[s.nowIndex], nil
 }
 }
-
-type Config struct {
-	U        string
-	P        string
-	Compress bool
-	Crypt    bool
-}
-
-type Host struct {
-	Id           int
-	Host         string //host
-	HeaderChange string //header change
-	HostChange   string //host change
-	Location     string //url router
-	Remark       string //remark
-	Scheme       string //http https all
-	NoStore      bool
-	IsClose      bool
-	Flow         *Flow
-	Client       *Client
-	Target       *Target //目标
-	Health       `json:"-"`
-	sync.RWMutex
-}

+ 3 - 3
server/proxy/http.go

@@ -58,7 +58,7 @@ func (s *httpServer) processHttps(c net.Conn) {
 		return
 		return
 	}
 	}
 	var host *file.Host
 	var host *file.Host
-	file.GetCsvDb().Hosts.Range(func(key, value interface{}) bool {
+	file.GetDb().JsonDb.Hosts.Range(func(key, value interface{}) bool {
 		v := value.(*file.Host)
 		v := value.(*file.Host)
 		if v.Scheme != "https" && v.Scheme != "all" {
 		if v.Scheme != "https" && v.Scheme != "all" {
 			return true
 			return true
@@ -193,7 +193,7 @@ func (s *httpServer) process(c *conn.Conn, r *http.Request) {
 		targetAddr string
 		targetAddr string
 		wg         sync.WaitGroup
 		wg         sync.WaitGroup
 	)
 	)
-	if host, err = file.GetCsvDb().GetInfoByHost(r.Host, r); err != nil {
+	if host, err = file.GetDb().GetInfoByHost(r.Host, r); err != nil {
 		logs.Notice("the url %s %s %s can't be parsed!", r.URL.Scheme, r.Host, r.RequestURI)
 		logs.Notice("the url %s %s %s can't be parsed!", r.URL.Scheme, r.Host, r.RequestURI)
 		goto end
 		goto end
 	}
 	}
@@ -245,7 +245,7 @@ func (s *httpServer) process(c *conn.Conn, r *http.Request) {
 				r.Method = "POST"
 				r.Method = "POST"
 			}
 			}
 			logs.Trace("new %s connection,clientId %d,host %s,url %s,remote address %s", r.URL.Scheme, host.Client.Id, r.Host, r.URL, r.RemoteAddr)
 			logs.Trace("new %s connection,clientId %d,host %s,url %s,remote address %s", r.URL.Scheme, host.Client.Id, r.Host, r.URL, r.RemoteAddr)
-			if hostTmp, err := file.GetCsvDb().GetInfoByHost(r.Host, r); err != nil {
+			if hostTmp, err := file.GetDb().GetInfoByHost(r.Host, r); err != nil {
 				logs.Notice("the url %s %s %s can't be parsed!", r.URL.Scheme, r.Host, r.RequestURI)
 				logs.Notice("the url %s %s %s can't be parsed!", r.URL.Scheme, r.Host, r.RequestURI)
 				break
 				break
 			} else if host != lastHost {
 			} else if host != lastHost {

+ 37 - 81
server/server.go

@@ -21,27 +21,24 @@ import (
 )
 )
 
 
 var (
 var (
-	Bridge       *bridge.Bridge
-	RunList      map[int]interface{} //运行中的任务
-	serverStatus []map[string]interface{}
+	Bridge  *bridge.Bridge
+	RunList map[int]interface{}
 )
 )
 
 
 func init() {
 func init() {
 	RunList = make(map[int]interface{})
 	RunList = make(map[int]interface{})
-	serverStatus = make([]map[string]interface{}, 0, 1500)
-	go getSeverStatus()
 }
 }
 
 
-//从csv文件中恢复任务
+//init task from db
 func InitFromCsv() {
 func InitFromCsv() {
 	//Add a public password
 	//Add a public password
 	if vkey := beego.AppConfig.String("public_vkey"); vkey != "" {
 	if vkey := beego.AppConfig.String("public_vkey"); vkey != "" {
 		c := file.NewClient(vkey, true, true)
 		c := file.NewClient(vkey, true, true)
-		file.GetCsvDb().NewClient(c)
+		file.GetDb().NewClient(c)
 		RunList[c.Id] = nil
 		RunList[c.Id] = nil
 	}
 	}
 	//Initialize services in server-side files
 	//Initialize services in server-side files
-	file.GetCsvDb().Tasks.Range(func(key, value interface{}) bool {
+	file.GetDb().JsonDb.Tasks.Range(func(key, value interface{}) bool {
 		if value.(*file.Tunnel).Status {
 		if value.(*file.Tunnel).Status {
 			AddTask(value.(*file.Tunnel))
 			AddTask(value.(*file.Tunnel))
 		}
 		}
@@ -49,6 +46,7 @@ func InitFromCsv() {
 	})
 	})
 }
 }
 
 
+//get bridge command
 func DealBridgeTask() {
 func DealBridgeTask() {
 	for {
 	for {
 		select {
 		select {
@@ -58,16 +56,16 @@ func DealBridgeTask() {
 			StopServer(t.Id)
 			StopServer(t.Id)
 		case id := <-Bridge.CloseClient:
 		case id := <-Bridge.CloseClient:
 			DelTunnelAndHostByClientId(id, true)
 			DelTunnelAndHostByClientId(id, true)
-			if v, ok := file.GetCsvDb().Clients.Load(id); ok {
+			if v, ok := file.GetDb().JsonDb.Clients.Load(id); ok {
 				if v.(*file.Client).NoStore {
 				if v.(*file.Client).NoStore {
-					file.GetCsvDb().DelClient(id)
+					file.GetDb().DelClient(id)
 				}
 				}
 			}
 			}
 		case tunnel := <-Bridge.OpenTask:
 		case tunnel := <-Bridge.OpenTask:
 			StartTask(tunnel.Id)
 			StartTask(tunnel.Id)
 		case s := <-Bridge.SecretChan:
 		case s := <-Bridge.SecretChan:
 			logs.Trace("New secret connection, addr", s.Conn.Conn.RemoteAddr())
 			logs.Trace("New secret connection, addr", s.Conn.Conn.RemoteAddr())
-			if t := file.GetCsvDb().GetTaskByMd5Password(s.Password); t != nil {
+			if t := file.GetDb().GetTaskByMd5Password(s.Password); t != nil {
 				if !t.Client.GetConn() {
 				if !t.Client.GetConn() {
 					logs.Info("Connections exceed the current client %d limit", t.Client.Id)
 					logs.Info("Connections exceed the current client %d limit", t.Client.Id)
 					s.Conn.Close()
 					s.Conn.Close()
@@ -158,11 +156,11 @@ func StopServer(id int) error {
 		} else {
 		} else {
 			logs.Warn("stop server id %d error", id)
 			logs.Warn("stop server id %d error", id)
 		}
 		}
-		if t, err := file.GetCsvDb().GetTask(id); err != nil {
+		if t, err := file.GetDb().GetTask(id); err != nil {
 			return err
 			return err
 		} else {
 		} else {
 			t.Status = false
 			t.Status = false
-			file.GetCsvDb().UpdateTask(t)
+			file.GetDb().UpdateTask(t)
 		}
 		}
 		delete(RunList, id)
 		delete(RunList, id)
 		return nil
 		return nil
@@ -202,12 +200,12 @@ func AddTask(t *file.Tunnel) error {
 
 
 //start task
 //start task
 func StartTask(id int) error {
 func StartTask(id int) error {
-	if t, err := file.GetCsvDb().GetTask(id); err != nil {
+	if t, err := file.GetDb().GetTask(id); err != nil {
 		return err
 		return err
 	} else {
 	} else {
 		AddTask(t)
 		AddTask(t)
 		t.Status = true
 		t.Status = true
-		file.GetCsvDb().UpdateTask(t)
+		file.GetDb().UpdateTask(t)
 	}
 	}
 	return nil
 	return nil
 }
 }
@@ -219,16 +217,16 @@ func DelTask(id int) error {
 			return err
 			return err
 		}
 		}
 	}
 	}
-	return file.GetCsvDb().DelTask(id)
+	return file.GetDb().DelTask(id)
 }
 }
 
 
 //get task list by page num
 //get task list by page num
 func GetTunnel(start, length int, typeVal string, clientId int, search string) ([]*file.Tunnel, int) {
 func GetTunnel(start, length int, typeVal string, clientId int, search string) ([]*file.Tunnel, int) {
 	list := make([]*file.Tunnel, 0)
 	list := make([]*file.Tunnel, 0)
 	var cnt int
 	var cnt int
-	keys := file.GetMapKeys(file.GetCsvDb().Tasks, false, "", "")
+	keys := file.GetMapKeys(file.GetDb().JsonDb.Tasks, false, "", "")
 	for _, key := range keys {
 	for _, key := range keys {
-		if value, ok := file.GetCsvDb().Tasks.Load(key); ok {
+		if value, ok := file.GetDb().JsonDb.Tasks.Load(key); ok {
 			v := value.(*file.Tunnel)
 			v := value.(*file.Tunnel)
 			if (typeVal != "" && v.Mode != typeVal || (clientId != 0 && v.Client.Id != clientId)) || (typeVal == "" && clientId != v.Client.Id) {
 			if (typeVal != "" && v.Mode != typeVal || (clientId != 0 && v.Client.Id != clientId)) || (typeVal == "" && clientId != v.Client.Id) {
 				continue
 				continue
@@ -257,15 +255,15 @@ func GetTunnel(start, length int, typeVal string, clientId int, search string) (
 	return list, cnt
 	return list, cnt
 }
 }
 
 
-//获取客户端列表
+//get client list
 func GetClientList(start, length int, search, sort, order string, clientId int) (list []*file.Client, cnt int) {
 func GetClientList(start, length int, search, sort, order string, clientId int) (list []*file.Client, cnt int) {
-	list, cnt = file.GetCsvDb().GetClientList(start, length, search, sort, order, clientId)
+	list, cnt = file.GetDb().GetClientList(start, length, search, sort, order, clientId)
 	dealClientData()
 	dealClientData()
 	return
 	return
 }
 }
 
 
 func dealClientData() {
 func dealClientData() {
-	file.GetCsvDb().Clients.Range(func(key, value interface{}) bool {
+	file.GetDb().JsonDb.Clients.Range(func(key, value interface{}) bool {
 		v := value.(*file.Client)
 		v := value.(*file.Client)
 		if _, ok := Bridge.Client.Load(v.Id); ok {
 		if _, ok := Bridge.Client.Load(v.Id); ok {
 			v.IsConnect = true
 			v.IsConnect = true
@@ -274,7 +272,7 @@ func dealClientData() {
 		}
 		}
 		v.Flow.InletFlow = 0
 		v.Flow.InletFlow = 0
 		v.Flow.ExportFlow = 0
 		v.Flow.ExportFlow = 0
-		file.GetCsvDb().Hosts.Range(func(key, value interface{}) bool {
+		file.GetDb().JsonDb.Hosts.Range(func(key, value interface{}) bool {
 			h := value.(*file.Host)
 			h := value.(*file.Host)
 			if h.Client.Id == v.Id {
 			if h.Client.Id == v.Id {
 				v.Flow.InletFlow += h.Flow.InletFlow
 				v.Flow.InletFlow += h.Flow.InletFlow
@@ -282,7 +280,7 @@ func dealClientData() {
 			}
 			}
 			return true
 			return true
 		})
 		})
-		file.GetCsvDb().Tasks.Range(func(key, value interface{}) bool {
+		file.GetDb().JsonDb.Tasks.Range(func(key, value interface{}) bool {
 			t := value.(*file.Tunnel)
 			t := value.(*file.Tunnel)
 			if t.Client.Id == v.Id {
 			if t.Client.Id == v.Id {
 				v.Flow.InletFlow += t.Flow.InletFlow
 				v.Flow.InletFlow += t.Flow.InletFlow
@@ -295,10 +293,10 @@ func dealClientData() {
 	return
 	return
 }
 }
 
 
-//根据客户端id删除其所属的所有隧道和域名
+//delete all host and tasks by client id
 func DelTunnelAndHostByClientId(clientId int, justDelNoStore bool) {
 func DelTunnelAndHostByClientId(clientId int, justDelNoStore bool) {
 	var ids []int
 	var ids []int
-	file.GetCsvDb().Tasks.Range(func(key, value interface{}) bool {
+	file.GetDb().JsonDb.Tasks.Range(func(key, value interface{}) bool {
 		v := value.(*file.Tunnel)
 		v := value.(*file.Tunnel)
 		if justDelNoStore && !v.NoStore {
 		if justDelNoStore && !v.NoStore {
 			return true
 			return true
@@ -312,7 +310,7 @@ func DelTunnelAndHostByClientId(clientId int, justDelNoStore bool) {
 		DelTask(id)
 		DelTask(id)
 	}
 	}
 	ids = ids[:0]
 	ids = ids[:0]
-	file.GetCsvDb().Hosts.Range(func(key, value interface{}) bool {
+	file.GetDb().JsonDb.Hosts.Range(func(key, value interface{}) bool {
 		v := value.(*file.Host)
 		v := value.(*file.Host)
 		if justDelNoStore && !v.NoStore {
 		if justDelNoStore && !v.NoStore {
 			return true
 			return true
@@ -323,23 +321,23 @@ func DelTunnelAndHostByClientId(clientId int, justDelNoStore bool) {
 		return true
 		return true
 	})
 	})
 	for _, id := range ids {
 	for _, id := range ids {
-		file.GetCsvDb().DelHost(id)
+		file.GetDb().DelHost(id)
 	}
 	}
 }
 }
 
 
-//关闭客户端连接
+//close the client
 func DelClientConnect(clientId int) {
 func DelClientConnect(clientId int) {
 	Bridge.DelClient(clientId)
 	Bridge.DelClient(clientId)
 }
 }
 
 
 func GetDashboardData() map[string]interface{} {
 func GetDashboardData() map[string]interface{} {
 	data := make(map[string]interface{})
 	data := make(map[string]interface{})
-	data["hostCount"] = file.GetCsvDb().GetMapLen(file.GetCsvDb().Hosts)
-	data["clientCount"] = file.GetCsvDb().GetMapLen(file.GetCsvDb().Clients) - 1 //Remove the public key client
+	data["hostCount"] = common.GeSynctMapLen(file.GetDb().JsonDb.Hosts)
+	data["clientCount"] = common.GeSynctMapLen(file.GetDb().JsonDb.Clients) - 1 //Remove the public key client
 	dealClientData()
 	dealClientData()
 	c := 0
 	c := 0
 	var in, out int64
 	var in, out int64
-	file.GetCsvDb().Clients.Range(func(key, value interface{}) bool {
+	file.GetDb().JsonDb.Clients.Range(func(key, value interface{}) bool {
 		v := value.(*file.Client)
 		v := value.(*file.Client)
 		if v.IsConnect {
 		if v.IsConnect {
 			c += 1
 			c += 1
@@ -352,7 +350,7 @@ func GetDashboardData() map[string]interface{} {
 	data["inletFlowCount"] = int(in)
 	data["inletFlowCount"] = int(in)
 	data["exportFlowCount"] = int(out)
 	data["exportFlowCount"] = int(out)
 	var tcp, udp, secret, socks5, p2p, http int
 	var tcp, udp, secret, socks5, p2p, http int
-	file.GetCsvDb().Tasks.Range(func(key, value interface{}) bool {
+	file.GetDb().JsonDb.Tasks.Range(func(key, value interface{}) bool {
 		switch value.(*file.Tunnel).Mode {
 		switch value.(*file.Tunnel).Mode {
 		case "tcp":
 		case "tcp":
 			tcp += 1
 			tcp += 1
@@ -386,7 +384,7 @@ func GetDashboardData() map[string]interface{} {
 	data["logLevel"] = beego.AppConfig.String("log_level")
 	data["logLevel"] = beego.AppConfig.String("log_level")
 	tcpCount := 0
 	tcpCount := 0
 
 
-	file.GetCsvDb().Clients.Range(func(key, value interface{}) bool {
+	file.GetDb().JsonDb.Clients.Range(func(key, value interface{}) bool {
 		tcpCount += int(value.(*file.Client).NowConn)
 		tcpCount += int(value.(*file.Client).NowConn)
 		return true
 		return true
 	})
 	})
@@ -416,10 +414,10 @@ func GetDashboardData() map[string]interface{} {
 	}
 	}
 	//chart
 	//chart
 	var fg int
 	var fg int
-	if len(serverStatus) >= 10 {
-		fg = len(serverStatus) / 10
+	if len(tool.ServerStatus) >= 10 {
+		fg = len(tool.ServerStatus) / 10
 		for i := 0; i <= 9; i++ {
 		for i := 0; i <= 9; i++ {
-			data["sys"+strconv.Itoa(i+1)] = serverStatus[i*fg]
+			data["sys"+strconv.Itoa(i+1)] = tool.ServerStatus[i*fg]
 		}
 		}
 	}
 	}
 	return data
 	return data
@@ -430,51 +428,9 @@ func flowSession(m time.Duration) {
 	for {
 	for {
 		select {
 		select {
 		case <-ticker.C:
 		case <-ticker.C:
-			file.GetCsvDb().StoreHostToCsv()
-			file.GetCsvDb().StoreTasksToCsv()
+			file.GetDb().JsonDb.StoreHostToJsonFile()
+			file.GetDb().JsonDb.StoreTasksToJsonFile()
+			file.GetDb().JsonDb.StoreClientsToJsonFile()
 		}
 		}
 	}
 	}
 }
 }
-
-func getSeverStatus() {
-	for {
-		if len(serverStatus) < 10 {
-			time.Sleep(time.Second)
-		} else {
-			time.Sleep(time.Minute)
-		}
-		cpuPercet, _ := cpu.Percent(0, true)
-		var cpuAll float64
-		for _, v := range cpuPercet {
-			cpuAll += v
-		}
-		m := make(map[string]interface{})
-		loads, _ := load.Avg()
-		m["load1"] = loads.Load1
-		m["load5"] = loads.Load5
-		m["load15"] = loads.Load15
-		m["cpu"] = math.Round(cpuAll / float64(len(cpuPercet)))
-		swap, _ := mem.SwapMemory()
-		m["swap_mem"] = math.Round(swap.UsedPercent)
-		vir, _ := mem.VirtualMemory()
-		m["virtual_mem"] = math.Round(vir.UsedPercent)
-		conn, _ := net.ProtoCounters(nil)
-		io1, _ := net.IOCounters(false)
-		time.Sleep(time.Millisecond * 500)
-		io2, _ := net.IOCounters(false)
-		if len(io2) > 0 && len(io1) > 0 {
-			m["io_send"] = (io2[0].BytesSent - io1[0].BytesSent) * 2
-			m["io_recv"] = (io2[0].BytesRecv - io1[0].BytesRecv) * 2
-		}
-		t := time.Now()
-		m["time"] = strconv.Itoa(t.Hour()) + ":" + strconv.Itoa(t.Minute()) + ":" + strconv.Itoa(t.Second())
-
-		for _, v := range conn {
-			m[v.Protocol] = v.Stats["CurrEstab"]
-		}
-		if len(serverStatus) >= 1440 {
-			serverStatus = serverStatus[1:]
-		}
-		serverStatus = append(serverStatus, m)
-	}
-}

+ 1 - 1
server/test/test.go

@@ -12,7 +12,7 @@ import (
 func TestServerConfig() {
 func TestServerConfig() {
 	var postTcpArr []int
 	var postTcpArr []int
 	var postUdpArr []int
 	var postUdpArr []int
-	file.GetCsvDb().Tasks.Range(func(key, value interface{}) bool {
+	file.GetDb().JsonDb.Tasks.Range(func(key, value interface{}) bool {
 		v := value.(*file.Tunnel)
 		v := value.(*file.Tunnel)
 		if v.Mode == "udp" {
 		if v.Mode == "udp" {
 			isInArr(&postUdpArr, v.Port, v.Remark, "udp")
 			isInArr(&postUdpArr, v.Port, v.Remark, "udp")

+ 61 - 1
server/tool/utils.go

@@ -3,9 +3,24 @@ package tool
 import (
 import (
 	"github.com/cnlh/nps/lib/common"
 	"github.com/cnlh/nps/lib/common"
 	"github.com/cnlh/nps/vender/github.com/astaxie/beego"
 	"github.com/cnlh/nps/vender/github.com/astaxie/beego"
+	"github.com/shirou/gopsutil/cpu"
+	"github.com/shirou/gopsutil/load"
+	"github.com/shirou/gopsutil/mem"
+	"github.com/shirou/gopsutil/net"
+	"math"
+	"strconv"
+	"time"
 )
 )
 
 
-var ports []int
+var (
+	ports        []int
+	ServerStatus []map[string]interface{}
+)
+
+func init() {
+	ServerStatus = make([]map[string]interface{}, 0, 1500)
+	go getSeverStatus()
+}
 
 
 func InitAllowPort() {
 func InitAllowPort() {
 	p := beego.AppConfig.String("allow_ports")
 	p := beego.AppConfig.String("allow_ports")
@@ -28,3 +43,48 @@ func TestServerPort(p int, m string) (b bool) {
 	}
 	}
 	return
 	return
 }
 }
+
+func getSeverStatus() {
+	for {
+		if len(ServerStatus) < 10 {
+			time.Sleep(time.Second)
+		} else {
+			time.Sleep(time.Minute)
+		}
+		cpuPercet, _ := cpu.Percent(0, true)
+		var cpuAll float64
+		for _, v := range cpuPercet {
+			cpuAll += v
+		}
+		m := make(map[string]interface{})
+		loads, _ := load.Avg()
+		m["load1"] = loads.Load1
+		m["load5"] = loads.Load5
+		m["load15"] = loads.Load15
+		m["cpu"] = math.Round(cpuAll / float64(len(cpuPercet)))
+		swap, _ := mem.SwapMemory()
+		m["swap_mem"] = math.Round(swap.UsedPercent)
+		vir, _ := mem.VirtualMemory()
+		m["virtual_mem"] = math.Round(vir.UsedPercent)
+		conn, _ := net.ProtoCounters(nil)
+		io1, _ := net.IOCounters(false)
+		time.Sleep(time.Millisecond * 500)
+		io2, _ := net.IOCounters(false)
+		if len(io2) > 0 && len(io1) > 0 {
+			m["io_send"] = (io2[0].BytesSent - io1[0].BytesSent) * 2
+			m["io_recv"] = (io2[0].BytesRecv - io1[0].BytesRecv) * 2
+		}
+		t := time.Now()
+		m["time"] = strconv.Itoa(t.Hour()) + ":" + strconv.Itoa(t.Minute()) + ":" + strconv.Itoa(t.Second())
+
+		for _, v := range conn {
+			m[v.Protocol] = v.Stats["CurrEstab"]
+		}
+		if len(ServerStatus) >= 1440 {
+			ServerStatus = ServerStatus[1:]
+		}
+		ServerStatus = append(ServerStatus, m)
+	}
+}
+
+

+ 2 - 2
web/controllers/base.go

@@ -156,13 +156,13 @@ func (s *BaseController) CheckUserAuth() {
 		if id := s.GetIntNoErr("id"); id != 0 {
 		if id := s.GetIntNoErr("id"); id != 0 {
 			belong := false
 			belong := false
 			if strings.Contains(s.actionName, "h") {
 			if strings.Contains(s.actionName, "h") {
-				if v, ok := file.GetCsvDb().Hosts.Load(id); ok {
+				if v, ok := file.GetDb().JsonDb.Hosts.Load(id); ok {
 					if v.(*file.Host).Client.Id == s.GetSession("clientId").(int) {
 					if v.(*file.Host).Client.Id == s.GetSession("clientId").(int) {
 						belong = true
 						belong = true
 					}
 					}
 				}
 				}
 			} else {
 			} else {
-				if v, ok := file.GetCsvDb().Tasks.Load(id); ok {
+				if v, ok := file.GetDb().JsonDb.Tasks.Load(id); ok {
 					if v.(*file.Tunnel).Client.Id == s.GetSession("clientId").(int) {
 					if v.(*file.Tunnel).Client.Id == s.GetSession("clientId").(int) {
 						belong = true
 						belong = true
 					}
 					}

+ 10 - 10
web/controllers/client.go

@@ -40,7 +40,7 @@ func (s *ClientController) Add() {
 	} else {
 	} else {
 		t := &file.Client{
 		t := &file.Client{
 			VerifyKey: s.GetString("vkey"),
 			VerifyKey: s.GetString("vkey"),
-			Id:        int(file.GetCsvDb().GetClientId()),
+			Id:        int(file.GetDb().JsonDb.GetClientId()),
 			Status:    true,
 			Status:    true,
 			Remark:    s.GetString("remark"),
 			Remark:    s.GetString("remark"),
 			Cnf: &file.Config{
 			Cnf: &file.Config{
@@ -64,7 +64,7 @@ func (s *ClientController) Add() {
 			t.Rate = rate.NewRate(int64(t.RateLimit * 1024))
 			t.Rate = rate.NewRate(int64(t.RateLimit * 1024))
 			t.Rate.Start()
 			t.Rate.Start()
 		}
 		}
-		if err := file.GetCsvDb().NewClient(t); err != nil {
+		if err := file.GetDb().NewClient(t); err != nil {
 			s.AjaxErr(err.Error())
 			s.AjaxErr(err.Error())
 		}
 		}
 		s.AjaxOk("add success")
 		s.AjaxOk("add success")
@@ -74,7 +74,7 @@ func (s *ClientController) GetClient() {
 	if s.Ctx.Request.Method == "POST" {
 	if s.Ctx.Request.Method == "POST" {
 		id := s.GetIntNoErr("id")
 		id := s.GetIntNoErr("id")
 		data := make(map[string]interface{})
 		data := make(map[string]interface{})
-		if c, err := file.GetCsvDb().GetClient(id); err != nil {
+		if c, err := file.GetDb().GetClient(id); err != nil {
 			data["code"] = 0
 			data["code"] = 0
 		} else {
 		} else {
 			data["code"] = 1
 			data["code"] = 1
@@ -90,7 +90,7 @@ func (s *ClientController) Edit() {
 	id := s.GetIntNoErr("id")
 	id := s.GetIntNoErr("id")
 	if s.Ctx.Request.Method == "GET" {
 	if s.Ctx.Request.Method == "GET" {
 		s.Data["menu"] = "client"
 		s.Data["menu"] = "client"
-		if c, err := file.GetCsvDb().GetClient(id); err != nil {
+		if c, err := file.GetDb().GetClient(id); err != nil {
 			s.error()
 			s.error()
 		} else {
 		} else {
 			s.Data["c"] = c
 			s.Data["c"] = c
@@ -98,17 +98,17 @@ func (s *ClientController) Edit() {
 		s.SetInfo("edit client")
 		s.SetInfo("edit client")
 		s.display()
 		s.display()
 	} else {
 	} else {
-		if c, err := file.GetCsvDb().GetClient(id); err != nil {
+		if c, err := file.GetDb().GetClient(id); err != nil {
 			s.error()
 			s.error()
 		} else {
 		} else {
 			if s.GetString("web_username") != "" {
 			if s.GetString("web_username") != "" {
-				if s.GetString("web_username") == beego.AppConfig.String("web_username") || !file.GetCsvDb().VerifyUserName(s.GetString("web_username"), c.Id) {
+				if s.GetString("web_username") == beego.AppConfig.String("web_username") || !file.GetDb().VerifyUserName(s.GetString("web_username"), c.Id) {
 					s.AjaxErr("web login username duplicate, please reset")
 					s.AjaxErr("web login username duplicate, please reset")
 					return
 					return
 				}
 				}
 			}
 			}
 			if s.GetSession("isAdmin").(bool) {
 			if s.GetSession("isAdmin").(bool) {
-				if !file.GetCsvDb().VerifyVkey(s.GetString("vkey"), c.Id) {
+				if !file.GetDb().VerifyVkey(s.GetString("vkey"), c.Id) {
 					s.AjaxErr("Vkey duplicate, please reset")
 					s.AjaxErr("Vkey duplicate, please reset")
 					return
 					return
 				}
 				}
@@ -135,7 +135,7 @@ func (s *ClientController) Edit() {
 				c.Rate = rate.NewRate(int64(2 << 23))
 				c.Rate = rate.NewRate(int64(2 << 23))
 				c.Rate.Start()
 				c.Rate.Start()
 			}
 			}
-			file.GetCsvDb().StoreClientsToCsv()
+			file.GetDb().JsonDb.StoreClientsToJsonFile()
 		}
 		}
 		s.AjaxOk("save success")
 		s.AjaxOk("save success")
 	}
 	}
@@ -144,7 +144,7 @@ func (s *ClientController) Edit() {
 //更改状态
 //更改状态
 func (s *ClientController) ChangeStatus() {
 func (s *ClientController) ChangeStatus() {
 	id := s.GetIntNoErr("id")
 	id := s.GetIntNoErr("id")
-	if client, err := file.GetCsvDb().GetClient(id); err == nil {
+	if client, err := file.GetDb().GetClient(id); err == nil {
 		client.Status = s.GetBoolNoErr("status")
 		client.Status = s.GetBoolNoErr("status")
 		if client.Status == false {
 		if client.Status == false {
 			server.DelClientConnect(client.Id)
 			server.DelClientConnect(client.Id)
@@ -157,7 +157,7 @@ func (s *ClientController) ChangeStatus() {
 //删除客户端
 //删除客户端
 func (s *ClientController) Del() {
 func (s *ClientController) Del() {
 	id := s.GetIntNoErr("id")
 	id := s.GetIntNoErr("id")
-	if err := file.GetCsvDb().DelClient(id); err != nil {
+	if err := file.GetDb().DelClient(id); err != nil {
 		s.AjaxErr("delete error")
 		s.AjaxErr("delete error")
 	}
 	}
 	server.DelTunnelAndHostByClientId(id, false)
 	server.DelTunnelAndHostByClientId(id, false)

+ 19 - 19
web/controllers/index.go

@@ -94,7 +94,7 @@ func (s *IndexController) Add() {
 			ServerIp:  s.GetString("server_ip"),
 			ServerIp:  s.GetString("server_ip"),
 			Mode:      s.GetString("type"),
 			Mode:      s.GetString("type"),
 			Target:    &file.Target{TargetStr: s.GetString("target")},
 			Target:    &file.Target{TargetStr: s.GetString("target")},
-			Id:        int(file.GetCsvDb().GetTaskId()),
+			Id:        int(file.GetDb().JsonDb.GetTaskId()),
 			Status:    true,
 			Status:    true,
 			Remark:    s.GetString("remark"),
 			Remark:    s.GetString("remark"),
 			Password:  s.GetString("password"),
 			Password:  s.GetString("password"),
@@ -106,10 +106,10 @@ func (s *IndexController) Add() {
 			s.AjaxErr("The port cannot be opened because it may has been occupied or is no longer allowed.")
 			s.AjaxErr("The port cannot be opened because it may has been occupied or is no longer allowed.")
 		}
 		}
 		var err error
 		var err error
-		if t.Client, err = file.GetCsvDb().GetClient(s.GetIntNoErr("client_id")); err != nil {
+		if t.Client, err = file.GetDb().GetClient(s.GetIntNoErr("client_id")); err != nil {
 			s.AjaxErr(err.Error())
 			s.AjaxErr(err.Error())
 		}
 		}
-		if err := file.GetCsvDb().NewTask(t); err != nil {
+		if err := file.GetDb().NewTask(t); err != nil {
 			s.AjaxErr(err.Error())
 			s.AjaxErr(err.Error())
 		}
 		}
 		if err := server.AddTask(t); err != nil {
 		if err := server.AddTask(t); err != nil {
@@ -122,7 +122,7 @@ func (s *IndexController) Add() {
 func (s *IndexController) GetOneTunnel() {
 func (s *IndexController) GetOneTunnel() {
 	id := s.GetIntNoErr("id")
 	id := s.GetIntNoErr("id")
 	data := make(map[string]interface{})
 	data := make(map[string]interface{})
-	if t, err := file.GetCsvDb().GetTask(id); err != nil {
+	if t, err := file.GetDb().GetTask(id); err != nil {
 		data["code"] = 0
 		data["code"] = 0
 	} else {
 	} else {
 		data["code"] = 1
 		data["code"] = 1
@@ -134,7 +134,7 @@ func (s *IndexController) GetOneTunnel() {
 func (s *IndexController) Edit() {
 func (s *IndexController) Edit() {
 	id := s.GetIntNoErr("id")
 	id := s.GetIntNoErr("id")
 	if s.Ctx.Request.Method == "GET" {
 	if s.Ctx.Request.Method == "GET" {
-		if t, err := file.GetCsvDb().GetTask(id); err != nil {
+		if t, err := file.GetDb().GetTask(id); err != nil {
 			s.error()
 			s.error()
 		} else {
 		} else {
 			s.Data["t"] = t
 			s.Data["t"] = t
@@ -142,10 +142,10 @@ func (s *IndexController) Edit() {
 		s.SetInfo("edit tunnel")
 		s.SetInfo("edit tunnel")
 		s.display()
 		s.display()
 	} else {
 	} else {
-		if t, err := file.GetCsvDb().GetTask(id); err != nil {
+		if t, err := file.GetDb().GetTask(id); err != nil {
 			s.error()
 			s.error()
 		} else {
 		} else {
-			if client, err := file.GetCsvDb().GetClient(s.GetIntNoErr("client_id")); err != nil {
+			if client, err := file.GetDb().GetClient(s.GetIntNoErr("client_id")); err != nil {
 				s.AjaxErr("modified error,the client is not exist")
 				s.AjaxErr("modified error,the client is not exist")
 				return
 				return
 			} else {
 			} else {
@@ -166,7 +166,7 @@ func (s *IndexController) Edit() {
 			t.LocalPath = s.GetString("local_path")
 			t.LocalPath = s.GetString("local_path")
 			t.StripPre = s.GetString("strip_pre")
 			t.StripPre = s.GetString("strip_pre")
 			t.Remark = s.GetString("remark")
 			t.Remark = s.GetString("remark")
-			file.GetCsvDb().UpdateTask(t)
+			file.GetDb().UpdateTask(t)
 			server.StopServer(t.Id)
 			server.StopServer(t.Id)
 			server.StartTask(t.Id)
 			server.StartTask(t.Id)
 		}
 		}
@@ -207,7 +207,7 @@ func (s *IndexController) HostList() {
 	} else {
 	} else {
 		start, length := s.GetAjaxParams()
 		start, length := s.GetAjaxParams()
 		clientId := s.GetIntNoErr("client_id")
 		clientId := s.GetIntNoErr("client_id")
-		list, cnt := file.GetCsvDb().GetHost(start, length, clientId, s.GetString("search"))
+		list, cnt := file.GetDb().GetHost(start, length, clientId, s.GetString("search"))
 		s.AjaxTable(list, cnt, cnt)
 		s.AjaxTable(list, cnt, cnt)
 	}
 	}
 }
 }
@@ -215,7 +215,7 @@ func (s *IndexController) HostList() {
 func (s *IndexController) GetHost() {
 func (s *IndexController) GetHost() {
 	if s.Ctx.Request.Method == "POST" {
 	if s.Ctx.Request.Method == "POST" {
 		data := make(map[string]interface{})
 		data := make(map[string]interface{})
-		if h, err := file.GetCsvDb().GetHostById(s.GetIntNoErr("id")); err != nil {
+		if h, err := file.GetDb().GetHostById(s.GetIntNoErr("id")); err != nil {
 			data["code"] = 0
 			data["code"] = 0
 		} else {
 		} else {
 			data["data"] = h
 			data["data"] = h
@@ -228,7 +228,7 @@ func (s *IndexController) GetHost() {
 
 
 func (s *IndexController) DelHost() {
 func (s *IndexController) DelHost() {
 	id := s.GetIntNoErr("id")
 	id := s.GetIntNoErr("id")
-	if err := file.GetCsvDb().DelHost(id); err != nil {
+	if err := file.GetDb().DelHost(id); err != nil {
 		s.AjaxErr("delete error")
 		s.AjaxErr("delete error")
 	}
 	}
 	s.AjaxOk("delete success")
 	s.AjaxOk("delete success")
@@ -242,7 +242,7 @@ func (s *IndexController) AddHost() {
 		s.display("index/hadd")
 		s.display("index/hadd")
 	} else {
 	} else {
 		h := &file.Host{
 		h := &file.Host{
-			Id:           int(file.GetCsvDb().GetHostId()),
+			Id:           int(file.GetDb().JsonDb.GetHostId()),
 			Host:         s.GetString("host"),
 			Host:         s.GetString("host"),
 			Target:       &file.Target{TargetStr: s.GetString("target")},
 			Target:       &file.Target{TargetStr: s.GetString("target")},
 			HeaderChange: s.GetString("header"),
 			HeaderChange: s.GetString("header"),
@@ -253,10 +253,10 @@ func (s *IndexController) AddHost() {
 			Scheme:       s.GetString("scheme"),
 			Scheme:       s.GetString("scheme"),
 		}
 		}
 		var err error
 		var err error
-		if h.Client, err = file.GetCsvDb().GetClient(s.GetIntNoErr("client_id")); err != nil {
+		if h.Client, err = file.GetDb().GetClient(s.GetIntNoErr("client_id")); err != nil {
 			s.AjaxErr("add error")
 			s.AjaxErr("add error")
 		}
 		}
-		if err := file.GetCsvDb().NewHost(h); err != nil {
+		if err := file.GetDb().NewHost(h); err != nil {
 			s.AjaxErr("add fail" + err.Error())
 			s.AjaxErr("add fail" + err.Error())
 		}
 		}
 		s.AjaxOk("add success")
 		s.AjaxOk("add success")
@@ -267,7 +267,7 @@ func (s *IndexController) EditHost() {
 	id := s.GetIntNoErr("id")
 	id := s.GetIntNoErr("id")
 	if s.Ctx.Request.Method == "GET" {
 	if s.Ctx.Request.Method == "GET" {
 		s.Data["menu"] = "host"
 		s.Data["menu"] = "host"
-		if h, err := file.GetCsvDb().GetHostById(id); err != nil {
+		if h, err := file.GetDb().GetHostById(id); err != nil {
 			s.error()
 			s.error()
 		} else {
 		} else {
 			s.Data["h"] = h
 			s.Data["h"] = h
@@ -275,7 +275,7 @@ func (s *IndexController) EditHost() {
 		s.SetInfo("edit")
 		s.SetInfo("edit")
 		s.display("index/hedit")
 		s.display("index/hedit")
 	} else {
 	} else {
-		if h, err := file.GetCsvDb().GetHostById(id); err != nil {
+		if h, err := file.GetDb().GetHostById(id); err != nil {
 			s.error()
 			s.error()
 		} else {
 		} else {
 			if h.Host != s.GetString("host") {
 			if h.Host != s.GetString("host") {
@@ -283,12 +283,12 @@ func (s *IndexController) EditHost() {
 				tmpHost.Host = s.GetString("host")
 				tmpHost.Host = s.GetString("host")
 				tmpHost.Location = s.GetString("location")
 				tmpHost.Location = s.GetString("location")
 				tmpHost.Scheme = s.GetString("scheme")
 				tmpHost.Scheme = s.GetString("scheme")
-				if file.GetCsvDb().IsHostExist(tmpHost) {
+				if file.GetDb().IsHostExist(tmpHost) {
 					s.AjaxErr("host has exist")
 					s.AjaxErr("host has exist")
 					return
 					return
 				}
 				}
 			}
 			}
-			if client, err := file.GetCsvDb().GetClient(s.GetIntNoErr("client_id")); err != nil {
+			if client, err := file.GetDb().GetClient(s.GetIntNoErr("client_id")); err != nil {
 				s.AjaxErr("modified error,the client is not exist")
 				s.AjaxErr("modified error,the client is not exist")
 			} else {
 			} else {
 				h.Client = client
 				h.Client = client
@@ -300,7 +300,7 @@ func (s *IndexController) EditHost() {
 			h.Remark = s.GetString("remark")
 			h.Remark = s.GetString("remark")
 			h.Location = s.GetString("location")
 			h.Location = s.GetString("location")
 			h.Scheme = s.GetString("scheme")
 			h.Scheme = s.GetString("scheme")
-			file.GetCsvDb().StoreHostToCsv()
+			file.GetDb().JsonDb.StoreHostToJsonFile()
 		}
 		}
 		s.AjaxOk("modified success")
 		s.AjaxOk("modified success")
 	}
 	}

+ 1 - 1
web/controllers/login.go

@@ -24,7 +24,7 @@ func (self *LoginController) Verify() {
 	}
 	}
 	b, err := beego.AppConfig.Bool("allow_user_login")
 	b, err := beego.AppConfig.Bool("allow_user_login")
 	if err == nil && b && !auth {
 	if err == nil && b && !auth {
-		file.GetCsvDb().Clients.Range(func(key, value interface{}) bool {
+		file.GetDb().JsonDb.Clients.Range(func(key, value interface{}) bool {
 			v := value.(*file.Client)
 			v := value.(*file.Client)
 			if !v.Status || v.NoDisplay {
 			if !v.Status || v.NoDisplay {
 				return true
 				return true