github.com/eagleql/xray-core@v1.4.4/main/confloader/external/external.go (about)

     1  package external
     2  
     3  //go:generate go run github.com/eagleql/xray-core/common/errors/errorgen
     4  
     5  import (
     6  	"bytes"
     7  	"io"
     8  	"io/ioutil"
     9  	"net/http"
    10  	"net/url"
    11  	"os"
    12  	"strings"
    13  	"time"
    14  
    15  	"github.com/eagleql/xray-core/common/buf"
    16  	"github.com/eagleql/xray-core/common/platform/ctlcmd"
    17  	"github.com/eagleql/xray-core/main/confloader"
    18  )
    19  
    20  func ConfigLoader(arg string) (out io.Reader, err error) {
    21  	var data []byte
    22  	switch {
    23  	case strings.HasPrefix(arg, "http://"), strings.HasPrefix(arg, "https://"):
    24  		data, err = FetchHTTPContent(arg)
    25  
    26  	case arg == "stdin:":
    27  		data, err = ioutil.ReadAll(os.Stdin)
    28  
    29  	default:
    30  		data, err = ioutil.ReadFile(arg)
    31  	}
    32  
    33  	if err != nil {
    34  		return
    35  	}
    36  	out = bytes.NewBuffer(data)
    37  	return
    38  }
    39  
    40  func FetchHTTPContent(target string) ([]byte, error) {
    41  	parsedTarget, err := url.Parse(target)
    42  	if err != nil {
    43  		return nil, newError("invalid URL: ", target).Base(err)
    44  	}
    45  
    46  	if s := strings.ToLower(parsedTarget.Scheme); s != "http" && s != "https" {
    47  		return nil, newError("invalid scheme: ", parsedTarget.Scheme)
    48  	}
    49  
    50  	client := &http.Client{
    51  		Timeout: 30 * time.Second,
    52  	}
    53  	resp, err := client.Do(&http.Request{
    54  		Method: "GET",
    55  		URL:    parsedTarget,
    56  		Close:  true,
    57  	})
    58  	if err != nil {
    59  		return nil, newError("failed to dial to ", target).Base(err)
    60  	}
    61  	defer resp.Body.Close()
    62  
    63  	if resp.StatusCode != 200 {
    64  		return nil, newError("unexpected HTTP status code: ", resp.StatusCode)
    65  	}
    66  
    67  	content, err := buf.ReadAllToBytes(resp.Body)
    68  	if err != nil {
    69  		return nil, newError("failed to read HTTP response").Base(err)
    70  	}
    71  
    72  	return content, nil
    73  }
    74  
    75  func ExtConfigLoader(files []string, reader io.Reader) (io.Reader, error) {
    76  	buf, err := ctlcmd.Run(append([]string{"convert"}, files...), reader)
    77  	if err != nil {
    78  		return nil, err
    79  	}
    80  
    81  	return strings.NewReader(buf.String()), nil
    82  }
    83  
    84  func init() {
    85  	confloader.EffectiveConfigFileLoader = ConfigLoader
    86  	confloader.EffectiveExtConfigLoader = ExtConfigLoader
    87  }