123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- package updater
- import (
- "context"
- "fmt"
- "io"
- "net/http"
- "os"
- "time"
- mihomoHttp "github.com/metacubex/mihomo/component/http"
- C "github.com/metacubex/mihomo/constant"
- "golang.org/x/exp/constraints"
- )
- func downloadForBytes(url string) ([]byte, error) {
- ctx, cancel := context.WithTimeout(context.Background(), time.Second*90)
- defer cancel()
- resp, err := mihomoHttp.HttpRequest(ctx, url, http.MethodGet, http.Header{"User-Agent": {C.UA}}, nil)
- if err != nil {
- return nil, err
- }
- defer resp.Body.Close()
- return io.ReadAll(resp.Body)
- }
- func saveFile(bytes []byte, path string) error {
- return os.WriteFile(path, bytes, 0o644)
- }
- // LimitReachedError records the limit and the operation that caused it.
- type LimitReachedError struct {
- Limit int64
- }
- // Error implements the [error] interface for *LimitReachedError.
- //
- // TODO(a.garipov): Think about error string format.
- func (lre *LimitReachedError) Error() string {
- return fmt.Sprintf("attempted to read more than %d bytes", lre.Limit)
- }
- // limitedReader is a wrapper for [io.Reader] limiting the input and dealing
- // with errors package.
- type limitedReader struct {
- r io.Reader
- limit int64
- n int64
- }
- // Read implements the [io.Reader] interface.
- func (lr *limitedReader) Read(p []byte) (n int, err error) {
- if lr.n == 0 {
- return 0, &LimitReachedError{
- Limit: lr.limit,
- }
- }
- p = p[:Min(lr.n, int64(len(p)))]
- n, err = lr.r.Read(p)
- lr.n -= int64(n)
- return n, err
- }
- // LimitReader wraps Reader to make it's Reader stop with ErrLimitReached after
- // n bytes read.
- func LimitReader(r io.Reader, n int64) (limited io.Reader, err error) {
- if n < 0 {
- return nil, &updateError{Message: "limit must be non-negative"}
- }
- return &limitedReader{
- r: r,
- limit: n,
- n: n,
- }, nil
- }
- // Min returns the smaller of x or y.
- func Min[T constraints.Integer | ~string](x, y T) (res T) {
- if x < y {
- return x
- }
- return y
- }
|