Skip to content

Commit

Permalink
add subscribe info from origin server
Browse files Browse the repository at this point in the history
  • Loading branch information
czyt committed Oct 10, 2024
1 parent fe63197 commit db2c28a
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 7 deletions.
16 changes: 16 additions & 0 deletions internal/pkg/bytesEx/appender.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package bytesEx

import "bytes"

func AppendPerLine(bytesToAppend []byte, appendContent string) []byte {
parts := bytes.Split(bytesToAppend, []byte{'\n'})
var buffer bytes.Buffer
for i, part := range parts {
buffer.Write(part)
buffer.WriteString(appendContent)
if i < len(parts)-1 {
buffer.WriteByte('\n')
}
}
return buffer.Bytes()
}
20 changes: 20 additions & 0 deletions internal/pkg/bytesEx/appender_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package bytesEx

import (
"encoding/base64"
"testing"
)

var data = "xxxx"

func TestAppendPerLine(t *testing.T) {
dst := make([]byte, base64.StdEncoding.DecodedLen(len(data)))
n, err := base64.StdEncoding.Decode(dst, []byte(data))
if err != nil {
t.Fatal(err)
}
dst = dst[:n]
line := AppendPerLine(dst, "🤭fucking high")
s := base64.StdEncoding.EncodeToString(line)
t.Log(s)
}
26 changes: 19 additions & 7 deletions internal/pkg/fetcher/fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/go-resty/resty/v2"
"net/http"
"raycat/internal/pkg/bytesEx"
"raycat/internal/pkg/subinfo"
"time"
)

Expand All @@ -30,16 +31,27 @@ func (c *Client) Fetch(baseUrl string) ([]byte, error) {
if err != nil {
return nil, err
}
var result []byte
if !bytesEx.IsBase64(resp.Body()) {
return resp.Body(), nil
result = resp.Body()
} else {
decodeLen := base64.StdEncoding.EncodedLen(len(resp.Body()))
decoded := make([]byte, decodeLen)
n, err := base64.StdEncoding.Decode(decoded, resp.Body())
if err != nil {
return nil, err
}
result = decoded[:n]
}
decodeLen := base64.StdEncoding.EncodedLen(len(resp.Body()))
decoded := make([]byte, decodeLen)
n, err := base64.StdEncoding.Decode(decoded, resp.Body())
if err != nil {
return nil, err
// check the sub has Subscription-Userinfo
subscribeInfo := resp.Header().Get("Subscription-Userinfo")
if subscribeInfo != "" {
info, err := subinfo.ParseSubscriptionInfo(subscribeInfo)
if err == nil && info != nil {
result = bytesEx.AppendPerLine(result, info.String())
}
}
return decoded[:n], nil
return result, nil
}

func checkResourceAvailable(url string) bool {
Expand Down
80 changes: 80 additions & 0 deletions internal/pkg/subinfo/subinfo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package subinfo

import (
"errors"
"fmt"
"strconv"
"strings"
"time"
)

const (
units = "KMGTPE"
unit = 1024
)

var (
invalidSubscribeUserInfoError = errors.New("invalid subscribe user info ")
)

// SubscriptionInfo 结构体用于存储解析后的信息
type SubscriptionInfo struct {
Upload int64
Download int64
Total int64
Expire time.Time
}

// ParseSubscriptionInfo parse Subscription-Userinfo
func ParseSubscriptionInfo(info string) (*SubscriptionInfo, error) {
result := &SubscriptionInfo{}
pairs := strings.Split(info, ";")
if len(pairs) == 0 {
return nil, invalidSubscribeUserInfoError
}
for _, pair := range pairs {
pair = strings.TrimSpace(pair)
kv := strings.SplitN(pair, "=", 2)
if len(kv) != 2 {
continue
}
key := strings.TrimSpace(kv[0])
value := strings.TrimSpace(kv[1])

switch key {
case "upload":
result.Upload, _ = strconv.ParseInt(value, 10, 64)
case "download":
result.Download, _ = strconv.ParseInt(value, 10, 64)
case "total":
result.Total, _ = strconv.ParseInt(value, 10, 64)
case "expire":
expireTime, err := strconv.ParseInt(value, 10, 64)
if err == nil {
result.Expire = time.Unix(expireTime, 0)
}
}
}
return result, nil
}

func formatBytes(bytes int64) string {
if bytes < unit {
return fmt.Sprintf("%d B", bytes)
}
div, exp := int64(unit), 0
for n := bytes / unit; n >= unit; n /= unit {
div *= unit
exp++
}
return fmt.Sprintf("%.1f %cB", float64(bytes)/float64(div), units[exp])
}

// String impl Stringer to display
func (si *SubscriptionInfo) String() string {
return fmt.Sprintf("ℹ Upload: %s Download: %s Total: %s ExpireAt: %s",
formatBytes(si.Upload),
formatBytes(si.Download),
formatBytes(si.Total),
si.Expire.Format("2006-01-02 15:04"))
}

0 comments on commit db2c28a

Please sign in to comment.