From cc13053f340435841108b6ec08736691ad92c8e2 Mon Sep 17 00:00:00 2001 From: GoEdgeLab Date: Wed, 17 Apr 2024 14:46:30 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BE=8B=E5=A4=96=E5=92=8C=E9=99=90=E5=88=B6UR?= =?UTF-8?q?L=E4=B8=AD=E5=A2=9E=E5=8A=A0=E5=B8=B8=E8=A7=81=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E3=80=81=E5=B8=B8=E8=A7=81=E9=9F=B3=E9=A2=91=E3=80=81?= =?UTF-8?q?=E5=B8=B8=E8=A7=81=E8=A7=86=E9=A2=91=E7=AD=89=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/serverconfigs/shared/url_pattern.go | 93 ++++++++++++++------ pkg/serverconfigs/shared/url_pattern_test.go | 40 +++++++++ 2 files changed, 106 insertions(+), 27 deletions(-) diff --git a/pkg/serverconfigs/shared/url_pattern.go b/pkg/serverconfigs/shared/url_pattern.go index 7d6854b..d7aa7b0 100644 --- a/pkg/serverconfigs/shared/url_pattern.go +++ b/pkg/serverconfigs/shared/url_pattern.go @@ -4,6 +4,7 @@ package shared import ( "fmt" + "path/filepath" "regexp" "strings" ) @@ -13,8 +14,15 @@ type URLPatternType = string const ( URLPatternTypeWildcard URLPatternType = "wildcard" // 通配符 URLPatternTypeRegexp URLPatternType = "regexp" // 正则表达式 + URLPatternTypeImages URLPatternType = "images" // 常见图片 + URLPatternTypeAudios URLPatternType = "audios" // 常见音频 + URLPatternTypeVideos URLPatternType = "videos" // 常见视频 ) +var commonImageExtensions = []string{".apng", ".avif", ".gif", ".jpg", ".jpeg", ".jfif", ".pjpeg", ".pjp", ".png", ".svg", ".webp", ".bmp", ".ico", ".cur", ".tif", ".tiff"} +var commonAudioExtensions = []string{".mp3", ".flac", ".wav", ".aac", ".ogg", ".m4a", ".wma", ".m3u8"} // m3u8 is special +var commonVideoExtensions = []string{".mp4", ".avi", ".mkv", ".mov", ".wmv", ".mpeg", ".3gp", ".webm", ".ts", ".m3u8"} + type URLPattern struct { Type URLPatternType `yaml:"type" json:"type"` Pattern string `yaml:"pattern" json:"pattern"` @@ -23,36 +31,36 @@ type URLPattern struct { } func (this *URLPattern) Init() error { - if len(this.Pattern) == 0 { - return nil - } - switch this.Type { case URLPatternTypeWildcard: - // 只支持星号 - var pieces = strings.Split(this.Pattern, "*") - for index, piece := range pieces { - pieces[index] = regexp.QuoteMeta(piece) + if len(this.Pattern) > 0 { + // 只支持星号 + var pieces = strings.Split(this.Pattern, "*") + for index, piece := range pieces { + pieces[index] = regexp.QuoteMeta(piece) + } + var pattern = strings.Join(pieces, "(.*)") + if len(pattern) > 0 && pattern[0] == '/' { + pattern = "(http|https)://[\\w.-]+" + pattern + } + reg, err := regexp.Compile("(?i)" /** 大小写不敏感 **/ + "^" + pattern + "$") + if err != nil { + return err + } + this.reg = reg } - var pattern = strings.Join(pieces, "(.*)") - if len(pattern) > 0 && pattern[0] == '/' { - pattern = "(http|https)://[\\w.-]+" + pattern - } - reg, err := regexp.Compile("(?i)" /** 大小写不敏感 **/ + "^" + pattern + "$") - if err != nil { - return err - } - this.reg = reg case URLPatternTypeRegexp: - var pattern = this.Pattern - if !strings.HasPrefix(pattern, "(?i)") { // 大小写不敏感 - pattern = "(?i)" + pattern + if len(this.Pattern) > 0 { + var pattern = this.Pattern + if !strings.HasPrefix(pattern, "(?i)") { // 大小写不敏感 + pattern = "(?i)" + pattern + } + reg, err := regexp.Compile(pattern) + if err != nil { + return fmt.Errorf("compile '%s' failed: %w", pattern, err) + } + this.reg = reg } - reg, err := regexp.Compile(pattern) - if err != nil { - return fmt.Errorf("compile '%s' failed: %w", pattern, err) - } - this.reg = reg } return nil @@ -63,8 +71,39 @@ func (this *URLPattern) Match(url string) bool { return true } - if this.reg != nil { - return this.reg.MatchString(url) + switch this.Type { + case URLPatternTypeImages: + var urlExt = strings.ToLower(filepath.Ext(url)) + if len(urlExt) > 0 { + for _, ext := range commonImageExtensions { + if ext == urlExt { + return true + } + } + } + case URLPatternTypeAudios: + var urlExt = strings.ToLower(filepath.Ext(url)) + if len(urlExt) > 0 { + for _, ext := range commonAudioExtensions { + if ext == urlExt { + return true + } + } + } + case URLPatternTypeVideos: + var urlExt = strings.ToLower(filepath.Ext(url)) + if len(urlExt) > 0 { + for _, ext := range commonVideoExtensions { + if ext == urlExt { + return true + } + } + } + default: + if this.reg != nil { + return this.reg.MatchString(url) + } } + return false } diff --git a/pkg/serverconfigs/shared/url_pattern_test.go b/pkg/serverconfigs/shared/url_pattern_test.go index ce66a42..1b98776 100644 --- a/pkg/serverconfigs/shared/url_pattern_test.go +++ b/pkg/serverconfigs/shared/url_pattern_test.go @@ -118,6 +118,46 @@ func TestURLPattern_Match(t *testing.T) { url: "https://example.com/123456/789", result: false, }, + { + patternType: "images", + url: "https://example.com/images/logo.png", + result: true, + }, + { + patternType: "images", + url: "https://example.com/images/logo.webp", + result: true, + }, + { + patternType: "images", + url: "https://example.com/images/logo.mp3", + result: false, + }, + { + patternType: "audios", + url: "https://example.com/audios/music.mp3", + result: true, + }, + { + patternType: "audios", + url: "https://example.com/audios/music.mm", + result: false, + }, + { + patternType: "videos", + url: "https://example.com/images/movie.mp4", + result: true, + }, + { + patternType: "videos", + url: "https://example.com/images/movie.ts", + result: true, + }, + { + patternType: "videos", + url: "https://example.com/images/movie.mp5", + result: false, + }, } { var p = &shared.URLPattern{ Type: ut.patternType,