Skip to content

Commit 12bd5a0

Browse files
committed
add(func): spuuort virtual host
1 parent b5626b2 commit 12bd5a0

8 files changed

Lines changed: 317 additions & 6 deletions

File tree

internal/conf/const.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,4 +191,5 @@ const (
191191
PathKey
192192
SharingIDKey
193193
SkipHookKey
194+
VirtualHostKey
194195
)

internal/db/db.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ var db *gorm.DB
1212

1313
func Init(d *gorm.DB) {
1414
db = d
15-
err := AutoMigrate(new(model.Storage), new(model.User), new(model.Meta), new(model.SettingItem), new(model.SearchNode), new(model.TaskItem), new(model.SSHPublicKey), new(model.SharingDB))
15+
err := AutoMigrate(new(model.Storage), new(model.User), new(model.Meta), new(model.SettingItem), new(model.SearchNode), new(model.TaskItem), new(model.SSHPublicKey), new(model.SharingDB), new(model.VirtualHost))
1616
if err != nil {
1717
log.Fatalf("failed migrate database: %s", err.Error())
1818
}

internal/db/virtual_host.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package db
2+
3+
import (
4+
"github.com/OpenListTeam/OpenList/v4/internal/model"
5+
"github.com/pkg/errors"
6+
)
7+
8+
func GetVirtualHostByDomain(domain string) (*model.VirtualHost, error) {
9+
var v model.VirtualHost
10+
if err := db.Where("domain = ?", domain).First(&v).Error; err != nil {
11+
return nil, errors.Wrapf(err, "failed select virtual host")
12+
}
13+
return &v, nil
14+
}
15+
16+
func GetVirtualHostById(id uint) (*model.VirtualHost, error) {
17+
var v model.VirtualHost
18+
if err := db.First(&v, id).Error; err != nil {
19+
return nil, errors.Wrapf(err, "failed get virtual host")
20+
}
21+
return &v, nil
22+
}
23+
24+
func CreateVirtualHost(v *model.VirtualHost) error {
25+
return errors.WithStack(db.Create(v).Error)
26+
}
27+
28+
func UpdateVirtualHost(v *model.VirtualHost) error {
29+
return errors.WithStack(db.Save(v).Error)
30+
}
31+
32+
func GetVirtualHosts(pageIndex, pageSize int) (vhosts []model.VirtualHost, count int64, err error) {
33+
vhostDB := db.Model(&model.VirtualHost{})
34+
if err = vhostDB.Count(&count).Error; err != nil {
35+
return nil, 0, errors.Wrapf(err, "failed get virtual hosts count")
36+
}
37+
if err = vhostDB.Order(columnName("id")).Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&vhosts).Error; err != nil {
38+
return nil, 0, errors.Wrapf(err, "failed find virtual hosts")
39+
}
40+
return vhosts, count, nil
41+
}
42+
43+
func DeleteVirtualHostById(id uint) error {
44+
return errors.WithStack(db.Delete(&model.VirtualHost{}, id).Error)
45+
}

internal/model/virtual_host.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package model
2+
3+
type VirtualHost struct {
4+
ID uint `json:"id" gorm:"primaryKey"`
5+
Enabled bool `json:"enabled"`
6+
Domain string `json:"domain" gorm:"unique" binding:"required"`
7+
Path string `json:"path" binding:"required"`
8+
WebHosting bool `json:"web_hosting"`
9+
}

server/handles/virtual_host.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package handles
2+
3+
import (
4+
"strconv"
5+
6+
"github.com/OpenListTeam/OpenList/v4/internal/model"
7+
"github.com/OpenListTeam/OpenList/v4/internal/op"
8+
"github.com/OpenListTeam/OpenList/v4/server/common"
9+
"github.com/gin-gonic/gin"
10+
)
11+
12+
func ListVirtualHosts(c *gin.Context) {
13+
var req model.PageReq
14+
if err := c.ShouldBind(&req); err != nil {
15+
common.ErrorResp(c, err, 400)
16+
return
17+
}
18+
req.Validate()
19+
vhosts, total, err := op.GetVirtualHosts(req.Page, req.PerPage)
20+
if err != nil {
21+
common.ErrorResp(c, err, 500, true)
22+
return
23+
}
24+
common.SuccessResp(c, common.PageResp{
25+
Content: vhosts,
26+
Total: total,
27+
})
28+
}
29+
30+
func GetVirtualHost(c *gin.Context) {
31+
idStr := c.Query("id")
32+
id, err := strconv.Atoi(idStr)
33+
if err != nil {
34+
common.ErrorResp(c, err, 400)
35+
return
36+
}
37+
vhost, err := op.GetVirtualHostById(uint(id))
38+
if err != nil {
39+
common.ErrorResp(c, err, 500, true)
40+
return
41+
}
42+
common.SuccessResp(c, vhost)
43+
}
44+
45+
func CreateVirtualHost(c *gin.Context) {
46+
var req model.VirtualHost
47+
if err := c.ShouldBind(&req); err != nil {
48+
common.ErrorResp(c, err, 400)
49+
return
50+
}
51+
if err := op.CreateVirtualHost(&req); err != nil {
52+
common.ErrorResp(c, err, 500, true)
53+
} else {
54+
common.SuccessResp(c)
55+
}
56+
}
57+
58+
func UpdateVirtualHost(c *gin.Context) {
59+
var req model.VirtualHost
60+
if err := c.ShouldBind(&req); err != nil {
61+
common.ErrorResp(c, err, 400)
62+
return
63+
}
64+
if err := op.UpdateVirtualHost(&req); err != nil {
65+
common.ErrorResp(c, err, 500, true)
66+
} else {
67+
common.SuccessResp(c)
68+
}
69+
}
70+
71+
func DeleteVirtualHost(c *gin.Context) {
72+
idStr := c.Query("id")
73+
id, err := strconv.Atoi(idStr)
74+
if err != nil {
75+
common.ErrorResp(c, err, 400)
76+
return
77+
}
78+
if err := op.DeleteVirtualHostById(uint(id)); err != nil {
79+
common.ErrorResp(c, err, 500, true)
80+
return
81+
}
82+
common.SuccessResp(c)
83+
}

server/middlewares/virtual_host.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package middlewares
2+
3+
import (
4+
"strings"
5+
6+
"github.com/OpenListTeam/OpenList/v4/internal/conf"
7+
"github.com/OpenListTeam/OpenList/v4/internal/op"
8+
"github.com/OpenListTeam/OpenList/v4/server/common"
9+
"github.com/gin-gonic/gin"
10+
)
11+
12+
// VirtualHost 虚拟主机中间件,根据请求的 Host 头匹配虚拟主机配置
13+
func VirtualHost(c *gin.Context) {
14+
host := c.Request.Host
15+
// 去掉端口号
16+
domain := stripPort(host)
17+
if domain == "" {
18+
c.Next()
19+
return
20+
}
21+
22+
vhost, err := op.GetVirtualHostByDomain(domain)
23+
if err != nil || !vhost.Enabled {
24+
// 未找到匹配的虚拟主机或未启用,继续正常处理
25+
c.Next()
26+
return
27+
}
28+
29+
// 将虚拟主机信息存入请求上下文
30+
common.GinWithValue(c, conf.VirtualHostKey, vhost)
31+
c.Next()
32+
}
33+
34+
// stripPort 去掉 host 中的端口号
35+
func stripPort(host string) string {
36+
if idx := strings.LastIndex(host, ":"); idx != -1 {
37+
// 确保不是 IPv6 地址(IPv6 地址用 [] 包裹)
38+
if !strings.Contains(host, "[") {
39+
return host[:idx]
40+
}
41+
}
42+
return host
43+
}

server/router.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ func Init(e *gin.Engine) {
3636
g.GET("/i/:link_name", handles.Plist)
3737
common.SecretKey = []byte(conf.Conf.JwtSecret)
3838
g.Use(middlewares.StoragesLoaded)
39+
g.Use(middlewares.VirtualHost)
3940
if conf.Conf.MaxConnections > 0 {
4041
g.Use(middlewares.MaxAllowed(conf.Conf.MaxConnections))
4142
}
@@ -122,6 +123,13 @@ func admin(g *gin.RouterGroup) {
122123
meta.POST("/update", handles.UpdateMeta)
123124
meta.POST("/delete", handles.DeleteMeta)
124125

126+
vhost := g.Group("/vhost")
127+
vhost.GET("/list", handles.ListVirtualHosts)
128+
vhost.GET("/get", handles.GetVirtualHost)
129+
vhost.POST("/create", handles.CreateVirtualHost)
130+
vhost.POST("/update", handles.UpdateVirtualHost)
131+
vhost.POST("/delete", handles.DeleteVirtualHost)
132+
125133
user := g.Group("/user")
126134
user.GET("/list", handles.ListUsers)
127135
user.GET("/get", handles.GetUser)

0 commit comments

Comments
 (0)