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 }