Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- `internal/updater/html` package - Add unit tests for slickvpn updating code - Change shared html package to be more share-able - Split html utilities in multiple files - Fix processing .ovpn files with prefix space Authored by @Rohaq Co-authored-by: Quentin McGaw <quentin.mcgaw@gmail.com>
- Loading branch information
Showing
27 changed files
with
2,582 additions
and
16 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -54,6 +54,7 @@ body: | |
- PrivateVPN | ||
- ProtonVPN | ||
- PureVPN | ||
- SlickVPN | ||
- Surfshark | ||
- TorGuard | ||
- VPNUnlimited | ||
|
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package slickvpn | ||
|
||
import ( | ||
"github.com/qdm12/gluetun/internal/configuration/settings" | ||
"github.com/qdm12/gluetun/internal/models" | ||
"github.com/qdm12/gluetun/internal/provider/utils" | ||
) | ||
|
||
func (p *Provider) GetConnection(selection settings.ServerSelection) ( | ||
connection models.Connection, err error) { | ||
defaults := utils.NewConnectionDefaults(0, 443, 0) //nolint:gomnd | ||
return utils.GetConnection(p.Name(), p.storage, selection, defaults, p.randSource) | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package slickvpn | ||
|
||
import ( | ||
"github.com/qdm12/gluetun/internal/configuration/settings" | ||
"github.com/qdm12/gluetun/internal/constants/openvpn" | ||
"github.com/qdm12/gluetun/internal/models" | ||
"github.com/qdm12/gluetun/internal/provider/utils" | ||
) | ||
|
||
func (p *Provider) OpenVPNConfig(connection models.Connection, | ||
settings settings.OpenVPN) (lines []string) { | ||
const pingSeconds = 10 | ||
const bufSize = 393216 | ||
providerSettings := utils.OpenVPNProviderSettings{ | ||
RemoteCertTLS: true, | ||
AuthUserPass: true, | ||
Ciphers: []string{ | ||
openvpn.AES256cbc, | ||
}, | ||
Ping: pingSeconds, | ||
SndBuf: bufSize, | ||
RcvBuf: bufSize, | ||
// Certificate found from https://www.slickvpn.com/tutorials/using-openvpn-configuration-files/ | ||
CA: "MIIESDCCAzCgAwIBAgIJAKHK5bbBPSU2MA0GCSqGSIb3DQEBBQUAMHUxCzAJBgNVBAYTAlVTMQwwCgYDVQQIEwNWUE4xDDAKBgNVBAcTA1ZQTjEMMAoGA1UEChMDVlBOMQwwCgYDVQQLEwNWUE4xDDAKBgNVBAMTA1ZQTjEMMAoGA1UEKRMDVlBOMRIwEAYJKoZIhvcNAQkBFgNWUE4wHhcNMjIwMjE0MjEzNDQwWhcNMzIwMjEyMjEzNDQwWjB1MQswCQYDVQQGEwJVUzEMMAoGA1UECBMDVlBOMQwwCgYDVQQHEwNWUE4xDDAKBgNVBAoTA1ZQTjEMMAoGA1UECxMDVlBOMQwwCgYDVQQDEwNWUE4xDDAKBgNVBCkTA1ZQTjESMBAGCSqGSIb3DQEJARYDVlBOMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwUl1XkfGo3c1uFsvgbO3C3yvu0+cHs9IUSsju5U9cPNCo53mqRHU/qntCC+ldIDKN+dNWn7eURIDszy+flutkgucs0qgETy5fzpXnVMtiKmMiOYWiJDor7j7QivRaxoT/O2fyjxvVCL8gMa60ekWSGBT6isYY8t8BnwTPVP0KvDm36wdaqLmubhf2XGvka/hhNx0SXMmz2x3OJ8BcoypZVLLk/+Qm6DJh1KxyDi4kI+jBC41QuaKKDNwb0kth1304eqZoUeCXtGkzl91y76ODAfdqzXf9WYJdgkXpOm53Cg7FtB42AqPRqHJVwYxDnQyrFwy4a3CWqFJnKtxJM/WlwIDAQABo4HaMIHXMB0GA1UdDgQWBBRSzxAtISfbSRPr0fmhwNZc8kOeKzCBpwYDVR0jBIGfMIGcgBRSzxAtISfbSRPr0fmhwNZc8kOeK6F5pHcwdTELMAkGA1UEBhMCVVMxDDAKBgNVBAgTA1ZQTjEMMAoGA1UEBxMDVlBOMQwwCgYDVQQKEwNWUE4xDDAKBgNVBAsTA1ZQTjEMMAoGA1UEAxMDVlBOMQwwCgYDVQQpEwNWUE4xEjAQBgkqhkiG9w0BCQEWA1ZQToIJAKHK5bbBPSU2MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAGuKFW765F3D5wax5IFSQbEtr+rVHgjR8jiYTzxOCmbLaU4oj6phOhfQJiTTADQYgCIC/DN0HsAEEqrKkwEn8KdAoNiAWfqCV/eqnK83y7yRDGx6/zfsch+PAzKZouMJLrvR9RYbHq7m3adZv84YLge7FE1JqFk1j6rSa4dUUnGQPrQgr9Sasnz8O8KK45XH6fqKrsd4p485n+BXPDzWVsHl4M5dqQV7qUZTazbzzh4NyP5/RQ6Oh5jqMN7po4qiqWv1pu0EKDxUG6gcECc2cTQwHhIOPeCGdHS7uuI2FlLnHaCUFBgi8zTsZxaeaPuPch5M7Zxbdg0GBhS2SmNi+io=", //nolint:lll | ||
ExtraLines: []string{ | ||
"redirect-gateway", | ||
}, | ||
} | ||
return utils.OpenVPNConfig(providerSettings, connection, settings) | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package slickvpn | ||
|
||
import ( | ||
"math/rand" | ||
"net/http" | ||
|
||
"github.com/qdm12/gluetun/internal/constants/providers" | ||
"github.com/qdm12/gluetun/internal/provider/common" | ||
"github.com/qdm12/gluetun/internal/provider/slickvpn/updater" | ||
"github.com/qdm12/gluetun/internal/provider/utils" | ||
) | ||
|
||
type Provider struct { | ||
storage common.Storage | ||
randSource rand.Source | ||
utils.NoPortForwarder | ||
common.Fetcher | ||
} | ||
|
||
func New(storage common.Storage, randSource rand.Source, | ||
client *http.Client, updaterWarner common.Warner, | ||
parallelResolver common.ParallelResolver) *Provider { | ||
return &Provider{ | ||
storage: storage, | ||
randSource: randSource, | ||
NoPortForwarder: utils.NewNoPortForwarding(providers.SlickVPN), | ||
Fetcher: updater.New(client, updaterWarner, parallelResolver), | ||
} | ||
} | ||
|
||
func (p *Provider) Name() string { | ||
return providers.SlickVPN | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package updater | ||
|
||
import ( | ||
"os" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
"golang.org/x/net/html" | ||
) | ||
|
||
func parseTestHTML(t *testing.T, htmlString string) *html.Node { | ||
t.Helper() | ||
rootNode, err := html.Parse(strings.NewReader(htmlString)) | ||
require.NoError(t, err) | ||
return rootNode | ||
} | ||
|
||
func parseTestDataIndexHTML(t *testing.T) *html.Node { | ||
t.Helper() | ||
|
||
data, err := os.ReadFile("testdata/index.html") | ||
require.NoError(t, err) | ||
|
||
return parseTestHTML(t, string(data)) | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package updater | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/qdm12/gluetun/internal/updater/resolver" | ||
) | ||
|
||
func parallelResolverSettings(hosts []string) (settings resolver.ParallelSettings) { | ||
const ( | ||
maxFailRatio = 0.1 | ||
maxDuration = 20 * time.Second | ||
betweenDuration = time.Second | ||
maxNoNew = 2 | ||
maxFails = 2 | ||
) | ||
return resolver.ParallelSettings{ | ||
Hosts: hosts, | ||
MaxFailRatio: maxFailRatio, | ||
Repeat: resolver.RepeatSettings{ | ||
MaxDuration: maxDuration, | ||
BetweenDuration: betweenDuration, | ||
MaxNoNew: maxNoNew, | ||
MaxFails: maxFails, | ||
SortIPs: true, | ||
}, | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package updater | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"sort" | ||
|
||
"github.com/qdm12/gluetun/internal/constants/vpn" | ||
"github.com/qdm12/gluetun/internal/models" | ||
"github.com/qdm12/gluetun/internal/provider/common" | ||
"github.com/qdm12/gluetun/internal/updater/openvpn" | ||
) | ||
|
||
func (u *Updater) FetchServers(ctx context.Context, minServers int) ( | ||
servers []models.Server, err error) { | ||
hostToData, err := fetchServers(ctx, u.client) | ||
if err != nil { | ||
return nil, fmt.Errorf("fetching and parsing website: %w", err) | ||
} | ||
|
||
openvpnURLs := make([]string, 0, len(hostToData)) | ||
for _, data := range hostToData { | ||
openvpnURLs = append(openvpnURLs, data.ovpnURL) | ||
} | ||
|
||
if len(openvpnURLs) < minServers { | ||
return nil, fmt.Errorf("%w: %d and expected at least %d", | ||
common.ErrNotEnoughServers, len(openvpnURLs), minServers) | ||
} | ||
|
||
const failEarly = false // some URLs from the website are not valid | ||
udpHostToURL, errors := openvpn.FetchMultiFiles(ctx, u.client, openvpnURLs, failEarly) | ||
for _, err := range errors { | ||
u.warner.Warn(fmt.Sprintf("fetching OpenVPN files: %s", err)) | ||
} | ||
|
||
if len(udpHostToURL) < minServers { | ||
return nil, fmt.Errorf("%w: %d and expected at least %d", | ||
common.ErrNotEnoughServers, len(udpHostToURL), minServers) | ||
} | ||
|
||
hosts := make([]string, 0, len(udpHostToURL)) | ||
for host := range udpHostToURL { | ||
hosts = append(hosts, host) | ||
} | ||
|
||
resolveSettings := parallelResolverSettings(hosts) | ||
hostToIPs, warnings, err := u.parallelResolver.Resolve(ctx, resolveSettings) | ||
for _, warning := range warnings { | ||
u.warner.Warn(warning) | ||
} | ||
if err != nil { | ||
return nil, fmt.Errorf("resolving hosts: %w", err) | ||
} | ||
|
||
if len(hostToIPs) < minServers { | ||
return nil, fmt.Errorf("%w: %d and expected at least %d", | ||
common.ErrNotEnoughServers, len(hosts), minServers) | ||
} | ||
|
||
servers = make([]models.Server, 0, len(hostToIPs)) | ||
for host, IPs := range hostToIPs { | ||
_, udp := udpHostToURL[host] | ||
|
||
serverData := hostToData[host] | ||
|
||
server := models.Server{ | ||
VPN: vpn.OpenVPN, | ||
Region: serverData.region, | ||
Country: serverData.country, | ||
City: serverData.city, | ||
Hostname: host, | ||
UDP: udp, | ||
IPs: IPs, | ||
} | ||
servers = append(servers, server) | ||
} | ||
|
||
sort.Sort(models.SortableServers(servers)) | ||
|
||
return servers, nil | ||
} |
Oops, something went wrong.