135 lines
2.8 KiB
Go
135 lines
2.8 KiB
Go
package falcon
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// Endpoint for proxy lookup
|
|
var endpoint = "http://ip-api.com/json?fields=66842623"
|
|
|
|
// Lookup represents a proxy lookup
|
|
type Lookup struct {
|
|
Protocol string `json:"protocol"`
|
|
IP string `json:"ip"`
|
|
Port int `json:"port"`
|
|
|
|
Status string `json:"status"`
|
|
Continent string `json:"continent"`
|
|
ContinentCode string `json:"continentCode"`
|
|
Country string `json:"country"`
|
|
CountryCode string `json:"countryCode"`
|
|
Region string `json:"region"`
|
|
RegionName string `json:"regionName"`
|
|
City string `json:"city"`
|
|
District string `json:"district"`
|
|
Zip string `json:"zip"`
|
|
Lat float64 `json:"lat"`
|
|
Lon float64 `json:"lon"`
|
|
Timezone string `json:"timezone"`
|
|
Offset int `json:"offset"`
|
|
Currency string `json:"currency"`
|
|
Isp string `json:"isp"`
|
|
Org string `json:"org"`
|
|
As string `json:"as"`
|
|
Asname string `json:"asname"`
|
|
Mobile bool `json:"mobile"`
|
|
Proxy bool `json:"proxy"`
|
|
Hosting bool `json:"hosting"`
|
|
Query string `json:"query"`
|
|
}
|
|
|
|
// Channels represents incoming proxy channels
|
|
type Channels struct {
|
|
// Incoming verified SOCKS5 proxies
|
|
SOCKS5 chan *Lookup
|
|
// Incoming verified SOCKS4 proxies
|
|
SOCKS4 chan *Lookup
|
|
// Incoming verified SOCKS4A proxies
|
|
SOCKS4A chan *Lookup
|
|
// Incoming verified HTTP proxies
|
|
HTTP chan *Lookup
|
|
// Incoming errors
|
|
Error chan error
|
|
}
|
|
|
|
// Verify will verify a proxy
|
|
func (c *Channels) Verify(proxy string, timeout time.Duration) {
|
|
// Create transport
|
|
scheme, transport, err := Transport(proxy)
|
|
if err != nil {
|
|
c.Error <- err
|
|
return
|
|
}
|
|
|
|
// Create client
|
|
client := &http.Client{
|
|
Timeout: timeout,
|
|
Transport: transport,
|
|
}
|
|
|
|
// Create request
|
|
req, err := http.NewRequest("GET", endpoint, nil)
|
|
if err != nil {
|
|
c.Error <- err
|
|
return
|
|
}
|
|
|
|
// Execute request
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
c.Error <- err
|
|
return
|
|
}
|
|
|
|
// Read body
|
|
body, err := io.ReadAll(res.Body)
|
|
if err != nil {
|
|
c.Error <- err
|
|
return
|
|
}
|
|
|
|
// Store lookup
|
|
var lookup Lookup
|
|
|
|
// Unmarshal JSON
|
|
err = json.Unmarshal(body, &lookup)
|
|
if err != nil {
|
|
c.Error <- err
|
|
return
|
|
}
|
|
|
|
// Replace & split IP
|
|
ip := strings.Split(strings.ReplaceAll(proxy, "//", ""), ":")
|
|
|
|
// Convert port
|
|
port, err := strconv.Atoi(ip[2])
|
|
if err != nil {
|
|
port = 0
|
|
}
|
|
|
|
// Set values
|
|
lookup.Protocol = scheme
|
|
lookup.IP = ip[1]
|
|
lookup.Port = port
|
|
|
|
// Check scheme
|
|
switch scheme {
|
|
case "socks5":
|
|
c.SOCKS5 <- &lookup
|
|
case "socks4":
|
|
c.SOCKS4 <- &lookup
|
|
case "socks4a":
|
|
c.SOCKS4A <- &lookup
|
|
case "https", "http":
|
|
c.HTTP <- &lookup
|
|
default:
|
|
c.Error <- fmt.Errorf("unknown proxy scheme: %s", scheme)
|
|
}
|
|
}
|