Files
bl/modules/base/middleware/middleware.go
昔念 a7bfaf92df
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
1
2026-02-07 16:47:33 +08:00

212 lines
6.6 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 middleware
import (
"blazing/common/rpc"
"blazing/cool"
"blazing/modules/base/config"
"blazing/modules/config/service"
"encoding/json"
"fmt"
"math/rand"
"net/http"
"net/http/httputil"
"net/url"
"path/filepath"
"strconv"
"time"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gtime"
"github.com/gogf/gf/v2/util/gconv"
"github.com/golang-jwt/jwt/v4"
"github.com/google/uuid"
"github.com/lxzan/gws"
)
const UpStream = "http://43.248.3.21:45632/"
func MiddlewareCORS(r *ghttp.Request) {
r.Response.CORSDefault()
corsOptions := r.Response.DefaultCORSOptions()
corsOptions.AllowDomain = []string{"*", "localhost", "tauri.localhost"}
if !r.Response.CORSAllowedOrigin(corsOptions) {
r.Response.WriteStatus(http.StatusForbidden)
return
}
r.Response.CORS(corsOptions)
if r.Response.Request.Method == "OPTIONS" {
r.Response.WriteStatus(http.StatusOK)
return
}
// fmt.Println(r.Response.Header())
//g.Dump(r.Response.Server.SetConfig(gtt))
//r.Response.Header().Del("Server") // 删除Server头
// r.Response.Header().Set("Server", "blazing")
r.Middleware.Next()
}
func StartServerProxy() {
s := g.Server()
// Parse the upstream URL
u, _ := url.Parse(UpStream)
// Create a new reverse proxy instance
proxy := httputil.NewSingleHostReverseProxy(u)
// Configure error handling for proxy failures
proxy.ErrorHandler = func(writer http.ResponseWriter, request *http.Request, e error) {
writer.WriteHeader(http.StatusBadGateway)
}
s.BindHandler("/bbs/api/fof/upload", func(r *ghttp.Request) {
// 1. 调用上传方法仍返回单个URL字符串不改动Upload方法
urlStr, err := cool.File().Upload(r.Context())
// 2. 错误处理返回标准化错误JSON
if err != nil {
r.Response.Header().Set("Content-Type", "application/json; charset=utf-8")
r.Response.WriteHeader(http.StatusBadRequest)
json.NewEncoder(r.Response.Writer).Encode(map[string]interface{}{
"code": 1,
"msg": err.Error(),
"data": nil,
})
return
}
// 3. 基于返回的URL构造完整的JSON结构体和示例完全一致
// 解析URL中的文件名和路径从urlStr中提取
baseName := filepath.Base(urlStr) // 提取文件名如13e8d062-xxx.jpg
dir := gtime.Now().Format("Y-m-d") // 日期目录2026-02-07
path := fmt.Sprintf("%s/%s", dir, baseName) // 拼接path字段
rand.Seed(time.Now().UnixNano())
randomID := strconv.Itoa(rand.Intn(1000)) // 模拟ID如54
uuidStr := uuid.New().String() // 生成UUID
humanSize := "743kB" // 模拟易读大小(可根据实际需求优化)
fileSize := int64(760783) // 模拟文件大小(字节)
// 构造和示例完全一致的响应结构体
fullResponse := map[string]interface{}{
"data": []map[string]interface{}{
{
"type": "files",
"id": randomID,
"attributes": map[string]interface{}{
"baseName": baseName,
"path": path,
"url": urlStr, // 用Upload返回的URL
"type": "image/jpeg", // 模拟MIME类型
"size": fileSize,
"humanSize": humanSize,
"createdAt": nil, // null
"uuid": uuidStr,
"tag": "just-url",
"hidden": false,
"bbcode": `[img]` + urlStr + `[/img]`, // 和URL一致
"shared": false,
"canViewInfo": false,
"canHide": true,
"canDelete": true,
},
},
},
}
// 4. 输出完整JSON响应
r.Response.Header().Set("Content-Type", "application/json; charset=utf-8")
if err := json.NewEncoder(r.Response.Writer).Encode(fullResponse); err != nil {
// 兜底错误
fmt.Fprintf(r.Response.Writer, `{"code":1,"msg":"响应生成失败:%s","data":null}`, err.Error())
}
})
// Handle all requests with path prefix "/proxy/*"
s.BindHandler("/bbs/*url", func(r *ghttp.Request) {
var (
//originalPath = r.Request.URL.Path
proxyToPath = "/" + r.Get("url").String()
)
// Rewrite the request path
r.Request.URL.Path = proxyToPath
// Log the proxy operation
//g.Log().Infof(r.Context(), `proxy:"%s" -> backend:"%s"`, originalPath, proxyToPath)
// Ensure request body can be read multiple times if needed
r.MakeBodyRepeatableRead(false)
// Forward the request to the backend server
proxy.ServeHTTP(r.Response.Writer, r.Request)
})
}
func init() {
if config.Config.Middleware.Authority.Enable {
g.Server().BindMiddleware("/admin/*/open/*", BaseAuthorityMiddlewareOpen)
g.Server().BindMiddleware("/rpc/*", BaseAuthorityMiddlewareOpen)
g.Server().BindMiddleware("/admin/*/comm/*", BaseAuthorityMiddlewareComm)
g.Server().BindMiddleware("/admin/*", BaseAuthorityMiddleware)
// g.Server().BindMiddleware("/*", AutoI18n)
g.Server().BindMiddleware("/*", MiddlewareCORS)
}
if config.Config.Middleware.Log.Enable {
g.Server().BindMiddleware("/admin/*", BaseLog)
}
StartServerProxy()
tt := rpc.CServer()
g.Server().BindHandler("/rpc/*", func(r *ghttp.Request) {
tt.ServeHTTP(r.Response.Writer, r.Request)
})
g.Server().BindHandler("/server/*", func(r *ghttp.Request) {
servert := new(ServerHandler)
id := gconv.Uint16(r.URL.Query().Get("id"))
servert.isinstall = gconv.Uint32(r.URL.Query().Get("isinstall"))
servert.ServerList = service.NewServerService().StartUPdate(id, int(servert.isinstall))
upgrader := gws.NewUpgrader(servert, &gws.ServerOption{
Authorize: func(_ *http.Request, _ gws.SessionStorage) bool {
tokenString := r.URL.Query().Get("Authorization")
token, err := jwt.ParseWithClaims(tokenString, &cool.Claims{}, func(_ *jwt.Token) (interface{}, error) {
return []byte(config.Config.Jwt.Secret), nil
})
if err != nil {
return false
}
if !token.Valid {
return false
}
admin := token.Claims.(*cool.Claims)
if admin.UserId != 10001 {
return false
}
// var name = r.URL.Query().Get("name")
// if name == "" {
// return false
// }
// t, _ := service.NewBaseSysUserService().Person(admin.UserID)
//Loger.Debug(context.TODO(), t.Mimi)
// session.Store("name", t.Mimi)
//session.Store("key", r.Header.Get("Sec-WebSocket-Key"))
return true
},
})
socket, err := upgrader.Upgrade(r.Response.Writer, r.Request)
if err != nil {
fmt.Println(err)
return
}
// ants.Submit(func() {
// socket.ReadLoop()
// })
// ants.Submit(func() { socket.ReadLoop() })
go socket.ReadLoop()
})
}