Feat: rework Surfshark servers data (#575)

- Feat: `MULTIHOP_ONLY` variable
- Feat: `COUNTRY` variable
- Feat: `CITY` variable
- Feat: `REGION` variable, with retro-compatibility
- Feat: merge servers from API, zip and hardcoded hostnames
- Fix: remove outdated and duplicate servers
- Maint: faster update with fully parallel DNS resolutions
This commit is contained in:
Quentin McGaw
2021-08-23 10:25:00 -07:00
committed by GitHub
parent 8b52af0d03
commit f1a82d9d9c
21 changed files with 3023 additions and 1803 deletions

View File

@@ -6,21 +6,43 @@ import (
"errors"
"fmt"
"net/http"
"github.com/qdm12/gluetun/internal/constants"
)
// Note: no multi-hop and some servers are missing from their API.
func addServersFromAPI(ctx context.Context, client *http.Client,
hts hostToServer) (err error) {
data, err := fetchAPI(ctx, client)
if err != nil {
return err
}
hostToLocation := constants.SurfsharkHostToLocation()
const tcp, udp = true, true
for _, serverData := range data {
locationData := hostToLocation[serverData.Host] // TODO remove in v4
retroLoc := locationData.RetroLoc // empty string if the host has no retro-compatible region
hts.add(serverData.Host, serverData.Region, serverData.Country,
serverData.Location, retroLoc, tcp, udp)
}
return nil
}
var (
ErrHTTPStatusCodeNotOK = errors.New("HTTP status code not OK")
ErrUnmarshalResponseBody = errors.New("failed unmarshaling response body")
)
//nolint:unused
type serverData struct {
Host string `json:"connectionName"`
Region string `json:"region"`
Country string `json:"country"`
Location string `json:"location"`
}
//nolint:unused,deadcode
func fetchAPI(ctx context.Context, client *http.Client) (
servers []serverData, err error) {
const url = "https://my.surfshark.com/vpn/api/v4/server/clusters"
@@ -37,7 +59,8 @@ func fetchAPI(ctx context.Context, client *http.Client) (
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
return nil, fmt.Errorf("%w: %s", ErrHTTPStatusCodeNotOK, response.Status)
return nil, fmt.Errorf("%w: %d %s", ErrHTTPStatusCodeNotOK,
response.StatusCode, response.Status)
}
decoder := json.NewDecoder(response.Body)