From eb6325958191acf96037d86503af968497a80199 Mon Sep 17 00:00:00 2001 From: andig Date: Sun, 16 Jun 2024 16:39:55 +0200 Subject: [PATCH] Http: allow template urls (#14413) --- provider/http.go | 28 ++++++------------ provider/http_test.go | 66 +++++++++++++++++++++++++------------------ 2 files changed, 48 insertions(+), 46 deletions(-) diff --git a/provider/http.go b/provider/http.go index 67730251d..6ee6f0eed 100644 --- a/provider/http.go +++ b/provider/http.go @@ -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) diff --git a/provider/http_test.go b/provider/http_test.go index 593d2cbeb..7316c6d7a 100644 --- a/provider/http_test.go +++ b/provider/http_test.go @@ -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()) }