github.com/igoogolx/clash@v1.19.8/adapter/provider/vehicle.go (about) 1 package provider 2 3 import ( 4 "context" 5 "io" 6 "net" 7 "net/http" 8 "net/url" 9 "os" 10 "time" 11 12 "github.com/igoogolx/clash/component/dialer" 13 types "github.com/igoogolx/clash/constant/provider" 14 ) 15 16 type FileVehicle struct { 17 path string 18 } 19 20 func (f *FileVehicle) Type() types.VehicleType { 21 return types.File 22 } 23 24 func (f *FileVehicle) Path() string { 25 return f.path 26 } 27 28 func (f *FileVehicle) Read() ([]byte, error) { 29 return os.ReadFile(f.path) 30 } 31 32 func NewFileVehicle(path string) *FileVehicle { 33 return &FileVehicle{path: path} 34 } 35 36 type HTTPVehicle struct { 37 url string 38 path string 39 } 40 41 func (h *HTTPVehicle) Type() types.VehicleType { 42 return types.HTTP 43 } 44 45 func (h *HTTPVehicle) Path() string { 46 return h.path 47 } 48 49 func (h *HTTPVehicle) Read() ([]byte, error) { 50 ctx, cancel := context.WithTimeout(context.Background(), time.Second*20) 51 defer cancel() 52 53 uri, err := url.Parse(h.url) 54 if err != nil { 55 return nil, err 56 } 57 58 req, err := http.NewRequest(http.MethodGet, uri.String(), nil) 59 if err != nil { 60 return nil, err 61 } 62 63 if user := uri.User; user != nil { 64 password, _ := user.Password() 65 req.SetBasicAuth(user.Username(), password) 66 } 67 68 req = req.WithContext(ctx) 69 70 transport := &http.Transport{ 71 // from http.DefaultTransport 72 MaxIdleConns: 100, 73 IdleConnTimeout: 90 * time.Second, 74 TLSHandshakeTimeout: 10 * time.Second, 75 ExpectContinueTimeout: 1 * time.Second, 76 DialContext: func(ctx context.Context, network, address string) (net.Conn, error) { 77 return dialer.DialContext(ctx, network, address) 78 }, 79 } 80 81 client := http.Client{Transport: transport} 82 resp, err := client.Do(req) 83 if err != nil { 84 return nil, err 85 } 86 defer resp.Body.Close() 87 88 buf, err := io.ReadAll(resp.Body) 89 if err != nil { 90 return nil, err 91 } 92 93 return buf, nil 94 } 95 96 func NewHTTPVehicle(url string, path string) *HTTPVehicle { 97 return &HTTPVehicle{url, path} 98 }