feat: refactor regex usage across multiple files and centralize patterns in a new utility (#10896)

This commit is contained in:
KOMATA 2025-11-11 16:14:09 +08:00 committed by GitHub
parent 51e98623c9
commit 02d22ba63f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 181 additions and 110 deletions

View file

@ -15,7 +15,6 @@ import (
"path"
"path/filepath"
"reflect"
"regexp"
"strconv"
"strings"
"time"
@ -40,6 +39,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/utils/files"
"github.com/1Panel-dev/1Panel/agent/utils/nginx"
"github.com/1Panel-dev/1Panel/agent/utils/nginx/parser"
"github.com/1Panel-dev/1Panel/agent/utils/re"
"github.com/1Panel-dev/1Panel/agent/utils/req_helper"
"github.com/1Panel-dev/1Panel/agent/utils/xpack"
"github.com/compose-spec/compose-go/v2/types"
@ -1820,8 +1820,7 @@ func getAppCommonConfig(envs map[string]interface{}) request.AppContainerConfig
config.CpuQuota = 0
}
if memLimit, ok := envs[constant.MemoryLimit]; ok {
re := regexp.MustCompile(`(\d+)([A-Za-z]+)`)
matches := re.FindStringSubmatch(memLimit.(string))
matches := re.GetRegex(re.NumberAlphaPattern).FindStringSubmatch(memLimit.(string))
if len(matches) == 3 {
num, err := strconv.ParseFloat(matches[1], 64)
if err == nil {

View file

@ -12,7 +12,6 @@ import (
"os"
"os/exec"
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"
@ -34,6 +33,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
"github.com/1Panel-dev/1Panel/agent/utils/common"
"github.com/1Panel-dev/1Panel/agent/utils/docker"
"github.com/1Panel-dev/1Panel/agent/utils/re"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/build"
"github.com/docker/docker/api/types/container"
@ -1166,7 +1166,7 @@ func (u *ContainerService) DownloadContainerLogs(containerType, container, since
errCh := make(chan error)
go func() {
scanner := bufio.NewScanner(stdout)
var ansiRegex = regexp.MustCompile(`\x1b\[[0-9;?]*[A-Za-z]|\x1b=|\x1b>`)
var ansiRegex = re.GetRegex(re.AnsiEscapePattern)
for scanner.Scan() {
line := scanner.Text()
cleanLine := ansiRegex.ReplaceAllString(line, "")

View file

@ -7,7 +7,6 @@ import (
"os"
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"
"time"
@ -24,6 +23,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/utils/compose"
"github.com/1Panel-dev/1Panel/agent/utils/encrypt"
"github.com/1Panel-dev/1Panel/agent/utils/mysql"
"github.com/1Panel-dev/1Panel/agent/utils/re"
"github.com/1Panel-dev/1Panel/agent/utils/mysql/client"
_ "github.com/go-sql-driver/mysql"
"github.com/jinzhu/copier"
@ -623,7 +623,7 @@ func updateMyCnf(oldFiles []string, group string, param string, value interface{
isOn := false
hasGroup := false
hasKey := false
regItem, _ := regexp.Compile(`\[*\]`)
regItem := re.GetRegex(re.MysqlGroupPattern)
var newFiles []string
i := 0
for _, line := range oldFiles {

View file

@ -3,15 +3,16 @@ package service
import (
"bufio"
"fmt"
"os"
"os/exec"
"strconv"
"strings"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/app/dto/response"
"github.com/1Panel-dev/1Panel/agent/buserr"
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
"os"
"os/exec"
"regexp"
"strconv"
"strings"
"github.com/1Panel-dev/1Panel/agent/utils/re"
)
func organizeDiskInfo(diskInfos []response.DiskBasicInfo) response.CompleteDiskInfo {
@ -205,12 +206,10 @@ func getDiskType(rota string) string {
return "Unknown"
}
var kvRe = regexp.MustCompile(`([A-Za-z0-9_]+)=("([^"\\]|\\.)*"|[^ \t]+)`)
func parseKeyValuePairs(line string) map[string]string {
fields := make(map[string]string)
matches := kvRe.FindAllStringSubmatch(line, -1)
matches := re.GetRegex(re.DiskKeyValuePattern).FindAllStringSubmatch(line, -1)
for _, m := range matches {
key := m[1]
raw := m[2]

View file

@ -5,7 +5,6 @@ import (
"math"
"os"
"path"
"regexp"
"strconv"
"strings"
"time"
@ -17,6 +16,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/constant"
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/files"
"github.com/1Panel-dev/1Panel/agent/utils/re"
"github.com/shirou/gopsutil/v4/disk"
)
@ -184,8 +184,7 @@ func createClashDir(clashDir string) error {
}
func getRecycleBinDTOFromName(filename string) (*response.RecycleBinDTO, error) {
r := regexp.MustCompile(`_1p_file_1p_(.+)_p_(\d+)_(\d+)`)
matches := r.FindStringSubmatch(filename)
matches := re.GetRegex(re.RecycleBinFilePattern).FindStringSubmatch(filename)
if len(matches) != 4 {
return nil, fmt.Errorf("invalid filename format")
}

View file

@ -35,6 +35,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/utils/docker"
"github.com/1Panel-dev/1Panel/agent/utils/env"
"github.com/1Panel-dev/1Panel/agent/utils/files"
"github.com/1Panel-dev/1Panel/agent/utils/re"
"github.com/pkg/errors"
"github.com/subosito/gotenv"
)
@ -244,8 +245,10 @@ func (r *RuntimeService) Page(req request.RuntimeSearch) (int64, []response.Runt
runtimeDTO.Params[k] = v
if strings.Contains(k, "CONTAINER_PORT") || strings.Contains(k, "HOST_PORT") {
if strings.Contains(k, "CONTAINER_PORT") {
r := regexp.MustCompile(`_(\d+)$`)
matches := r.FindStringSubmatch(k)
matches := re.GetRegex(re.TrailingDigitsPattern).FindStringSubmatch(k)
if len(matches) < 2 {
continue
}
containerPort, err := strconv.Atoi(v)
if err != nil {
continue
@ -829,7 +832,7 @@ func (r *RuntimeService) GetPHPConfig(id uint) (*response.PHPConfig, error) {
if strings.HasPrefix(line, ";") {
continue
}
matches := regexp.MustCompile(`^\s*([a-z_]+)\s*=\s*(.*)$`).FindStringSubmatch(line)
matches := re.GetRegex(re.PhpAssignmentPattern).FindStringSubmatch(line)
if len(matches) == 3 {
params[matches[1]] = matches[2]
}

View file

@ -12,7 +12,6 @@ import (
"os/exec"
"path"
"path/filepath"
"regexp"
"strconv"
"strings"
"time"
@ -34,6 +33,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/utils/compose"
"github.com/1Panel-dev/1Panel/agent/utils/docker"
"github.com/1Panel-dev/1Panel/agent/utils/files"
"github.com/1Panel-dev/1Panel/agent/utils/re"
"github.com/pkg/errors"
"github.com/subosito/gotenv"
"gopkg.in/yaml.v3"
@ -979,8 +979,10 @@ func handleRuntimeDTO(res *response.RuntimeDTO, runtime model.Runtime) error {
for k, v := range envs {
if strings.Contains(k, "CONTAINER_PORT") || strings.Contains(k, "HOST_PORT") {
if strings.Contains(k, "CONTAINER_PORT") {
r := regexp.MustCompile(`_(\d+)$`)
matches := r.FindStringSubmatch(k)
matches := re.GetRegex(re.TrailingDigitsPattern).FindStringSubmatch(k)
if len(matches) < 2 {
return fmt.Errorf("invalid container port key: %s", k)
}
containerPort, err := strconv.Atoi(v)
if err != nil {
return err

View file

@ -3,6 +3,15 @@ package service
import (
"errors"
"fmt"
"os"
"path"
"path/filepath"
"strconv"
"strings"
"github.com/subosito/gotenv"
"gopkg.in/yaml.v3"
"github.com/1Panel-dev/1Panel/agent/app/dto/request"
"github.com/1Panel-dev/1Panel/agent/app/dto/response"
"github.com/1Panel-dev/1Panel/agent/app/model"
@ -15,14 +24,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/utils/docker"
"github.com/1Panel-dev/1Panel/agent/utils/env"
"github.com/1Panel-dev/1Panel/agent/utils/files"
"github.com/subosito/gotenv"
"gopkg.in/yaml.v3"
"os"
"path"
"path/filepath"
"regexp"
"strconv"
"strings"
"github.com/1Panel-dev/1Panel/agent/utils/re"
)
type TensorRTLLMService struct{}
@ -61,8 +63,10 @@ func (t TensorRTLLMService) Page(req request.TensorRTLLMSearch) response.TensorR
for k, v := range envs {
if strings.Contains(k, "CONTAINER_PORT") || strings.Contains(k, "HOST_PORT") {
if strings.Contains(k, "CONTAINER_PORT") {
r := regexp.MustCompile(`_(\d+)$`)
matches := r.FindStringSubmatch(k)
matches := re.GetRegex(re.TrailingDigitsPattern).FindStringSubmatch(k)
if len(matches) < 2 {
continue
}
containerPort, err := strconv.Atoi(v)
if err != nil {
continue

View file

@ -14,7 +14,6 @@ import (
"os"
"path"
"reflect"
"regexp"
"sort"
"strconv"
"strings"
@ -46,6 +45,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/utils/nginx"
"github.com/1Panel-dev/1Panel/agent/utils/nginx/components"
"github.com/1Panel-dev/1Panel/agent/utils/nginx/parser"
"github.com/1Panel-dev/1Panel/agent/utils/re"
"golang.org/x/crypto/bcrypt"
)
@ -1859,27 +1859,24 @@ func (w WebsiteService) GetProxyCache(id uint) (res response.NginxProxyCache, er
if len(params) == 0 {
return
}
zoneRegexp := regexp.MustCompile(`keys_zone=proxy_cache_zone_of_[\w.]+:(\d+)([kmgt]?)`)
sizeRegexp := regexp.MustCompile(`max_size=([0-9.]+)([kmgt]?)`)
inactiveRegexp := regexp.MustCompile(`inactive=(\d+)([smhd])`)
for _, param := range params {
if match, _ := regexp.MatchString(`keys_zone=proxy_cache_zone_of_[\w.]+:\d+[kmgt]?`, param); match {
matches := zoneRegexp.FindStringSubmatch(param)
if re.GetRegex(re.ProxyCacheZonePattern).MatchString(param) {
matches := re.GetRegex(re.ProxyCacheZonePattern).FindStringSubmatch(param)
if len(matches) > 0 {
res.ShareCache, _ = strconv.Atoi(matches[1])
res.ShareCacheUnit = matches[2]
}
}
if match, _ := regexp.MatchString(`max_size=\d+(\.\d+)?[kmgt]?`, param); match {
matches := sizeRegexp.FindStringSubmatch(param)
if re.GetRegex(re.ProxyCacheMaxSizeValidationPattern).MatchString(param) {
matches := re.GetRegex(re.ProxyCacheMaxSizePattern).FindStringSubmatch(param)
if len(matches) > 0 {
res.CacheLimit, _ = strconv.ParseFloat(matches[1], 64)
res.CacheLimitUnit = matches[2]
}
}
if match, _ := regexp.MatchString(`inactive=\d+[smhd]`, param); match {
matches := inactiveRegexp.FindStringSubmatch(param)
if re.GetRegex(re.ProxyCacheInactivePattern).MatchString(param) {
matches := re.GetRegex(re.ProxyCacheInactivePattern).FindStringSubmatch(param)
if len(matches) > 0 {
res.CacheExpire, _ = strconv.Atoi(matches[1])
res.CacheExpireUnit = matches[2]
@ -2598,8 +2595,7 @@ func (w WebsiteService) GetAntiLeech(id uint) (*response.NginxAntiLeechRes, erro
}
if lDir.GetName() == "expires" {
res.Cache = true
re := regexp.MustCompile(`^(\d+)(\w+)$`)
matches := re.FindStringSubmatch(lDir.GetParameters()[0])
matches := re.GetRegex(re.NumberWordPattern).FindStringSubmatch(lDir.GetParameters()[0])
if matches == nil {
continue
}

View file

@ -9,7 +9,6 @@ import (
"os"
"path"
"path/filepath"
"regexp"
"strconv"
"strings"
"syscall"
@ -34,6 +33,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/utils/files"
"github.com/1Panel-dev/1Panel/agent/utils/nginx"
"github.com/1Panel-dev/1Panel/agent/utils/nginx/parser"
"github.com/1Panel-dev/1Panel/agent/utils/re"
"github.com/pkg/errors"
"gorm.io/gorm"
)
@ -1538,8 +1538,7 @@ func getServer(website model.Website) (*components.Server, error) {
func parseTimeString(input string) (int, string, error) {
input = strings.TrimSpace(input)
re := regexp.MustCompile(`^(\d+)([smhdw]?)$`)
matches := re.FindStringSubmatch(input)
matches := re.GetRegex(re.DurationWithOptionalUnitPattern).FindStringSubmatch(input)
if len(matches) < 2 {
return 0, "", fmt.Errorf("invalid time format: %s", input)

View file

@ -3,6 +3,7 @@ package firewall
import (
"github.com/1Panel-dev/1Panel/agent/utils/firewall"
"github.com/1Panel-dev/1Panel/agent/utils/firewall/client/iptables"
"github.com/1Panel-dev/1Panel/agent/utils/re"
)
func Init() {
@ -10,6 +11,8 @@ func Init() {
if err != nil {
return
}
re.RegisterRegex(iptables.Chian1PanelBasicPortPattern)
re.RegisterRegex(iptables.Chain1PanelBasicAddressPattern)
clientName := client.Name()
if clientName == "ufw" || clientName == "iptables" {
_ = iptables.LoadRulesFromFile(iptables.FilterTab, iptables.Chain1PanelForward, iptables.ForwardFileName)

View file

@ -1,10 +1,10 @@
package validator
import (
"regexp"
"unicode"
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/re"
"github.com/go-playground/validator/v10"
)
@ -25,20 +25,12 @@ func Init() {
func checkNamePattern(fl validator.FieldLevel) bool {
value := fl.Field().String()
result, err := regexp.MatchString("^[a-zA-Z\u4e00-\u9fa5]{1}[a-zA-Z0-9_\u4e00-\u9fa5]{0,30}$", value)
if err != nil {
global.LOG.Errorf("regexp matchString failed, %v", err)
}
return result
return re.GetRegex(re.ValidatorNamePattern).MatchString(value)
}
func checkIpPattern(fl validator.FieldLevel) bool {
value := fl.Field().String()
result, err := regexp.MatchString(`^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}$`, value)
if err != nil {
global.LOG.Errorf("regexp check ip matchString failed, %v", err)
}
return result
return re.GetRegex(re.ValidatorIPPattern).MatchString(value)
}
func checkPasswordPattern(fl validator.FieldLevel) bool {

View file

@ -29,9 +29,11 @@ import (
"github.com/1Panel-dev/1Panel/agent/init/validator"
"github.com/1Panel-dev/1Panel/agent/init/viper"
"github.com/1Panel-dev/1Panel/agent/utils/encrypt"
"github.com/1Panel-dev/1Panel/agent/utils/re"
)
func Start() {
re.Init()
viper.Init()
dir.Init()
log.Init()

View file

@ -4,6 +4,15 @@ import (
"encoding/json"
"errors"
"fmt"
"net/http"
"os"
"os/exec"
"strings"
"sync"
"time"
"github.com/jinzhu/copier"
"github.com/1Panel-dev/1Panel/agent/app/dto"
"github.com/1Panel-dev/1Panel/agent/app/model"
"github.com/1Panel-dev/1Panel/agent/app/repo"
@ -12,14 +21,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/i18n"
"github.com/1Panel-dev/1Panel/agent/utils/email"
"github.com/jinzhu/copier"
"net/http"
"os"
"os/exec"
"regexp"
"strings"
"sync"
"time"
"github.com/1Panel-dev/1Panel/agent/utils/re"
)
var cronJobAlertTypes = []string{"shell", "app", "website", "database", "directory", "log", "snapshot", "curl", "cutWebsiteLog", "clean", "ntp"}
@ -424,7 +426,7 @@ func FindRecentSuccessLoginNotInWhitelist(minutes int, whitelist []string) ([]st
whitelistMap[ip] = struct{}{}
}
ipRegex := regexp.MustCompile(`from\s+([0-9.]+)\s+port\s+(\d+)`)
ipRegex := re.GetRegex(re.AlertIPPattern)
for _, line := range lines {
line = strings.TrimSpace(line)

View file

@ -6,9 +6,10 @@ import (
"net/http"
"net/url"
"os"
"regexp"
cosSDK "github.com/tencentyun/cos-go-sdk-v5"
"github.com/1Panel-dev/1Panel/agent/utils/re"
)
type cosClient struct {
@ -30,8 +31,7 @@ func NewCosClient(vars map[string]interface{}) (*cosClient, error) {
endpointType := "cos"
if len(endpoint) != 0 {
re := regexp.MustCompile(`.*cos-dualstack\..*`)
if re.MatchString(endpoint) {
if re.GetRegex(re.CosDualStackPattern).MatchString(endpoint) {
endpointType = "cos-dualstack"
}
}

View file

@ -8,7 +8,6 @@ import (
"net"
"os/exec"
"reflect"
"regexp"
"sort"
"strconv"
"strings"
@ -19,6 +18,7 @@ import (
"github.com/1Panel-dev/1Panel/agent/buserr"
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
"github.com/1Panel-dev/1Panel/agent/utils/re"
"golang.org/x/net/idna"
)
@ -303,12 +303,7 @@ func LoadTimeZoneByCmd() string {
}
func IsValidDomain(domain string) bool {
pattern := `^([\w\p{Han}\-\*]{1,100}\.){1,10}([\w\p{Han}\-]{1,24}|[\w\p{Han}\-]{1,24}\.[\w\p{Han}\-]{1,24})(:\d{1,5})?$`
match, err := regexp.MatchString(pattern, domain)
if err != nil {
return false
}
return match
return re.GetRegex(re.DomainPattern).MatchString(domain)
}
func ContainsChinese(text string) bool {
@ -398,8 +393,7 @@ func HandleIPList(content string) ([]string, error) {
}
func GetSystemVersion(versionString string) string {
re := regexp.MustCompile(`v(\d+\.\d+\.\d+)`)
match := re.FindStringSubmatch(versionString)
match := re.GetRegex(re.VersionPattern).FindStringSubmatch(versionString)
if len(match) > 1 {
return match[1]
}

View file

@ -6,7 +6,6 @@ import (
"context"
"fmt"
"path"
"regexp"
"strings"
"github.com/compose-spec/compose-go/v2/loader"
@ -14,6 +13,8 @@ import (
"github.com/docker/compose/v2/pkg/api"
"github.com/joho/godotenv"
"gopkg.in/yaml.v3"
"github.com/1Panel-dev/1Panel/agent/utils/re"
)
type ComposeService struct {
@ -36,8 +37,7 @@ func GetComposeProject(projectName, workDir string, yml []byte, env []byte, skip
Environment: envMap,
}
projectName = strings.ToLower(projectName)
reg, _ := regexp.Compile(`[^a-z0-9_-]+`)
projectName = reg.ReplaceAllString(projectName, "")
projectName = re.GetRegex(re.ComposeDisallowedCharsPattern).ReplaceAllString(projectName, "")
project, err := loader.LoadWithContext(context.Background(), details, func(options *loader.Options) {
options.SetProjectName(projectName, true)
options.ResolvePaths = true
@ -141,9 +141,7 @@ func loadEnvFile(env []byte) (map[string]string, error) {
}
func replaceEnvVars(input string, envVars map[string]string) string {
re := regexp.MustCompile(`\$\{([^}]+)\}`)
return re.ReplaceAllStringFunc(input, func(match string) string {
return re.GetRegex(re.ComposeEnvVarPattern).ReplaceAllStringFunc(input, func(match string) string {
varName := match[2 : len(match)-1]
if value, exists := envVars[varName]; exists {
return value

View file

@ -2,7 +2,6 @@ package client
import (
"fmt"
"regexp"
"strings"
"sync"
@ -10,10 +9,9 @@ import (
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
"github.com/1Panel-dev/1Panel/agent/utils/controller"
"github.com/1Panel-dev/1Panel/agent/utils/re"
)
var ForwardListRegex = regexp.MustCompile(`^port=(\d{1,5}):proto=(.+?):toport=(\d{1,5}):toaddr=(.*)$`)
type Firewall struct{}
func NewFirewalld() (*Firewall, error) {
@ -124,8 +122,8 @@ func (f *Firewall) ListForward() ([]FireInfo, error) {
line = strings.TrimFunc(line, func(r rune) bool {
return r <= 32
})
if ForwardListRegex.MatchString(line) {
match := ForwardListRegex.FindStringSubmatch(line)
if re.GetRegex(re.FirewalldForwardPattern).MatchString(line) {
match := re.GetRegex(re.FirewalldForwardPattern).FindStringSubmatch(line)
if len(match) < 4 {
continue
}

View file

@ -2,7 +2,6 @@ package client
import (
"fmt"
"regexp"
"strconv"
"strings"
@ -10,11 +9,9 @@ import (
"github.com/1Panel-dev/1Panel/agent/global"
"github.com/1Panel-dev/1Panel/agent/utils/cmd"
"github.com/1Panel-dev/1Panel/agent/utils/firewall/client/iptables"
"github.com/1Panel-dev/1Panel/agent/utils/re"
)
var portRuleRegex = regexp.MustCompile(`-A\s+INPUT\s+-p\s+(\w+)(?:\s+-m\s+\w+)*\s+--dport\s+(\d+(?::\d+)?)\s+-j\s+(\w+)`)
var addressRuleRegex = regexp.MustCompile(`-A\s+(INPUT|OUTPUT)\s+-s\s+(\S+)\s+-j\s+(\w+)`)
type Iptables struct{}
func NewIptables() (*Iptables, error) {
@ -70,7 +67,7 @@ func (i *Iptables) ListPort() ([]FireInfo, error) {
var datas []FireInfo
lines := strings.Split(stdout, "\n")
chainPortRegex := regexp.MustCompile(fmt.Sprintf(`-A\s+%s\s+(?:-s\s+(\S+)\s+)?-p\s+(\w+)(?:\s+-m\s+\w+)*\s+--dport\s+(\d+(?::\d+)?)\s+-j\s+(\w+)`, iptables.Chain1PanelBasic))
chainPortRegex := re.GetRegex(iptables.Chian1PanelBasicPortPattern)
for _, line := range lines {
line = strings.TrimSpace(line)
if !strings.HasPrefix(line, fmt.Sprintf("-A %s", iptables.Chain1PanelBasic)) {
@ -111,8 +108,7 @@ func (i *Iptables) ListAddress() ([]FireInfo, error) {
lines := strings.Split(stdout, "\n")
addressMap := make(map[string]FireInfo)
chainAddressRegex := regexp.MustCompile(fmt.Sprintf(`-A\s+%s\s+(?:-s\s+(\S+)|(?:-d\s+(\S+)))?\s+-j\s+(\w+)`, iptables.Chain1PanelBasic))
chainAddressRegex := re.GetRegex(iptables.Chain1PanelBasicAddressPattern)
for _, line := range lines {
line = strings.TrimSpace(line)
if !strings.HasPrefix(line, fmt.Sprintf("-A %s", iptables.Chain1PanelBasic)) {

View file

@ -2,7 +2,6 @@ package iptables
import (
"fmt"
"regexp"
"strconv"
"strings"
"time"
@ -31,10 +30,6 @@ const (
AllowSSH = "-p tcp --dport ssh -j ACCEPT"
)
var (
natListRegex = regexp.MustCompile(`^(\d+)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)(?:\s+(.+?) .+?:(\d{1,5}(?::\d+)?).+?[ :](.+-.+|(?:.+:)?\d{1,5}(?:-\d{1,5})?))?$`)
)
const (
ACCEPT = "ACCEPT"
DROP = "DROP"
@ -47,6 +42,11 @@ const (
NatTab = "nat"
)
var (
Chain1PanelBasicAddressPattern = fmt.Sprintf(`-A\s+%s\s+(?:-s\s+(\S+)|(?:-d\s+(\S+)))?\s+-j\s+(\w+)`, Chain1PanelBasic)
Chian1PanelBasicPortPattern = fmt.Sprintf(`-A\s+%s\s+(?:-s\s+(\S+)\s+)?-p\s+(\w+)(?:\s+-m\s+\w+)*\s+--dport\s+(\d+(?::\d+)?)\s+-j\s+(\w+)`, Chain1PanelBasic)
)
func RunWithStd(tab, rule string) (string, error) {
cmdMgr := cmd.NewCommandMgr(cmd.WithIgnoreExist1(), cmd.WithTimeout(20*time.Second))
stdout, err := cmdMgr.RunWithStdoutBashCf("%s iptables -t %s %s", cmd.SudoHandleCmd(), tab, rule)

View file

@ -3,6 +3,8 @@ package iptables
import (
"fmt"
"strings"
"github.com/1Panel-dev/1Panel/agent/utils/re"
)
func AddForward(protocol, srcPort, dest, destPort, iface string, save bool) error {
@ -69,7 +71,7 @@ func ListForward(chain ...string) ([]IptablesNatInfo, error) {
if err != nil {
return nil, err
}
natListRegex := re.GetRegex(re.IptablesNatListPattern)
var forwardList []IptablesNatInfo
for _, line := range strings.Split(stdout, "\n") {
line = strings.TrimFunc(line, func(r rune) bool {

View file

@ -2,9 +2,10 @@ package components
import (
"fmt"
"regexp"
"strconv"
"strings"
"github.com/1Panel-dev/1Panel/agent/utils/re"
)
type Location struct {
@ -60,8 +61,7 @@ func NewLocation(directive IDirective) *Location {
dirs := dir.GetBlock().GetDirectives()
for _, di := range dirs {
if di.GetName() == "expires" {
re := regexp.MustCompile(`^(\d+)(\w+)$`)
matches := re.FindStringSubmatch(di.GetParameters()[0])
matches := re.GetRegex(re.NumberWordPattern).FindStringSubmatch(di.GetParameters()[0])
if matches == nil {
continue
}
@ -80,8 +80,7 @@ func NewLocation(directive IDirective) *Location {
}
case "proxy_cache_valid":
timeParam := params[len(params)-1]
re := regexp.MustCompile(`^(\d+)(\w+)$`)
matches := re.FindStringSubmatch(timeParam)
matches := re.GetRegex(re.NumberWordPattern).FindStringSubmatch(timeParam)
if matches == nil {
continue
}

84
agent/utils/re/re.go Normal file
View file

@ -0,0 +1,84 @@
package re
import (
"fmt"
"regexp"
)
const (
NumberAlphaPattern = `(\d+)([A-Za-z]+)`
ComposeDisallowedCharsPattern = `[^a-z0-9_-]+`
ComposeEnvVarPattern = `\$\{([^}]+)\}`
DiskKeyValuePattern = `([A-Za-z0-9_]+)=("([^"\\]|\\.)*"|[^ \t]+)`
FirewalldForwardPattern = `^port=(\d{1,5}):proto=(.+?):toport=(\d{1,5}):toaddr=(.*)$`
IptablesNatListPattern = `^(\d+)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)\s+(.+?)(?:\s+(.+?) .+?:(\d{1,5}(?::\d+)?).+?[ :](.+-.+|(?:.+:)?\d{1,5}(?:-\d{1,5})?))?$`
ValidatorNamePattern = `^[a-zA-Z\p{Han}]{1}[a-zA-Z0-9_\p{Han}]{0,30}$`
ValidatorIPPattern = `^((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}$`
DomainPattern = `^([\w\p{Han}\-\*]{1,100}\.){1,10}([\w\p{Han}\-]{1,24}|[\w\p{Han}\-]{1,24}\.[\w\p{Han}\-]{1,24})(:\d{1,5})?$`
ProxyCacheZonePattern = `keys_zone=proxy_cache_zone_of_[\w.]+:(\d+)([kmgt]?)`
ProxyCacheMaxSizePattern = `max_size=([0-9.]+)([kmgt]?)`
ProxyCacheMaxSizeValidationPattern = `max_size=\d+(\.\d+)?[kmgt]?`
ProxyCacheInactivePattern = `inactive=(\d+)([smhd])`
NumberWordPattern = `^(\d+)(\w+)$`
TrailingDigitsPattern = `_(\d+)$`
AlertIPPattern = `from\s+([0-9.]+)\s+port\s+(\d+)`
CosDualStackPattern = `.*cos-dualstack\..*`
VersionPattern = `v(\d+\.\d+\.\d+)`
PhpAssignmentPattern = `^\s*([a-z_]+)\s*=\s*(.*)$`
DurationWithOptionalUnitPattern = `^(\d+)([smhdw]?)$`
MysqlGroupPattern = `\[*\]`
AnsiEscapePattern = "\x1b\\[[0-9;?]*[A-Za-z]|\x1b=|\x1b>"
RecycleBinFilePattern = `_1p_file_1p_(.+)_p_(\d+)_(\d+)`
)
var regexMap = make(map[string]*regexp.Regexp)
// InitRegex compiles all regex patterns and stores them in the map.
// This function should be called once at program startup.
func Init() {
patterns := []string{
NumberAlphaPattern,
ComposeDisallowedCharsPattern,
ComposeEnvVarPattern,
DiskKeyValuePattern,
FirewalldForwardPattern,
IptablesNatListPattern,
ValidatorNamePattern,
ValidatorIPPattern,
DomainPattern,
ProxyCacheZonePattern,
ProxyCacheMaxSizePattern,
ProxyCacheMaxSizeValidationPattern,
ProxyCacheInactivePattern,
NumberWordPattern,
TrailingDigitsPattern,
AlertIPPattern,
CosDualStackPattern,
VersionPattern,
PhpAssignmentPattern,
DurationWithOptionalUnitPattern,
MysqlGroupPattern,
AnsiEscapePattern,
RecycleBinFilePattern,
}
for _, pattern := range patterns {
regexMap[pattern] = regexp.MustCompile(pattern)
}
}
// GetRegex retrieves a compiled regex by its pattern string.
// Panics if the pattern is not found in the map.
func GetRegex(pattern string) *regexp.Regexp {
regex, exists := regexMap[pattern]
if !exists {
panic(fmt.Sprintf("regex pattern not found: %s", pattern))
}
return regex
}
// RegisterRegex registers a regex pattern and stores it in the map.
// This function should be called once at program startup.
func RegisterRegex(pattern string) {
regexMap[pattern] = regexp.MustCompile(pattern)
}