mirror of
https://github.com/grafana/grafana.git
synced 2024-12-02 13:39:19 -06:00
062d255124
* replace ioutil.ReadFile -> os.ReadFile * replace ioutil.ReadAll -> io.ReadAll * replace ioutil.TempFile -> os.CreateTemp * replace ioutil.NopCloser -> io.NopCloser * replace ioutil.WriteFile -> os.WriteFile * replace ioutil.TempDir -> os.MkdirTemp * replace ioutil.Discard -> io.Discard
111 lines
2.3 KiB
Go
111 lines
2.3 KiB
Go
package imguploader
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"net"
|
|
"net/http"
|
|
"net/url"
|
|
"os"
|
|
"path"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/grafana/grafana/pkg/util"
|
|
)
|
|
|
|
type WebdavUploader struct {
|
|
url string
|
|
username string
|
|
password string
|
|
public_url string
|
|
}
|
|
|
|
var netTransport = &http.Transport{
|
|
Proxy: http.ProxyFromEnvironment,
|
|
Dial: (&net.Dialer{
|
|
Timeout: 60 * time.Second,
|
|
}).Dial,
|
|
TLSHandshakeTimeout: 5 * time.Second,
|
|
}
|
|
|
|
var netClient = &http.Client{
|
|
Timeout: time.Second * 60,
|
|
Transport: netTransport,
|
|
}
|
|
|
|
func (u *WebdavUploader) PublicURL(filename string) string {
|
|
if strings.Contains(u.public_url, "${file}") {
|
|
return strings.ReplaceAll(u.public_url, "${file}", filename)
|
|
}
|
|
|
|
publicURL, _ := url.Parse(u.public_url)
|
|
publicURL.Path = path.Join(publicURL.Path, filename)
|
|
return publicURL.String()
|
|
}
|
|
|
|
func (u *WebdavUploader) Upload(ctx context.Context, imgToUpload string) (string, error) {
|
|
url, _ := url.Parse(u.url)
|
|
filename, err := util.GetRandomString(20)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
filename += pngExt
|
|
url.Path = path.Join(url.Path, filename)
|
|
|
|
// We can ignore the gosec G304 warning on this one because `imgToUpload` comes
|
|
// from alert notifiers and is only used to upload images generated by alerting.
|
|
// nolint:gosec
|
|
imgData, err := os.ReadFile(imgToUpload)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
req, err := http.NewRequest("PUT", url.String(), bytes.NewReader(imgData))
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if ctx != nil {
|
|
req = req.WithContext(ctx)
|
|
}
|
|
if u.username != "" {
|
|
req.SetBasicAuth(u.username, u.password)
|
|
}
|
|
|
|
res, err := netClient.Do(req)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer func() {
|
|
if err := res.Body.Close(); err != nil {
|
|
logger.Warn("Failed to close response body", "err", err)
|
|
}
|
|
}()
|
|
|
|
if res.StatusCode != http.StatusCreated {
|
|
body, err := io.ReadAll(res.Body)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to read response body: %w", err)
|
|
}
|
|
return "", fmt.Errorf("failed to upload image, statuscode: %d, body: %s", res.StatusCode, body)
|
|
}
|
|
|
|
if u.public_url != "" {
|
|
return u.PublicURL(filename), nil
|
|
}
|
|
|
|
return url.String(), nil
|
|
}
|
|
|
|
func NewWebdavImageUploader(url, username, password, public_url string) (*WebdavUploader, error) {
|
|
return &WebdavUploader{
|
|
url: url,
|
|
username: username,
|
|
password: password,
|
|
public_url: public_url,
|
|
}, nil
|
|
}
|