fix(urllib): fix rejection of valid proxy URLs in feeds
When attempting to set a proxy in a feed, due to a regression caused by 4cd9dd6af7
the form validation would now only accept HTTP(S) proxies, and reject SOCKS proxies, despite this being
a valid configuration before. Adding a new function to validate proxy URLs separates the concerns
and allows using a SOCKS proxy url again.
This commit is contained in:
@@ -57,7 +57,7 @@ func (s *SubscriptionForm) Validate() *locale.LocalizedError {
|
||||
return locale.NewLocalizedError("error.feed_invalid_urlrewrite_rule")
|
||||
}
|
||||
|
||||
if s.ProxyURL != "" && !urllib.IsAbsoluteURL(s.ProxyURL) {
|
||||
if s.ProxyURL != "" && !urllib.IsValidProxyURL(s.ProxyURL) {
|
||||
return locale.NewLocalizedError("error.invalid_feed_proxy_url")
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,11 @@ func hasHTTPPrefix(inputURL string) bool {
|
||||
return strings.HasPrefix(inputURL, "https://") || strings.HasPrefix(inputURL, "http://")
|
||||
}
|
||||
|
||||
// hasSOCKSPrefix reports whether the URL string begins with an SOCKS5 or SOCKS5H scheme.
|
||||
func hasSOCKSPrefix(inputURL string) bool {
|
||||
return strings.HasPrefix(inputURL, "socks5://") || strings.HasPrefix(inputURL, "socks5h://")
|
||||
}
|
||||
|
||||
// IsAbsoluteURL reports whether the link is absolute and starts with an HTTP or HTTPS scheme.
|
||||
func IsAbsoluteURL(inputURL string) bool {
|
||||
if !hasHTTPPrefix(inputURL) {
|
||||
@@ -55,6 +60,18 @@ func IsAbsoluteURL(inputURL string) bool {
|
||||
return parsedURL.IsAbs()
|
||||
}
|
||||
|
||||
// IsValidProxyURL reports whether the url is absolute, has a host and starts with an HTTP, HTTPS, SOCKS5 or SOCKS5H scheme.
|
||||
func IsValidProxyURL(inputURL string) bool {
|
||||
if !hasHTTPPrefix(inputURL) && !hasSOCKSPrefix(inputURL) {
|
||||
return false
|
||||
}
|
||||
parsedURL, err := url.Parse(inputURL)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return parsedURL.IsAbs() && parsedURL.Host != ""
|
||||
}
|
||||
|
||||
// resolveToAbsoluteURL resolves a relative URL using a base URL, parsing the base only if needed.
|
||||
func resolveToAbsoluteURL(parsedBaseURL *url.URL, baseURL, relativeURL string) (string, error) {
|
||||
// Avoid parsing the relative URL if it's already absolute
|
||||
|
||||
@@ -68,6 +68,34 @@ func TestIsAbsoluteURL(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValidProxyURL(t *testing.T) {
|
||||
scenarios := map[string]bool{
|
||||
"http://127.0.0.1:3128": true,
|
||||
"http://[::1]:1055": true,
|
||||
"https://proxy.example.org": true,
|
||||
"socks5://127.0.0.1:1080": true,
|
||||
"socks5h://127.0.0.1:1080": true,
|
||||
"socks5://[::1]:1055": true,
|
||||
"socks5h://[::1]:1055": true,
|
||||
"socks5://[::1%25eno1]:1055": true,
|
||||
"ftp://host": false,
|
||||
"/relative/path": false,
|
||||
"invalid url": false,
|
||||
"http://[::1": false,
|
||||
"http:///var/run/socket": false,
|
||||
"sock:///socket.file": false,
|
||||
"socks5://[::1%eno1]:1055": false,
|
||||
"": false,
|
||||
}
|
||||
|
||||
for input, expected := range scenarios {
|
||||
actual := IsValidProxyURL(input)
|
||||
if actual != expected {
|
||||
t.Errorf(`Unexpected result, got %v instead of %v for %q`, actual, expected, input)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAbsoluteURL(t *testing.T) {
|
||||
type absoluteScenario struct {
|
||||
name string
|
||||
|
||||
@@ -48,7 +48,7 @@ func ValidateFeedCreation(store *storage.Storage, userID int64, request *model.F
|
||||
}
|
||||
}
|
||||
|
||||
if request.ProxyURL != "" && !urllib.IsAbsoluteURL(request.ProxyURL) {
|
||||
if request.ProxyURL != "" && !urllib.IsValidProxyURL(request.ProxyURL) {
|
||||
return locale.NewLocalizedError("error.invalid_feed_proxy_url")
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ func ValidateFeedModification(store *storage.Storage, userID, feedID int64, requ
|
||||
return locale.NewLocalizedError("error.proxy_url_not_empty")
|
||||
}
|
||||
|
||||
if !urllib.IsAbsoluteURL(*request.ProxyURL) {
|
||||
if !urllib.IsValidProxyURL(*request.ProxyURL) {
|
||||
return locale.NewLocalizedError("error.invalid_feed_proxy_url")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ func ValidateSubscriptionDiscovery(request *model.SubscriptionDiscoveryRequest)
|
||||
return locale.NewLocalizedError("error.invalid_site_url")
|
||||
}
|
||||
|
||||
if request.ProxyURL != "" && !urllib.IsAbsoluteURL(request.ProxyURL) {
|
||||
if request.ProxyURL != "" && !urllib.IsValidProxyURL(request.ProxyURL) {
|
||||
return locale.NewLocalizedError("error.invalid_proxy_url")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user