Http: allow template urls (#14413)

This commit is contained in:
andig 2024-06-16 16:39:55 +02:00 • committed by GitHub
parent 925e510bc7
commit eb63259581
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 48 additions and 46 deletions

View file

@ -7,14 +7,12 @@ import (
"net/http"
"strconv"
"strings"
"text/template"
"time"
"github.com/evcc-io/evcc/provider/pipeline"
"github.com/evcc-io/evcc/util"
"github.com/evcc-io/evcc/util/request"
"github.com/evcc-io/evcc/util/transport"
"github.com/go-sprout/sprout"
"github.com/gregjones/httpcache"
"github.com/jpfielding/go-http-digest/pkg/digest"
)
@ -95,14 +93,9 @@ func NewHTTPProviderFromConfig(other map[string]interface{}) (Provider, error) {
// NewHTTP create HTTP provider
func NewHTTP(log *util.Logger, method, uri string, insecure bool, scale float64, cache time.Duration) *HTTP {
url := util.DefaultScheme(uri, "http")
if strings.HasPrefix(url, "http") && !strings.HasPrefix(uri, "http") {
log.WARN.Printf("missing scheme for %s, assuming http", uri)
}
p := &HTTP{
Helper: request.NewHelper(log),
url: url,
url: uri,
method: method,
scale: scale,
cache: cache,
@ -166,18 +159,10 @@ func (p *HTTP) request(url string, body string) ([]byte, error) {
b = strings.NewReader(body)
}
tmpl, err := template.New("url").Funcs(sprout.TxtFuncMap()).Parse(url)
if err != nil {
return nil, err
}
builder := new(strings.Builder)
if err := tmpl.Execute(builder, nil); err != nil {
return nil, err
}
url := util.DefaultScheme(url, "http")
// empty method becomes GET
req, err := request.New(p.method, builder.String(), b, p.headers)
req, err := request.New(p.method, url, b, p.headers)
if err != nil {
return []byte{}, err
}
@ -194,7 +179,12 @@ var _ StringProvider = (*HTTP)(nil)
// StringGetter sends string request
func (p *HTTP) StringGetter() (func() (string, error), error) {
return func() (string, error) {
b, err := p.request(p.url, p.body)
url, err := setFormattedValue(p.url, "", "")
if err != nil {
return "", err
}
b, err := p.request(url, p.body)
if err == nil && p.pipeline != nil {
b, err = p.pipeline.Process(b)

View file

@ -3,13 +3,11 @@ package provider
import (
"net/http"
"net/http/httptest"
"net/url"
"testing"
"github.com/evcc-io/evcc/util"
"github.com/samber/lo"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)
type httpHandler struct {
@ -23,40 +21,54 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
_, _ = w.Write([]byte(h.val))
}
func TestHttpGet(t *testing.T) {
h := new(httpHandler)
srv := httptest.NewServer(h)
defer srv.Close()
func TestHttp(t *testing.T) {
suite.Run(t, new(httpTestSuite))
}
uri := srv.URL + "/foo/bar"
type httpTestSuite struct {
suite.Suite
h *httpHandler
srv *httptest.Server
}
func (suite *httpTestSuite) SetupSuite() {
suite.h = new(httpHandler)
suite.srv = httptest.NewServer(suite.h)
}
func (suite *httpTestSuite) TearDown() {
suite.srv.Close()
}
func (suite *httpTestSuite) TestGet() {
uri := suite.srv.URL + "/foo/bar{{\"/baz\"}}"
p := NewHTTP(util.NewLogger("foo"), http.MethodGet, uri, false, 1, 0)
uriUrl, _ := url.Parse(uri)
g, err := p.StringGetter()
require.NoError(t, err)
suite.Require().NoError(err)
res, err := g()
require.NoError(t, err)
assert.Equal(t, uriUrl.Path, h.req.URL.Path)
assert.Equal(t, h.val, res)
suite.Require().NoError(err)
suite.Require().Equal("/foo/bar/baz", suite.h.req.URL.String())
suite.Require().Equal(suite.h.val, res)
}
func TestHttpSet(t *testing.T) {
h := new(httpHandler)
srv := httptest.NewServer(h)
defer srv.Close()
uri := srv.URL + "/foo/bar?baz={{.baz}}"
func (suite *httpTestSuite) TestSetQuery() {
uri := suite.srv.URL + "/foo/bar?baz={{.baz}}"
p := NewHTTP(util.NewLogger("foo"), http.MethodGet, uri, false, 1, 0)
uriUrl, _ := url.Parse(uri)
s, err := p.StringSetter("baz")
suite.Require().NoError(err)
suite.Require().NoError(s("4711"))
suite.Require().Equal("/foo/bar?baz=4711", suite.h.req.URL.String())
}
func (suite *httpTestSuite) TestSetPath() {
uri := suite.srv.URL + "/foo/bar/{{.baz}}"
p := NewHTTP(util.NewLogger("foo"), http.MethodGet, uri, false, 1, 0)
s, err := p.StringSetter("baz")
require.NoError(t, err)
err = s("4711")
require.NoError(t, err)
assert.Equal(t, uriUrl.Path, h.req.URL.Path)
assert.Equal(t, "baz=4711", h.req.URL.RawQuery)
suite.Require().NoError(err)
suite.Require().NoError(s("4711"))
suite.Require().Equal("/foo/bar/4711", suite.h.req.URL.String())
}