Skip to content

Commit

Permalink
Merge 5b57e0d into 1c6e072
Browse files Browse the repository at this point in the history
  • Loading branch information
Hoshinonyaruko authored Nov 25, 2024
2 parents 1c6e072 + 5b57e0d commit eaf6488
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 87 deletions.
6 changes: 1 addition & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -459,11 +459,7 @@ func main() {
r.POST("/uploadrecord", server.UploadBase64RecordHandler(rateLimiter))
// 使用 CreateHandleValidation,传入 WebhookHandler 实例
server.InitPrivateKey(conf.Settings.ClientSecret)
if len(conf.Settings.WebhookPrefixIp) == 0 {
r.POST("/"+conf.Settings.WebhookPath, server.CreateHandleValidationSafe(webhookHandler))
} else {
r.POST("/"+conf.Settings.WebhookPath, server.CreateHandleValidation(webhookHandler, conf.Settings.WebhookPrefixIp))
}
r.POST("/"+conf.Settings.WebhookPath, server.CreateHandleValidationSafe(webhookHandler))

r.Static("/channel_temp", "./channel_temp")
if config.GetFrpPort() == "0" && !config.GetDisableWebui() {
Expand Down
85 changes: 4 additions & 81 deletions server/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"sync/atomic"

"github.com/gin-gonic/gin"
"github.com/hoshinonyaruko/gensokyo/mylog"
"github.com/tencent-connect/botgo/dto"
"github.com/tencent-connect/botgo/event"
"github.com/tencent-connect/botgo/websocket/client"
Expand Down Expand Up @@ -71,84 +72,6 @@ func InitPrivateKey(botSecret string) {
publicKey = pkey
}

// CreateHandleValidation 创建用于签名验证和消息入队的处理函数
func CreateHandleValidation(wh *WebhookHandler, allowedPrefixes []string) gin.HandlerFunc {
return func(c *gin.Context) {
// 提取客户端 IP
clientIP := c.ClientIP()

// 检查是否匹配任意一个允许的前缀
allowed := false
for _, prefix := range allowedPrefixes {
if strings.HasPrefix(clientIP, prefix) {
allowed = true
break
}
}

if !allowed {
log.Printf("Request from unauthorized IP: %s", clientIP)
c.JSON(http.StatusForbidden, gin.H{"error": "Access denied"})
return
}

// 读取 HTTP Body
httpBody, err := io.ReadAll(c.Request.Body)
if err != nil {
log.Println("Failed to read HTTP body:", err)
c.JSON(http.StatusBadRequest, gin.H{"error": "Failed to read request body"})
return
}

// 解析请求数据
var payload Payload
if err := json.Unmarshal(httpBody, &payload); err != nil {
log.Println("Failed to parse HTTP payload:", err)
c.JSON(http.StatusBadRequest, gin.H{"error": "Failed to parse payload"})
return
}

// 判断 Op 类型
switch payload.Op {
case 13:
// 签名验证逻辑
var msg bytes.Buffer
msg.WriteString(payload.D.EventTs)
msg.WriteString(payload.D.PlainToken)
signature := hex.EncodeToString(ed25519.Sign(privateKey, msg.Bytes()))

// 返回签名验证响应
c.JSON(http.StatusOK, gin.H{
"plain_token": payload.D.PlainToken,
"signature": signature,
})

default:
// 异步推送消息到队列
go func(httpBody []byte, payload Payload) {
webhookPayload := &WebhookPayload{
PlainToken: payload.D.PlainToken,
EventTs: payload.D.EventTs,
RawMessage: httpBody,
}

// 尝试写入队列
select {
case wh.messageQueue <- webhookPayload:
log.Println("Message enqueued successfully")
default:
log.Println("Message queue is full, dropping message")
}
}(httpBody, payload)

// 返回 HTTP Callback ACK 响应
c.JSON(http.StatusOK, gin.H{
"op": 12,
})
}
}
}

func CreateHandleValidationSafe(wh *WebhookHandler) gin.HandlerFunc {
return func(c *gin.Context) {
// 读取 HTTP Body
Expand Down Expand Up @@ -204,7 +127,7 @@ func CreateHandleValidationSafe(wh *WebhookHandler) gin.HandlerFunc {
// 尝试写入队列
select {
case wh.messageQueue <- webhookPayload:
log.Println("Message enqueued successfully")
mylog.Println("Message enqueued successfully")
default:
log.Println("Message queue is full, dropping message")
}
Expand Down Expand Up @@ -265,7 +188,7 @@ func validateSignature(req *http.Request, publicKey ed25519.PublicKey) error {
func (wh *WebhookHandler) ListenAndProcessMessages() {
for payload := range wh.messageQueue {
go func(p *WebhookPayload) {
log.Printf("Processing Webhook event with token: %s", p.PlainToken)
mylog.Printf("Processing Webhook event with token: %s", p.PlainToken)
// 业务逻辑处理的地方
payload := &dto.WSPayload{}
if err := json.Unmarshal(p.RawMessage, payload); err != nil {
Expand All @@ -276,7 +199,7 @@ func (wh *WebhookHandler) ListenAndProcessMessages() {
atomic.StoreInt64(&client.Global_s, payload.S)

payload.RawMessage = p.RawMessage
log.Printf("%s receive %s message, %s", p.EventTs, dto.OPMeans(payload.OPCode), string(p.RawMessage))
mylog.Printf("%s receive %s message, %s", p.EventTs, dto.OPMeans(payload.OPCode), string(p.RawMessage))

// 性能不够 报错也没用 就扬了
go event.ParseAndHandle(payload)
Expand Down
1 change: 0 additions & 1 deletion template/config_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ settings:
crt : "" #证书路径 从你的域名服务商或云服务商申请签发SSL证书(qq要求SSL)
key : "" #密钥路径 Apache(crt文件、key文件)示例: "C:\\123.key" \需要双写成\\
webhook_path : "webhook" #webhook监听的地址,默认\webhook
webhook_prefix_ip : [] #默认为空,通过webhook进行签名验证来源,设置时,只允许ip前缀的请求,不验证签名. 2024年11月22日最近的webhookip都是 183.47.105. 开始的.
force_ssl : false #默认当port设置为443时启用ssl,true可以在其他port设置下强制启用ssl.
http_port_after_ssl : "444" # 指定启动SSL之后的备用HTTP服务器的端口号,默认为444
Expand Down

0 comments on commit eaf6488

Please sign in to comment.