HFish/core/protocol/redis/redis.go
SanJin 60d7580cea 1. ~ 修复 Mysql 三次握手不主动关闭连接异常问题
2. ~ 日记格式完善
3. ~ 暗网钓鱼支持
4. ~ UI 优化
5. ~ 支持分页
6. ~ 筛选
7. ~ 提供黑名单IP接口
8. ~ 邮件发送支持编辑器
9. ~ 支持 ip 地理信息
2019-08-09 10:13:54 +08:00

132 lines
2.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package redis
import (
"net"
"bufio"
"strings"
"strconv"
"HFish/utils/try"
"HFish/core/report"
"HFish/utils/log"
)
var kvData map[string]string
func Start(addr string) {
kvData = make(map[string]string)
//建立socket监听端口
netListen, _ := net.Listen("tcp", addr)
defer netListen.Close()
for {
conn, err := netListen.Accept()
if err != nil {
continue
}
arr := strings.Split(conn.RemoteAddr().String(), ":")
id := report.ReportRedis(arr[0], conn.RemoteAddr().String()+" 已经连接")
log.Pr("Redis", arr[0], "已经连接")
go handleConnection(conn, id)
}
}
//处理 Redis 连接
func handleConnection(conn net.Conn, id int64) {
for {
str := parseRESP(conn)
switch value := str.(type) {
case string:
go report.ReportUpdateRedis(id, "&&"+str.(string))
if len(value) == 0 {
goto end
}
conn.Write([]byte(value))
case []string:
if value[0] == "SET" || value[0] == "set" {
// 模拟 redis set
try.Try(func() {
key := string(value[1])
val := string(value[2])
kvData[key] = val
go report.ReportUpdateRedis(id, "&&"+value[0]+" "+value[1]+" "+value[2])
}).Catch(func() {
// 取不到 key 会异常
})
conn.Write([]byte("+OK\r\n"))
} else if value[0] == "GET" || value[0] == "get" {
// 模拟 redis get
key := string(value[1])
val := string(kvData[key])
valLen := strconv.Itoa(len(val))
str := "$" + valLen + "\r\n" + val + "\r\n"
go report.ReportUpdateRedis(id, "&&"+value[0]+" "+value[1])
conn.Write([]byte(str))
} else {
try.Try(func() {
go report.ReportUpdateRedis(id, "&&"+value[0]+" "+value[1])
}).Catch(func() {
go report.ReportUpdateRedis(id, "&&"+value[0])
})
conn.Write([]byte("+OK\r\n"))
}
break
default:
}
}
end:
conn.Close()
}
// 解析 Redis 协议
func parseRESP(conn net.Conn) interface{} {
r := bufio.NewReader(conn)
line, err := r.ReadString('\n')
if err != nil {
return ""
}
cmdType := string(line[0])
cmdTxt := strings.Trim(string(line[1:]), "\r\n")
switch cmdType {
case "*":
count, _ := strconv.Atoi(cmdTxt)
var data []string
for i := 0; i < count; i++ {
line, _ := r.ReadString('\n')
cmd_txt := strings.Trim(string(line[1:]), "\r\n")
c, _ := strconv.Atoi(cmd_txt)
length := c + 2
str := ""
for length > 0 {
block, _ := r.Peek(length)
if length != len(block) {
}
r.Discard(length)
str += string(block)
length -= len(block)
}
data = append(data, strings.Trim(str, "\r\n"))
}
return data
default:
return cmdTxt
}
}