Compare commits

...

37 Commits

Author SHA1 Message Date
9b7aab1fc7 chore: rename delete.yml 2023-03-30 16:04:09 +00:00
3c717097cb Merge branch 'Alpha' into Meta 2023-03-30 16:03:47 +00:00
991de009be chore: update readme 2023-03-30 15:57:52 +00:00
2fef329319 fix: upgrade backup 2023-03-29 13:59:36 +00:00
db7623968d fix: inner http use host of address 2023-03-29 20:50:46 +08:00
7c80c88feb chore: push latest alpha core to MetaCubeX/AlphaBinary 2023-03-29 12:28:16 +00:00
2c7153cd7a chore: clean up code 2023-03-29 16:19:26 +08:00
d730feecb4 chore: use inner for upgrade core 2023-03-29 06:03:13 +00:00
8293b7fdae Merge branch 'Beta' into Meta
# Conflicts:
#	.github/workflows/docker.yaml
#	.github/workflows/prerelease.yml
2023-02-19 01:25:34 +08:00
0ba415866e Merge branch 'Alpha' into Beta 2023-02-19 01:25:01 +08:00
53b41ca166 Chore: Add action for deleting old workflow 2023-01-30 18:17:22 +08:00
8a75f78e63 chore: adjust Dockerfile 2023-01-12 02:24:12 +08:00
d9692c6366 Merge branch 'Beta' into Meta 2023-01-12 02:15:14 +08:00
f4b0062dfc Merge branch 'Alpha' into Beta 2023-01-12 02:14:49 +08:00
b9ffc82e53 Merge branch 'Beta' into Meta 2023-01-12 01:33:56 +08:00
78aaea6a45 Merge branch 'Alpha' into Beta 2023-01-12 01:33:16 +08:00
3645fbf161 Merge pull request #327 from Rasphino/Meta
Update flake.nix hash
2023-01-08 00:29:29 +08:00
a1d0f22132 fix: update flake.nix hash 2023-01-07 23:38:32 +08:00
fa73b0f4bf Merge remote-tracking branch 'origin/Beta' into Meta 2023-01-01 19:41:36 +08:00
3b76a8b839 Merge remote-tracking branch 'origin/Alpha' into Beta 2023-01-01 19:40:36 +08:00
667f42dcdc Merge pull request #282 from tdjnodj/Meta
Update README.md
2022-12-03 17:23:51 +08:00
dfbe09860f Update README.md 2022-12-03 17:17:08 +08:00
9e20f9c26a chore: update dependencies 2022-11-28 20:33:10 +08:00
f968d0cb82 chore: update github action 2022-11-26 20:16:12 +08:00
2ad84f4379 Merge branch 'Beta' into Meta 2022-11-02 18:08:22 +08:00
c7aa16426f Merge branch 'Alpha' into Beta 2022-11-02 18:07:29 +08:00
5987f8e3b5 Merge branch 'Beta' into Meta 2022-08-29 13:08:29 +08:00
3a8eb72de2 Merge branch 'Alpha' into Beta 2022-08-29 13:08:22 +08:00
33abbdfd24 Merge pull request #174 from MetaCubeX/Alpha
Alpha
2022-08-29 11:24:07 +08:00
0703d6cbff Merge pull request #173 from MetaCubeX/Alpha
Alpha
2022-08-29 11:22:14 +08:00
10d2d14938 Merge branch 'Beta' into Meta
# Conflicts:
#	rules/provider/classical_strategy.go
2022-07-02 10:41:41 +08:00
691cf1d8d6 Merge pull request #94 from bash99/Meta
Update README.md
2022-06-15 19:15:51 +08:00
d1decb8e58 Update README.md
add permissions for systemctl services
clash-dashboard change to updated one
2022-06-15 14:00:05 +08:00
7d04904109 fix: leak dns when domain in hosts list 2022-06-11 18:51:26 +08:00
a5acd3aa97 refactor: clear linkname,reduce cycle dependencies,transport init geosite function 2022-06-11 18:51:22 +08:00
eea9a12560 fix: 规则匹配默认策略组返回错误 2022-06-09 14:18:35 +08:00
0a4570b55c fix: group filter touch provider 2022-06-09 14:18:29 +08:00
10 changed files with 100 additions and 107 deletions

16
.github/workflows/Delete.yml vendored Normal file
View File

@ -0,0 +1,16 @@
name: Delete old workflow runs
on:
schedule:
- cron: '0 0 1 * *'
# Run monthly, at 00:00 on the 1st day of month.
jobs:
del_runs:
runs-on: ubuntu-latest
steps:
- name: Delete workflow runs
uses: GitRML/delete-workflow-runs@main
with:
token: ${{ secrets.AUTH_PAT }}
repository: ${{ github.repository }}
retain_days: 30

View File

@ -268,18 +268,6 @@ jobs:
generate_release_notes: true
body_path: release.txt
- name: Git push assets to "release" branch
run: |
cd bin || exit 1
git init
git config --local user.name "github-actions[bot]"
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
git checkout -b release
git add .
git commit -m "${{ env.BUILDTIME }}"
git remote add origin "https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}"
git push -f -u origin release
Upload-Release:
permissions: write-all
if: ${{ github.ref_type=='tag' }}

16
.github/workflows/delete.yml vendored Normal file
View File

@ -0,0 +1,16 @@
name: Delete old workflow runs
on:
schedule:
- cron: '0 0 1 * *'
# Run monthly, at 00:00 on the 1st day of month.
jobs:
del_runs:
runs-on: ubuntu-latest
steps:
- name: Delete workflow runs
uses: GitRML/delete-workflow-runs@main
with:
token: ${{ secrets.AUTH_PAT }}
repository: ${{ github.repository }}
retain_days: 30

View File

@ -30,8 +30,7 @@
- Comprehensive HTTP RESTful API controller
## Wiki
Documentation and configuring examples are available on [Clash.Meta Wiki](https://clash-meta.wiki).
Configuration examples can be found at [/docs/config.yaml](https://github.com/MetaCubeX/Clash.Meta/blob/Alpha/docs/config.yaml), while documentation can be found [Clash.Meta Wiki](https://clash-meta.wiki).
## Build

View File

@ -42,6 +42,8 @@ func NewInner(conn net.Conn, dst string, host string) *context.ConnContext {
if host == "" {
if ip, err := netip.ParseAddr(h); err == nil {
metadata.DstIP = ip
} else {
metadata.Host = h
}
}
}

View File

@ -53,7 +53,7 @@ func HttpRequest(ctx context.Context, url, method string, header map[string][]st
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
DialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
conn := inner.HandleTcp(address, urlRes.Hostname())
conn := inner.HandleTcp(address, "")
return conn, nil
},
TLSClientConfig: tls.GetDefaultTLSConfig(),

View File

@ -66,7 +66,7 @@ func (p *path) MMDB() string {
// 目录则直接跳过
continue
} else {
if strings.EqualFold(strings.ToLower(fi.Name()), "country.mmdb") {
if strings.EqualFold(fi.Name(), "Country.mmdb") {
GeoipName = fi.Name()
return P.Join(p.homeDir, fi.Name())
}
@ -93,7 +93,7 @@ func (p *path) GeoIP() string {
// 目录则直接跳过
continue
} else {
if strings.EqualFold(strings.ToLower(fi.Name()), "geoip.dat") {
if strings.EqualFold(fi.Name(), "GeoIP.dat") {
GeoipName = fi.Name()
return P.Join(p.homeDir, fi.Name())
}
@ -112,7 +112,7 @@ func (p *path) GeoSite() string {
// 目录则直接跳过
continue
} else {
if strings.EqualFold(strings.ToLower(fi.Name()), "geosite.dat") {
if strings.EqualFold(fi.Name(), "GeoSite.dat") {
GeositeName = fi.Name()
return P.Join(p.homeDir, fi.Name())
}

View File

@ -47,7 +47,7 @@ func restart(w http.ResponseWriter, r *http.Request) {
cmd.Stderr = os.Stderr
err = cmd.Start()
if err != nil {
log.Fatalln("restarting:: %s", err)
log.Fatalln("restarting: %s", err)
}
os.Exit(0)

View File

@ -1,18 +1,12 @@
package route
import (
"fmt"
"net/http"
"os"
"os/exec"
"runtime"
"syscall"
"github.com/Dreamacro/clash/hub/updater"
"github.com/Dreamacro/clash/log"
"github.com/go-chi/chi/v5"
"github.com/go-chi/render"
)
func upgradeRouter() http.Handler {
@ -30,41 +24,5 @@ func upgrade(w http.ResponseWriter, r *http.Request) {
return
}
execPath, err := os.Executable()
if err != nil {
render.Status(r, http.StatusInternalServerError)
render.JSON(w, r, newError(fmt.Sprintf("getting path: %s", err)))
return
}
render.JSON(w, r, render.M{"status": "ok"})
if f, ok := w.(http.Flusher); ok {
f.Flush()
}
// modify from https://github.com/AdguardTeam/AdGuardHome/blob/595484e0b3fb4c457f9bb727a6b94faa78a66c5f/internal/home/controlupdate.go#L180
// The background context is used because the underlying functions wrap it
// with timeout and shut down the server, which handles current request. It
// also should be done in a separate goroutine for the same reason.
go func() {
if runtime.GOOS == "windows" {
cmd := exec.Command(execPath, os.Args[1:]...)
log.Infoln("restarting: %q %q", execPath, os.Args[1:])
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Start()
if err != nil {
log.Fatalln("restarting: %s", err)
}
os.Exit(0)
}
log.Infoln("restarting: %q %q", execPath, os.Args[1:])
err = syscall.Exec(execPath, os.Args, os.Environ())
if err != nil {
log.Fatalln("restarting: %s", err)
}
}()
restart(w, r)
}

View File

@ -3,6 +3,7 @@ package updater
import (
"archive/zip"
"compress/gzip"
"context"
"fmt"
"io"
"net/http"
@ -11,7 +12,9 @@ import (
"runtime"
"strings"
"sync"
"time"
clashHttp "github.com/Dreamacro/clash/component/http"
"github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/log"
)
@ -19,30 +22,24 @@ import (
// modify from https://github.com/AdguardTeam/AdGuardHome/blob/595484e0b3fb4c457f9bb727a6b94faa78a66c5f/internal/updater/updater.go
// Updater is the Clash.Meta updater.
var (
client http.Client
goarch string
goos string
goarm string
gomips string
workDir string
versionCheckURL string
workDir string
// mu protects all fields below.
mu sync.RWMutex
// TODO(a.garipov): See if all of these fields actually have to be in
// this struct.
currentExeName string // 当前可执行文件
updateDir string // 更新目录
packageName string // 更新压缩文件
backupDir string // 备份目录
backupExeName string // 备份文件名
updateExeName string // 更新后的可执行文件
unpackedFile string
baseURL string = "https://ghproxy.com/https://github.com/MetaCubeX/Clash.Meta/releases/download/Prerelease-Alpha/clash.meta"
baseURL string = "https://github.com/MetaCubeX/Clash.Meta/releases/download/Prerelease-Alpha/clash.meta"
versionURL string = "https://github.com/MetaCubeX/Clash.Meta/releases/download/Prerelease-Alpha/version.txt"
packageURL string
latestVersion string
@ -59,9 +56,18 @@ func (e *updateError) Error() string {
// Update performs the auto-updater. It returns an error if the updater failed.
// If firstRun is true, it assumes the configuration file doesn't exist.
func Update() (err error) {
mu.Lock()
defer mu.Unlock()
goos = runtime.GOOS
goarch = runtime.GOARCH
latestVersion = getLatestVersion()
latestVersion, err = getLatestVersion()
if err != nil {
err := &updateError{Message: err.Error()}
return err
}
log.Infoln("current version alpha-%s, latest version alpha-%s", constant.Version, latestVersion)
if latestVersion == constant.Version {
err := &updateError{Message: "Already using latest version"}
@ -69,10 +75,6 @@ func Update() (err error) {
}
updateDownloadURL()
mu.Lock()
defer mu.Unlock()
log.Infoln("current version alpha-%s", constant.Version)
defer func() {
if err != nil {
@ -88,7 +90,6 @@ func Update() (err error) {
}
workDir = filepath.Dir(execPath)
//log.Infoln("workDir %s", execPath)
err = prepare(execPath)
if err != nil {
@ -107,6 +108,11 @@ func Update() (err error) {
return fmt.Errorf("unpacking: %w", err)
}
err = backup()
if err != nil {
return fmt.Errorf("replacing: %w", err)
}
err = replace()
if err != nil {
return fmt.Errorf("replacing: %w", err)
@ -115,14 +121,6 @@ func Update() (err error) {
return nil
}
// VersionCheckURL returns the version check URL.
func VersionCheckURL() (vcu string) {
mu.RLock()
defer mu.RUnlock()
return versionCheckURL
}
// prepare fills all necessary fields in Updater object.
func prepare(exePath string) (err error) {
updateDir = filepath.Join(workDir, "meta-update")
@ -142,7 +140,7 @@ func prepare(exePath string) (err error) {
updateExeName = "clash.meta" + "-" + goos + "-" + goarch
}
log.Infoln("updateExeName: %s ,currentExeName: %s", updateExeName, currentExeName)
log.Infoln("updateExeName: %s ", updateExeName)
backupExeName = filepath.Join(backupDir, filepath.Base(exePath))
updateExeName = filepath.Join(updateDir, updateExeName)
@ -168,13 +166,13 @@ func unpack() error {
log.Debugln("updater: unpacking package")
if strings.HasSuffix(pkgNameOnly, ".zip") {
unpackedFile, err = zipFileUnpack(packageName, updateDir)
_, err = zipFileUnpack(packageName, updateDir)
if err != nil {
return fmt.Errorf(".zip unpack failed: %w", err)
}
} else if strings.HasSuffix(pkgNameOnly, ".gz") {
unpackedFile, err = gzFileUnpack(packageName, updateDir)
_, err = gzFileUnpack(packageName, updateDir)
if err != nil {
return fmt.Errorf(".gz unpack failed: %w", err)
}
@ -186,25 +184,37 @@ func unpack() error {
return nil
}
// backup makes a backup of the current configuration and supporting files. It
// ignores the configuration file if firstRun is true.
func backup() (err error) {
log.Infoln("updater: backing up current Exefile")
_ = os.Mkdir(backupDir, 0o755)
err = copyFile(currentExeName, backupExeName)
if err != nil {
return fmt.Errorf("copySupportingFiles(%s, %s) failed: %w", currentExeName, backupExeName, err)
}
return nil
}
// replace moves the current executable with the updated one and also copies the
// supporting files.
func replace() error {
//err := copySupportingFiles(unpackedFiles, updateDir, workDir)
//if err != nil {
// return fmt.Errorf("copySupportingFiles(%s, %s) failed: %w", updateDir, workDir, err)
//}
var err error
log.Infoln("updater: renaming: %s to %s", currentExeName, backupExeName)
err := os.Rename(currentExeName, backupExeName)
if err != nil {
return err
}
// log.Infoln("updater: renaming: %s to %s", currentExeName, backupExeName)
// err := os.Rename(currentExeName, backupExeName)
// if err != nil {
// return err
// }
if goos == "windows" {
// rename fails with "File in use" error
log.Infoln("copying:%s to %s", updateExeName, currentExeName)
log.Infoln("copying: %s to %s", updateExeName, currentExeName)
err = copyFile(updateExeName, currentExeName)
} else {
log.Infoln("copying: %s to %s", updateExeName, currentExeName)
err = os.Rename(updateExeName, currentExeName)
}
if err != nil {
@ -226,8 +236,11 @@ const MaxPackageFileSize = 32 * 1024 * 1024
// Download package file and save it to disk
func downloadPackageFile() (err error) {
var resp *http.Response
resp, err = client.Get(packageURL)
// var resp *http.Response
// resp, err = client.Get(packageURL)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*90)
defer cancel()
resp, err := clashHttp.HttpRequest(ctx, packageURL, http.MethodGet, http.Header{"User-Agent": {"clash"}}, nil)
if err != nil {
return fmt.Errorf("http request failed: %w", err)
}
@ -255,11 +268,11 @@ func downloadPackageFile() (err error) {
log.Debugln("updateDir %s", updateDir)
err = os.Mkdir(updateDir, 0o755)
if err != nil {
fmt.Errorf("mkdir error: %w", err)
return fmt.Errorf("mkdir error: %w", err)
}
log.Debugln("updater: saving package to file %s", packageName)
err = os.WriteFile(packageName, body, 0o755)
err = os.WriteFile(packageName, body, 0o644)
if err != nil {
return fmt.Errorf("os.WriteFile() failed: %w", err)
}
@ -405,10 +418,12 @@ func copyFile(src, dst string) error {
return nil
}
func getLatestVersion() string {
resp, err := http.Get(versionURL)
func getLatestVersion() (version string, err error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
defer cancel()
resp, err := clashHttp.HttpRequest(ctx, versionURL, http.MethodGet, http.Header{"User-Agent": {"clash"}}, nil)
if err != nil {
return ""
return "", fmt.Errorf("get Latest Version fail: %w", err)
}
defer func() {
closeErr := resp.Body.Close()
@ -419,11 +434,10 @@ func getLatestVersion() string {
body, err := io.ReadAll(resp.Body)
if err != nil {
return ""
return "", fmt.Errorf("get Latest Version fail: %w", err)
}
content := strings.TrimRight(string(body), "\n")
log.Infoln("latest:%s", content)
return content
return content, nil
}
func updateDownloadURL() {