github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/infra/control/fetch.go (about)

     1  package control
     2  
     3  import (
     4  	"net/http"
     5  	"net/url"
     6  	"os"
     7  	"strings"
     8  	"time"
     9  
    10  	"v2ray.com/core/common"
    11  	"v2ray.com/core/common/buf"
    12  )
    13  
    14  type FetchCommand struct{}
    15  
    16  func (c *FetchCommand) Name() string {
    17  	return "fetch"
    18  }
    19  
    20  func (c *FetchCommand) Description() Description {
    21  	return Description{
    22  		Short: "Fetch resources",
    23  		Usage: []string{"v2ctl fetch <url>"},
    24  	}
    25  }
    26  
    27  func (c *FetchCommand) Execute(args []string) error {
    28  	if len(args) < 1 {
    29  		return newError("empty url")
    30  	}
    31  	content, err := FetchHTTPContent(args[0])
    32  	if err != nil {
    33  		return newError("failed to read HTTP response").Base(err)
    34  	}
    35  
    36  	os.Stdout.Write(content)
    37  	return nil
    38  }
    39  
    40  // FetchHTTPContent dials https for remote content
    41  func FetchHTTPContent(target string) ([]byte, error) {
    42  
    43  	parsedTarget, err := url.Parse(target)
    44  	if err != nil {
    45  		return nil, newError("invalid URL: ", target).Base(err)
    46  	}
    47  
    48  	if s := strings.ToLower(parsedTarget.Scheme); s != "http" && s != "https" {
    49  		return nil, newError("invalid scheme: ", parsedTarget.Scheme)
    50  	}
    51  
    52  	client := &http.Client{
    53  		Timeout: 30 * time.Second,
    54  	}
    55  	resp, err := client.Do(&http.Request{
    56  		Method: "GET",
    57  		URL:    parsedTarget,
    58  		Close:  true,
    59  	})
    60  	if err != nil {
    61  		return nil, newError("failed to dial to ", target).Base(err)
    62  	}
    63  	defer resp.Body.Close()
    64  
    65  	if resp.StatusCode != 200 {
    66  		return nil, newError("unexpected HTTP status code: ", resp.StatusCode)
    67  	}
    68  
    69  	content, err := buf.ReadAllToBytes(resp.Body)
    70  	if err != nil {
    71  		return nil, newError("failed to read HTTP response").Base(err)
    72  	}
    73  
    74  	return content, nil
    75  }
    76  
    77  func init() {
    78  	common.Must(RegisterCommand(&FetchCommand{}))
    79  }