github.com/v2fly/v2ray-core/v5@v5.16.2-0.20240507031116-8191faa6e095/app/subscription/documentfetcher/httpfetcher/http.go (about) 1 package httpfetcher 2 3 import ( 4 "context" 5 "io" 6 gonet "net" 7 "net/http" 8 9 "github.com/v2fly/v2ray-core/v5/common" 10 "github.com/v2fly/v2ray-core/v5/common/net" 11 12 "github.com/v2fly/v2ray-core/v5/app/subscription" 13 "github.com/v2fly/v2ray-core/v5/app/subscription/documentfetcher" 14 "github.com/v2fly/v2ray-core/v5/common/environment" 15 "github.com/v2fly/v2ray-core/v5/common/environment/envctx" 16 ) 17 18 //go:generate go run github.com/v2fly/v2ray-core/v5/common/errors/errorgen 19 20 func newHTTPFetcher() *httpFetcher { 21 return &httpFetcher{} 22 } 23 24 func init() { 25 common.Must(documentfetcher.RegisterFetcher("http", newHTTPFetcher())) 26 } 27 28 type httpFetcher struct{} 29 30 func (h *httpFetcher) DownloadDocument(ctx context.Context, source *subscription.ImportSource, opts ...documentfetcher.FetcherOptions) ([]byte, error) { 31 instanceNetwork := envctx.EnvironmentFromContext(ctx).(environment.InstanceNetworkCapabilitySet) 32 outboundDialer := instanceNetwork.OutboundDialer() 33 var httpRoundTripper http.RoundTripper //nolint: gosimple 34 httpRoundTripper = &http.Transport{ 35 DialContext: func(ctx_ context.Context, network string, addr string) (gonet.Conn, error) { 36 dest, err := net.ParseDestination(network + ":" + addr) 37 if err != nil { 38 return nil, newError("unable to parse destination") 39 } 40 return outboundDialer(ctx, dest, source.ImportUsingTag) 41 }, 42 } 43 request, err := http.NewRequest("GET", source.Url, nil) 44 if err != nil { 45 return nil, newError("unable to generate request").Base(err) 46 } 47 resp, err := httpRoundTripper.RoundTrip(request) 48 if err != nil { 49 return nil, newError("unable to send request").Base(err) 50 } 51 defer resp.Body.Close() 52 if resp.StatusCode != http.StatusOK { 53 return nil, newError("unexpected http status ", resp.StatusCode, "=", resp.Status) 54 } 55 data, err := io.ReadAll(resp.Body) 56 if err != nil { 57 return nil, newError("unable to read response").Base(err) 58 } 59 return data, nil 60 }