Data sources: Don't fail if URL doesn't specify protocol (#24497)

This commit is contained in:
Arve Knudsen
2020-05-12 13:04:18 +02:00
committed by GitHub
parent 0475f96347
commit 164242f5fd
7 changed files with 193 additions and 25 deletions

View File

@ -0,0 +1,50 @@
package datasource
import (
"fmt"
"net/url"
"regexp"
"github.com/grafana/grafana/pkg/infra/log"
)
var logger = log.New("datasource")
// URLValidationError represents an error from validating a data source URL.
type URLValidationError struct {
error
url string
}
// Error returns the error message.
func (e URLValidationError) Error() string {
return fmt.Sprintf("Validation of data source URL %q failed: %s", e.url, e.error.Error())
}
// Unwrap returns the wrapped error.
func (e URLValidationError) Unwrap() error {
return e.error
}
// reURL is a regexp to detect if a URL specifies the protocol. We match also strings where the actual protocol is
// missing (i.e., "://"), in order to catch these as invalid when parsing.
var reURL = regexp.MustCompile("^[^:]*://")
// ValidateURL validates a data source URL.
//
// If successful, the valid URL object is returned, otherwise an error is returned.
func ValidateURL(urlStr string) (*url.URL, error) {
// Make sure the URL starts with a protocol specifier, so parsing is unambiguous
if !reURL.MatchString(urlStr) {
logger.Debug(
"Data source URL doesn't specify protocol, so prepending it with http:// in order to make it unambiguous")
urlStr = fmt.Sprintf("http://%s", urlStr)
}
u, err := url.Parse(urlStr)
if err != nil {
return nil, URLValidationError{error: err, url: urlStr}
}
return u, nil
}