Backport: parsing improvement + tests
This commit is contained in:
parent
0b8aecb1c8
commit
aebdfe2131
|
@ -0,0 +1,13 @@
|
|||
package pools
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var CopABuffer = &sync.Pool{New: func() interface{} { return &strings.Builder{} }}
|
||||
|
||||
func DiscardBuffer(buf *strings.Builder) {
|
||||
buf.Reset()
|
||||
CopABuffer.Put(buf)
|
||||
}
|
|
@ -2,16 +2,12 @@ package prox5
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
ipa "inet.af/netaddr"
|
||||
)
|
||||
|
||||
// throw shit proxies here, get map
|
||||
|
@ -22,70 +18,6 @@ func init() {
|
|||
inChan = make(chan string, 100000)
|
||||
}
|
||||
|
||||
func checkV6(in string) (filtered string, ok bool) {
|
||||
split := strings.Split(in, "]:")
|
||||
if len(split) != 2 {
|
||||
return in, false
|
||||
}
|
||||
|
||||
combo, err := ipa.ParseIPPort(split[0] + "]:" + split[1])
|
||||
if err != nil {
|
||||
return in, false
|
||||
}
|
||||
|
||||
if !strings.Contains(split[1], ":") {
|
||||
return combo.String(), true
|
||||
}
|
||||
|
||||
split6 := strings.Split(split[1], ":")
|
||||
if len(split6) != 2 {
|
||||
return in, false
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s:%s@%s", split6[0], split6[1], combo.String()), true
|
||||
}
|
||||
|
||||
func (s *Swamp) filter(in string) (filtered string, ok bool) {
|
||||
if !strings.Contains(in, ":") {
|
||||
return in, false
|
||||
}
|
||||
split := strings.Split(in, ":")
|
||||
|
||||
if len(split) < 2 {
|
||||
return in, false
|
||||
}
|
||||
|
||||
if _, err := strconv.Atoi(split[1]); err != nil {
|
||||
return in, false
|
||||
}
|
||||
|
||||
switch len(split) {
|
||||
case 2:
|
||||
if _, ok := dns.IsDomainName(split[0]); ok {
|
||||
return in, true
|
||||
}
|
||||
combo, err := ipa.ParseIPPort(in)
|
||||
if err != nil {
|
||||
return in, false
|
||||
}
|
||||
return combo.String(), true
|
||||
case 4:
|
||||
if _, ok := dns.IsDomainName(split[0]); ok {
|
||||
return fmt.Sprintf("%s:%s@%s:%s", split[2], split[3], split[0], split[1]), true
|
||||
}
|
||||
combo, err := ipa.ParseIPPort(split[0] + ":" + split[1])
|
||||
if err != nil {
|
||||
return in, false
|
||||
}
|
||||
return fmt.Sprintf("%s:%s@%s", split[2], split[3], combo.String()), true
|
||||
default:
|
||||
if !strings.Contains(split[0], "[") || !strings.Contains(split[0], "]:") {
|
||||
return in, false
|
||||
}
|
||||
}
|
||||
return checkV6(in)
|
||||
}
|
||||
|
||||
// LoadProxyTXT loads proxies from a given seed file and feeds them to the mapBuilder to be later queued automatically for validation.
|
||||
// Expects the following formats:
|
||||
// * 127.0.0.1:1080
|
||||
|
@ -125,7 +57,7 @@ func (s *Swamp) LoadProxyTXT(seedFile string) int {
|
|||
|
||||
// LoadSingleProxy loads a SOCKS proxy into our map. Uses the format: 127.0.0.1:1080 (host:port).
|
||||
func (s *Swamp) LoadSingleProxy(sock string) (ok bool) {
|
||||
if sock, ok = s.filter(sock); !ok {
|
||||
if sock, ok = filter(sock); !ok {
|
||||
return
|
||||
}
|
||||
go s.loadSingleProxy(sock)
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
package prox5
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
ipa "inet.af/netaddr"
|
||||
|
||||
"git.tcp.direct/kayos/prox5/internal/pools"
|
||||
)
|
||||
|
||||
func filterv6(in string) (filtered string, ok bool) {
|
||||
split := strings.Split(in, "]:")
|
||||
if len(split) < 2 {
|
||||
|
||||
return "", false
|
||||
}
|
||||
split2 := strings.Split(split[1], ":")
|
||||
switch len(split2) {
|
||||
case 0:
|
||||
combo, err := ipa.ParseIPPort(buildProxyString("", "", split[0], split2[0], true))
|
||||
if err == nil {
|
||||
return combo.String(), true
|
||||
}
|
||||
case 1:
|
||||
concat := buildProxyString("", "", split[0], split2[0], true)
|
||||
combo, err := ipa.ParseIPPort(concat)
|
||||
if err == nil {
|
||||
return combo.String(), true
|
||||
}
|
||||
default:
|
||||
_, err := ipa.ParseIPPort(buildProxyString("", "", split[0], split2[0], true))
|
||||
if err == nil {
|
||||
return buildProxyString(split2[1], split2[2], split[0], split2[0], true), true
|
||||
}
|
||||
}
|
||||
return "", true
|
||||
}
|
||||
|
||||
func isNumber(s string) bool {
|
||||
_, err := strconv.Atoi(s)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
func buildProxyString(username, password, address, port string, v6 bool) (result string) {
|
||||
builder := pools.CopABuffer.Get().(*strings.Builder)
|
||||
if username != "" && password != "" {
|
||||
builder.WriteString(username)
|
||||
builder.WriteString(":")
|
||||
builder.WriteString(password)
|
||||
builder.WriteString("@")
|
||||
}
|
||||
builder.WriteString(address)
|
||||
if v6 {
|
||||
builder.WriteString("]")
|
||||
}
|
||||
builder.WriteString(":")
|
||||
builder.WriteString(port)
|
||||
result = builder.String()
|
||||
pools.DiscardBuffer(builder)
|
||||
return
|
||||
}
|
||||
|
||||
func filter(in string) (filtered string, ok bool) { //nolint:cyclop
|
||||
if !strings.Contains(in, ":") {
|
||||
return "", false
|
||||
}
|
||||
split := strings.Split(in, ":")
|
||||
|
||||
if len(split) < 2 {
|
||||
return "", false
|
||||
}
|
||||
switch len(split) {
|
||||
case 2:
|
||||
_, isDomain := dns.IsDomainName(split[0])
|
||||
if isDomain && isNumber(split[1]) {
|
||||
return in, true
|
||||
}
|
||||
combo, err := ipa.ParseIPPort(in)
|
||||
if err != nil {
|
||||
return "", false
|
||||
}
|
||||
return combo.String(), true
|
||||
case 4:
|
||||
_, isDomain := dns.IsDomainName(split[0])
|
||||
if isDomain && isNumber(split[1]) {
|
||||
return buildProxyString(split[2], split[3], split[0], split[1], false), true
|
||||
}
|
||||
_, isDomain = dns.IsDomainName(split[2])
|
||||
if isDomain && isNumber(split[3]) {
|
||||
return buildProxyString(split[0], split[1], split[2], split[3], false), true
|
||||
}
|
||||
if _, err := ipa.ParseIPPort(split[2] + ":" + split[3]); err == nil {
|
||||
return buildProxyString(split[0], split[1], split[2], split[3], false), true
|
||||
}
|
||||
if _, err := ipa.ParseIPPort(split[0] + ":" + split[1]); err == nil {
|
||||
return buildProxyString(split[2], split[3], split[0], split[1], false), true
|
||||
}
|
||||
default:
|
||||
if !strings.Contains(in, "[") || !strings.Contains(in, "]:") {
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
return filterv6(in)
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package prox5
|
||||
|
||||
import "testing"
|
||||
|
||||
func Test_filter(t *testing.T) {
|
||||
type args struct {
|
||||
in string
|
||||
}
|
||||
type test struct {
|
||||
name string
|
||||
args args
|
||||
wantFiltered string
|
||||
wantOk bool
|
||||
}
|
||||
var tests = []test{
|
||||
{
|
||||
name: "simple",
|
||||
args: args{
|
||||
in: "127.0.0.1:1080",
|
||||
},
|
||||
wantFiltered: "127.0.0.1:1080",
|
||||
wantOk: true,
|
||||
},
|
||||
{
|
||||
name: "withAuth",
|
||||
args: args{
|
||||
in: "127.0.0.1:1080:user:pass",
|
||||
},
|
||||
wantFiltered: "user:pass@127.0.0.1:1080",
|
||||
wantOk: true,
|
||||
},
|
||||
{
|
||||
name: "simpleDomain",
|
||||
args: args{
|
||||
in: "yeet.com:1080",
|
||||
},
|
||||
wantFiltered: "yeet.com:1080",
|
||||
wantOk: true,
|
||||
},
|
||||
{
|
||||
name: "domainWithAuth",
|
||||
args: args{
|
||||
in: "yeet.com:1080:user:pass",
|
||||
},
|
||||
wantFiltered: "user:pass@yeet.com:1080",
|
||||
wantOk: true,
|
||||
},
|
||||
{
|
||||
name: "ipv6",
|
||||
args: args{
|
||||
in: "[fe80::2ef0:5dff:fe7f:c299]:1080",
|
||||
},
|
||||
wantFiltered: "[fe80::2ef0:5dff:fe7f:c299]:1080",
|
||||
wantOk: true,
|
||||
},
|
||||
{
|
||||
name: "ipv6WithAuth",
|
||||
args: args{
|
||||
in: "[fe80::2ef0:5dff:fe7f:c299]:1080:user:pass",
|
||||
},
|
||||
wantFiltered: "user:pass@[fe80::2ef0:5dff:fe7f:c299]:1080",
|
||||
wantOk: true,
|
||||
},
|
||||
{
|
||||
name: "invalid",
|
||||
args: args{
|
||||
in: "yeet",
|
||||
},
|
||||
wantFiltered: "",
|
||||
wantOk: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotFiltered, gotOk := filter(tt.args.in)
|
||||
if gotFiltered != tt.wantFiltered {
|
||||
t.Errorf("filter() gotFiltered = %v, want %v", gotFiltered, tt.wantFiltered)
|
||||
}
|
||||
if gotOk != tt.wantOk {
|
||||
t.Errorf("filter() gotOk = %v, want %v", gotOk, tt.wantOk)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue