Skip to content

Commit

Permalink
Feat: support to specify IP or CIDR in config file for text input format
Browse files Browse the repository at this point in the history
  • Loading branch information
Loyalsoldier committed Aug 31, 2024
1 parent a0d3f15 commit a5a300d
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 13 deletions.
43 changes: 39 additions & 4 deletions configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,10 @@ Supported `output` formats:
- **type**: (required) the name of the input format
- **action**: (required) action type, the value could be `add`(to add IP / CIDR) or `remove`(to remove IP / CIDR)
- **args**: (required)
- **name**: the list name (cannot be used with `inputDir`; must be used with `uri`)
- **uri**: the path to plaintext txt file, can be local file path or remote `http` or `https` URL (cannot be used with `inputDir`; must be used with `name`)
- **inputDir**: the directory of the files to walk through (excluded children directories). (the filename will be the list name; cannot be used with `name` or `uri`)
- **name**: (optional) the list name (cannot be used with `inputDir`; must be used with `uri` or `ipOrCIDR`)
- **uri**: (optional) the path to plaintext txt file, can be local file path or remote `http` or `https` URL (cannot be used with `inputDir`; must be used with `name`; can be used with `ipOrCIDR`)
- **ipOrCIDR**: (optional, array) an array of plaintext IP addresses or CIDRs (cannot be used with `inputDir`; must be used with `name`; can be used with `uri`)
- **inputDir**: (optional) the directory of the files to walk through (excluded children directories). (the filename will be the list name; cannot be used with `name` or `uri` or `ipOrCIDR`)
- **wantedList**: (optional, array) specified wanted files. (used with `inputDir`)
- **onlyIPType**: (optional) the IP address type to be processed, the value is `ipv4` or `ipv6`
- **removePrefixesInLine**: (optional, array) the array of string prefixes to be removed in each line
Expand All @@ -202,7 +203,7 @@ Supported `output` formats:
```jsonc
{
"type": "text",
"action": "add", // add IP or CIDR
"action": "add", // add IP or CIDR
"args": {
"name": "cn",
"uri": "./cn.txt", // get IPv4 and IPv6 addresses from local file cn.txt, and add to list cn
Expand All @@ -212,6 +213,40 @@ Supported `output` formats:
}
```

```jsonc
{
"type": "text",
"action": "add", // add IP or CIDR
"args": {
"name": "cn",
"ipOrCIDR": ["1.0.0.1", "1.0.0.1/24"] // add IP or CIDR to cn list
}
}
```

```jsonc
{
"type": "text",
"action": "remove", // remove IP or CIDR
"args": {
"name": "cn",
"ipOrCIDR": ["1.0.0.1", "1.0.0.1/24"] // remove IP or CIDR from cn list
}
}
```

```jsonc
{
"type": "text",
"action": "add", // add IP or CIDR
"args": {
"name": "cn",
"uri": "./cn.txt", // get IPv4 and IPv6 addresses from local file cn.txt, and add to list cn
"ipOrCIDR": ["1.0.0.1", "1.0.0.1/24"] // add IP or CIDR to cn list
}
}
```

```jsonc
{
"type": "text",
Expand Down
51 changes: 43 additions & 8 deletions plugin/plaintext/text_in.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ func newTextIn(action lib.Action, data json.RawMessage) (lib.InputConverter, err
var tmp struct {
Name string `json:"name"`
URI string `json:"uri"`
IPOrCIDR []string `json:"ipOrCIDR"`
InputDir string `json:"inputDir"`
Want []string `json:"wantedList"`
OnlyIPType lib.IPType `json:"onlyIPType"`
Expand All @@ -46,12 +47,15 @@ func newTextIn(action lib.Action, data json.RawMessage) (lib.InputConverter, err
}
}

if tmp.Name == "" && tmp.URI == "" && tmp.InputDir == "" {
return nil, fmt.Errorf("type %s | action %s missing inputdir or name or uri", typeTextIn, action)
}

if (tmp.Name != "" && tmp.URI == "") || (tmp.Name == "" && tmp.URI != "") {
return nil, fmt.Errorf("type %s | action %s name & uri must be specified together", typeTextIn, action)
if tmp.InputDir == "" {
if tmp.Name == "" {
return nil, fmt.Errorf("❌ [type %s | action %s] missing inputDir or name", typeTextIn, action)
}
if tmp.URI == "" && len(tmp.IPOrCIDR) == 0 {
return nil, fmt.Errorf("❌ [type %s | action %s] missing uri or ipOrCIDR", typeTextIn, action)
}
} else if tmp.Name != "" || tmp.URI != "" || len(tmp.IPOrCIDR) > 0 {
return nil, fmt.Errorf("❌ [type %s | action %s] inputDir is not allowed to be used with name or uri or ipOrCIDR", typeTextIn, action)
}

// Filter want list
Expand All @@ -68,6 +72,7 @@ func newTextIn(action lib.Action, data json.RawMessage) (lib.InputConverter, err
Description: descTextIn,
Name: tmp.Name,
URI: tmp.URI,
IPOrCIDR: tmp.IPOrCIDR,
InputDir: tmp.InputDir,
Want: wantList,
OnlyIPType: tmp.OnlyIPType,
Expand All @@ -83,6 +88,7 @@ type textIn struct {
Description string
Name string
URI string
IPOrCIDR []string
InputDir string
Want map[string]bool
OnlyIPType lib.IPType
Expand Down Expand Up @@ -110,15 +116,25 @@ func (t *textIn) Input(container lib.Container) (lib.Container, error) {
switch {
case t.InputDir != "":
err = t.walkDir(t.InputDir, entries)

case t.Name != "" && t.URI != "":
switch {
case strings.HasPrefix(strings.ToLower(t.URI), "http://"), strings.HasPrefix(strings.ToLower(t.URI), "https://"):
err = t.walkRemoteFile(t.URI, t.Name, entries)
default:
err = t.walkLocalFile(t.URI, t.Name, entries)
}
if err != nil {
return nil, err
}

fallthrough

case t.Name != "" && len(t.IPOrCIDR) > 0:
err = t.appendIPOrCIDR(t.IPOrCIDR, t.Name, entries)

default:
return nil, fmt.Errorf("config missing argument inputDir or name or uri")
return nil, fmt.Errorf("❌ [type %s | action %s] config missing argument inputDir or name or uri or ipOrCIDR", t.Type, t.Action)
}

if err != nil {
Expand All @@ -134,7 +150,7 @@ func (t *textIn) Input(container lib.Container) (lib.Container, error) {
}

if len(entries) == 0 {
return nil, fmt.Errorf("type %s | action %s no entry is generated", t.Type, t.Action)
return nil, fmt.Errorf("❌ [type %s | action %s] no entry is generated", t.Type, t.Action)
}

for _, entry := range entries {
Expand Down Expand Up @@ -280,3 +296,22 @@ func (t *textIn) scanFile(reader io.Reader, entry *lib.Entry) error {

return nil
}

func (t *textIn) appendIPOrCIDR(ipOrCIDR []string, name string, entries map[string]*lib.Entry) error {
name = strings.ToUpper(name)

entry, found := entries[name]
if !found {
entry = lib.NewEntry(name)
}

for _, cidr := range ipOrCIDR {
if err := entry.AddPrefix(strings.TrimSpace(cidr)); err != nil {
return err
}
}

entries[name] = entry

return nil
}
2 changes: 1 addition & 1 deletion plugin/v2ray/dat_in.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func newGeoIPDatIn(action lib.Action, data json.RawMessage) (lib.InputConverter,
}

if tmp.URI == "" {
return nil, fmt.Errorf("[type %s | action %s] uri must be specified in config", typeGeoIPdatIn, action)
return nil, fmt.Errorf("[type %s | action %s] uri must be specified in config", typeGeoIPdatIn, action)
}

// Filter want list
Expand Down

0 comments on commit a5a300d

Please sign in to comment.