Skip to content

Commit 051dd4c

Browse files
committed
书籍所有人可以直链播放音频和视频
1 parent 860070c commit 051dd4c

File tree

2 files changed

+106
-11
lines changed

2 files changed

+106
-11
lines changed

conf/enumerate.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,20 +68,20 @@ var (
6868
)
6969

7070
var (
71-
audioExt sync.Map
72-
videoExt sync.Map
71+
AudioExt sync.Map
72+
VideoExt sync.Map
7373
)
7474

7575
// 初始化支持的音视频格式
7676
func init() {
7777
// 音频格式
7878
for _, ext := range []string{".flac", ".wma", ".weba", ".aac", ".oga", ".ogg", ".mp3", ".webm", ".mid", ".wav", ".opus", ".m4a", ".amr", ".aiff", ".au"} {
79-
audioExt.Store(ext, true)
79+
AudioExt.Store(ext, true)
8080
}
8181

8282
// 视频格式
8383
for _, ext := range []string{".ogm", ".wmv", ".asx", ".mpg", ".webm", ".mp4", ".ogv", ".mpeg", ".mov", ".m4v", ".avi"} {
84-
videoExt.Store(ext, true)
84+
VideoExt.Store(ext, true)
8585
}
8686
}
8787

@@ -132,10 +132,10 @@ func IsAllowUploadFileExt(ext string, typ ...string) bool {
132132
if len(typ) > 0 {
133133
t := strings.ToLower(strings.TrimSpace(typ[0]))
134134
if t == "audio" {
135-
_, ok := audioExt.Load(ext)
135+
_, ok := AudioExt.Load(ext)
136136
return ok
137137
} else if t == "video" {
138-
_, ok := videoExt.Load(ext)
138+
_, ok := VideoExt.Load(ext)
139139
return ok
140140
}
141141
}

controllers/StaticController.go

Lines changed: 100 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@ package controllers
33
import (
44
"fmt"
55
"net/http"
6+
"net/url"
67
"path/filepath"
78
"strings"
89

10+
"github.com/TruthHun/BookStack/conf"
911
"github.com/TruthHun/BookStack/models"
12+
"github.com/TruthHun/BookStack/models/store"
1013

1114
"github.com/TruthHun/BookStack/utils"
1215
"github.com/astaxie/beego"
@@ -39,7 +42,7 @@ func (this *StaticController) Uploads() {
3942
http.ServeFile(this.Ctx.ResponseWriter, this.Ctx.Request, path)
4043
}
4144

42-
//静态文件,这个加在路由的最后
45+
// 静态文件,这个加在路由的最后
4346
func (this *StaticController) StaticFile() {
4447
file := this.GetString(":splat")
4548
if strings.HasPrefix(file, ".well-known") || file == "sitemap.xml" {
@@ -51,12 +54,104 @@ func (this *StaticController) StaticFile() {
5154
http.ServeFile(this.Ctx.ResponseWriter, this.Ctx.Request, path)
5255
}
5356

54-
// 书籍静态文件
57+
// ProjectsFile 书籍静态文件
5558
func (this *StaticController) ProjectsFile() {
59+
if utils.StoreType != utils.StoreOss {
60+
this.Abort("404")
61+
}
62+
5663
object := filepath.Join("projects/", strings.TrimLeft(this.GetString(":splat"), "./"))
57-
if utils.StoreType == utils.StoreOss { //oss
64+
object = strings.ReplaceAll(object, "\\", "/")
65+
// 不是音频和视频,直接跳转
66+
if !this.isMedia(object) {
5867
this.Redirect(this.OssDomain+"/"+object, 302)
59-
} else { //local
60-
this.Abort("404")
68+
return
69+
}
70+
71+
// query := this.Ctx.Request.URL.Query()
72+
// 签名验证
73+
sign := this.GetString("sign")
74+
if !this.isValidSign(sign) {
75+
// 签名验证不通过,需要再次验证书籍是否是用户的(针对编辑状态)
76+
if !this.isBookOwner() {
77+
this.Abort("404")
78+
return
79+
}
80+
}
81+
82+
var expireInSec int64 = 2
83+
if bucket, err := store.ModelStoreOss.GetBucket(); err == nil {
84+
object, _ = bucket.SignURL(object, http.MethodGet, expireInSec)
85+
if slice := strings.Split(object, "/"); len(slice) > 2 {
86+
object = strings.Join(slice[3:], "/")
87+
}
88+
}
89+
this.Redirect(this.OssDomain+"/"+object, 302)
90+
}
91+
92+
// 是否是音视频
93+
func (this *StaticController) isMedia(path string) (yes bool) {
94+
var videoOK, audioOK bool
95+
ext := strings.ToLower(filepath.Ext(path))
96+
_, videoOK = conf.VideoExt.Load(ext)
97+
_, audioOK = conf.VideoExt.Load(ext)
98+
return audioOK || videoOK
99+
}
100+
101+
// 是否是书籍项目所有人(书籍项目所有人,可以直链播放音视频)
102+
func (this *StaticController) isBookOwner() (yes bool) {
103+
memberID := 0
104+
// 从session中获取用户信息
105+
if member, ok := this.GetSession(conf.LoginSessionName).(models.Member); ok {
106+
memberID = member.MemberId
107+
}
108+
109+
if memberID <= 0 {
110+
// 如果Cookie中存在登录信息,从cookie中获取用户信息
111+
if cookie, ok := this.GetSecureCookie(conf.GetAppKey(), "login"); ok {
112+
var remember CookieRemember
113+
if err := utils.Decode(cookie, &remember); err == nil {
114+
memberID = remember.MemberId
115+
}
116+
}
117+
}
118+
if memberID <= 0 {
119+
return
61120
}
121+
122+
referer := this.Ctx.Request.Referer()
123+
if referer == "" {
124+
return
125+
}
126+
127+
bookIdentify := ""
128+
if u, err := url.Parse(referer); err == nil {
129+
fmt.Println(u.Path)
130+
if slice := strings.Split(u.Path, "/"); len(slice) >= 3 && slice[1] == "api" {
131+
bookIdentify = slice[2]
132+
}
133+
}
134+
135+
if bookIdentify == "" {
136+
return
137+
}
138+
139+
bookID := 0
140+
if book, err := models.NewBook().FindByIdentify(bookIdentify, "book_id"); err == nil {
141+
bookID = book.BookId
142+
}
143+
if bookID <= 0 {
144+
return
145+
}
146+
147+
if r, err := models.NewRelationship().FindByBookIdAndMemberId(bookID, memberID); err == nil && r.RelationshipId > 0 {
148+
return true
149+
}
150+
151+
return false
152+
}
153+
154+
// 是否是合法的签名(针对音频和视频,签名不可用的时候再验证用户有没有登录,用户登录了再验证用户是不是书籍所有人)
155+
func (this *StaticController) isValidSign(sign string) bool {
156+
return false
62157
}

0 commit comments

Comments
 (0)