The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/pkg/plugins/pluginscdn/url_constructor.go

61 lines
1.6 KiB

package pluginscdn
import (
"fmt"
"net/url"
"path"
"strings"
)
// URLConstructor is a struct that can build CDN URLs for plugins on a remote CDN.
type URLConstructor struct {
// cdnURLTemplate is absolute base url of the CDN. This string will be formatted
// according to the rules specified in the Path method.
cdnURLTemplate string
// pluginID is the ID of the plugin.
pluginID string
// pluginVersion is the version of the plugin.
pluginVersion string
}
// Path returns a new *url.URL that points to an asset file for the CDN, plugin and plugin version
// specified by the current URLConstructor.
//
// c.cdnURLTemplate is used to build the string, the following substitutions are performed in it:
//
// - {id} -> plugin id
//
// - {version} -> plugin version
//
// - {assetPath} -> assetPath
//
// The asset Path is sanitized via path.Clean (double slashes are removed, "../" is resolved, etc).
//
// The returned URL will be for a file, so it won't have a trailing slash.
func (c URLConstructor) Path(assetPath string) (*url.URL, error) {
u, err := url.Parse(
strings.TrimRight(
strings.NewReplacer(
"{id}", c.pluginID,
"{version}", c.pluginVersion,
"{assetPath}", strings.Trim(path.Clean("/"+assetPath+"/"), "/"),
).Replace(c.cdnURLTemplate),
"/",
),
)
if err != nil {
return nil, fmt.Errorf("url parse: %w", err)
}
return u, nil
}
// StringPath is like Path, but it returns the absolute URL as a string rather than *url.URL.
func (c URLConstructor) StringPath(assetPath string) (string, error) {
u, err := c.Path(assetPath)
if err != nil {
return "", err
}
return u.String(), nil
}