65 lines
1.3 KiB
Go
65 lines
1.3 KiB
Go
package windscribe
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
var (
|
|
ErrHTTPStatusCodeNotOK = errors.New("HTTP status code not OK")
|
|
ErrUnmarshalResponseBody = errors.New("failed unmarshaling response body")
|
|
)
|
|
|
|
type apiData struct {
|
|
Data []regionData `json:"data"`
|
|
}
|
|
|
|
type regionData struct {
|
|
Region string `json:"name"`
|
|
Groups []groupData `json:"groups"`
|
|
}
|
|
|
|
type groupData struct {
|
|
City string `json:"city"`
|
|
Nodes []serverData `json:"nodes"`
|
|
OvpnX509 string `json:"ovpn_x509"`
|
|
}
|
|
|
|
type serverData struct {
|
|
Hostname string `json:"hostname"`
|
|
IP net.IP `json:"ip"`
|
|
IP2 net.IP `json:"ip2"`
|
|
IP3 net.IP `json:"ip3"`
|
|
}
|
|
|
|
func fetchAPI(ctx context.Context, client *http.Client) (
|
|
data apiData, err error) {
|
|
const baseURL = "https://assets.windscribe.com/serverlist/mob-v2/1/"
|
|
cacheBreaker := time.Now().Unix()
|
|
url := baseURL + strconv.Itoa(int(cacheBreaker))
|
|
|
|
request, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
|
if err != nil {
|
|
return data, err
|
|
}
|
|
|
|
response, err := client.Do(request)
|
|
if err != nil {
|
|
return data, err
|
|
}
|
|
defer response.Body.Close()
|
|
|
|
decoder := json.NewDecoder(response.Body)
|
|
if err := decoder.Decode(&data); err != nil {
|
|
return data, fmt.Errorf("%w: %s", ErrUnmarshalResponseBody, err)
|
|
}
|
|
|
|
return data, nil
|
|
}
|