mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
				
	
	
		
			62 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			62 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
	
| 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
 | |
| }
 |