parser.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package urlline
  2. import (
  3. "bufio"
  4. "bytes"
  5. "github.com/v2fly/v2ray-core/v5/app/subscription/containers"
  6. "github.com/v2fly/v2ray-core/v5/common"
  7. "net/url"
  8. "strings"
  9. )
  10. func newURLLineParser() containers.SubscriptionContainerDocumentParser {
  11. return &parser{}
  12. }
  13. type parser struct{}
  14. func (p parser) ParseSubscriptionContainerDocument(rawConfig []byte) (*containers.Container, error) {
  15. result := &containers.Container{}
  16. result.Kind = "URLLine"
  17. result.Metadata = make(map[string]string)
  18. scanner := bufio.NewScanner(bytes.NewReader(rawConfig))
  19. const maxCapacity int = 1024 * 256
  20. buf := make([]byte, maxCapacity)
  21. scanner.Buffer(buf, maxCapacity)
  22. parsedLine := 0
  23. failedLine := 0
  24. for scanner.Scan() {
  25. content := scanner.Text()
  26. content = strings.TrimSpace(content)
  27. if strings.HasPrefix(content, "#") {
  28. continue
  29. }
  30. if strings.HasPrefix(content, "//") {
  31. continue
  32. }
  33. _, err := url.Parse(content)
  34. if err != nil {
  35. failedLine++
  36. continue
  37. } else {
  38. parsedLine++
  39. }
  40. result.ServerSpecs = append(result.ServerSpecs, containers.UnparsedServerConf{
  41. KindHint: "URL",
  42. Content: scanner.Bytes(),
  43. })
  44. }
  45. if failedLine > parsedLine || parsedLine == 0 {
  46. return nil, newError("failed to parse as URLLine").Base(newError("too many failed lines"))
  47. }
  48. return result, nil
  49. }
  50. func init() {
  51. common.Must(containers.RegisterParser("URLLine", newURLLineParser()))
  52. }