Last active
July 3, 2021 23:22
-
-
Save AmirSoleimani/bfc29e3936af5a7221680fbb8f11682c to your computer and use it in GitHub Desktop.
NordVPN Proxy and HTTP Request
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/json" | |
"fmt" | |
"io/ioutil" | |
"log" | |
"net/http" | |
"os" | |
"time" | |
"golang.org/x/net/proxy" | |
) | |
const ( | |
NordServerListEndpoint = "https://nordvpn.com/api/server" | |
NordSocks5Port = "1080" | |
) | |
var ( | |
NordUser = os.Getenv("NORD_EMAIL") | |
NordPassword = os.Getenv("NORD_PASSWORD") | |
NordProxyServers = []NordServer{} | |
) | |
type NordServer struct { | |
IPAddress string `json:"ip_address"` | |
Domain string `json:"domain"` | |
Country string `json:"country"` | |
Features struct { | |
Socks bool `json:"socks"` | |
} `json:"features"` | |
} | |
const TestURL = "https://ifconfig.me" | |
var ( | |
ProxyRound int | |
httpTransportCache = map[string]*http.Transport{} | |
) | |
func main() { | |
var err error | |
NordProxyServers, err = GetServerList() | |
if err != nil { | |
log.Fatal(err) | |
} | |
for i := 0; i < 50; i++ { | |
proxyServer := NordProxyServers[ProxyRound%len(NordProxyServers)] | |
ProxyRound++ | |
// setup a http client | |
cachedHttpTransport, exist := httpTransportCache[proxyServer.Domain] | |
if !exist { | |
// create a socks5 dialer | |
dialer, err := proxy.SOCKS5("tcp", proxyServer.Domain+":"+NordSocks5Port, &proxy.Auth{ | |
User: NordUser, | |
Password: NordPassword, | |
}, proxy.Direct) | |
if err != nil { | |
fmt.Fprintln(os.Stderr, "can't connect to the proxy:", err) | |
continue | |
} | |
cachedHttpTransport = &http.Transport{} | |
if contextDialer, ok := dialer.(proxy.ContextDialer); ok { | |
cachedHttpTransport.DialContext = contextDialer.DialContext | |
} | |
httpTransportCache[proxyServer.Domain] = cachedHttpTransport | |
} | |
IP, err := GetMyIP(cachedHttpTransport.Clone()) | |
if err != nil { | |
fmt.Fprintln(os.Stderr, "can't get the IP address:", err) | |
continue | |
} | |
fmt.Printf("IP:%s ProxyDomain:%s ProxyCountry:%s\n", string(IP), proxyServer.Domain, proxyServer.Domain) | |
} | |
} | |
func GetMyIP(httpTransport *http.Transport) ([]byte, error) { | |
defer httpTransport.CloseIdleConnections() | |
httpClient := &http.Client{ | |
Transport: httpTransport, | |
Timeout: 15 * time.Second, | |
} | |
// Do request | |
resp, err := httpClient.Get(TestURL) | |
if err != nil { | |
return nil, err | |
} | |
defer resp.Body.Close() | |
return ioutil.ReadAll(resp.Body) | |
} | |
func GetServerList() ([]NordServer, error) { | |
resp, err := http.Get(NordServerListEndpoint) | |
if err != nil { | |
return nil, err | |
} | |
if resp.StatusCode != 200 { | |
return nil, fmt.Errorf("Response status code is %d", resp.StatusCode) | |
} | |
respByte, err := ioutil.ReadAll(resp.Body) | |
if err != nil { | |
return nil, err | |
} | |
result := []NordServer{} | |
err = json.Unmarshal(respByte, &result) | |
if err != nil { | |
return nil, err | |
} | |
output := []NordServer{} | |
for _, s := range result { | |
if s.Features.Socks { | |
output = append(output, s) | |
} | |
} | |
return output, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment