falcon/proxy.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)
}
}