Skip to content

Commit

Permalink
Fix eval.toSlice() (#805)
Browse files Browse the repository at this point in the history
* added tests for use of toSlice() with various HCL attributes

* added bool values handling in to stringification in toSlice()

* added changelog entry

---------

Co-authored-by: Marcel Ludwig <marcel.ludwig@milecrew.com>
  • Loading branch information
johakoch and malud authored Apr 8, 2024
1 parent 67c84c6 commit 4cbe626
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Unreleased changes are available as `coupergateway/couper:edge` container.
* [`Server-Timing` header](https://docs.couper.io/configuration/block/settings) only reporting last requests/proxies of [endpoint sequences](https://docs.couper.io/configuration/block/endpoint#endpoint-sequence) ([#751](https://github.com/coupergateway/couper/pull/751))
* Selecting of appropriate [error handler](https://docs.couper.io/configuration/block/error_handler) in two cases ([#753](https://github.com/coupergateway/couper/pull/753))
* Storing of digit-starting string object keys in [request context](https://docs.couper.io/configuration/variables#request) and of digit-starting string header field names in [request](https://docs.couper.io/configuration/variables#request) variable ([#799](https://github.com/coupergateway/couper/pull/799))
* Use of boolean values for the `headers` attribute or [modifiers](https://docs.couper.io/configuration/modifiers) ([#805](https://github.com/coupergateway/couper/pull/805))

* **Dependencies**
* build with go 1.21 ([#800](https://github.com/coupergateway/couper/pull/800))
Expand Down
2 changes: 2 additions & 0 deletions eval/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,8 @@ func deleteHeader(val cty.Value, headerCtx http.Header) {

func toSlice(val interface{}) []string {
switch v := val.(type) {
case bool:
return []string{strconv.FormatBool(v)}
case float64:
return []string{strconv.FormatFloat(v, 'f', 0, 64)}
case string:
Expand Down
3 changes: 2 additions & 1 deletion internal/test/test_backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func registerHTTPHandler(b *Backend) {
func createAnythingHandler(status int) func(rw http.ResponseWriter, req *http.Request) {
return func(rw http.ResponseWriter, req *http.Request) {
type anything struct {
Args, Query url.Values
Args, Query, PostForm url.Values
Body string
Headers http.Header
Host string
Expand All @@ -113,6 +113,7 @@ func createAnythingHandler(status int) func(rw http.ResponseWriter, req *http.Re
Host: req.Host,
Method: req.Method,
Path: req.URL.Path,
PostForm: req.PostForm,
Query: req.URL.Query(),
RawQuery: req.URL.RawQuery,
RemoteAddr: req.RemoteAddr,
Expand Down
94 changes: 94 additions & 0 deletions server/http_endpoints_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1245,3 +1245,97 @@ func TestEndpointWildcardProxyPathWildcard(t *testing.T) {
})
}
}

func Test_toSlice1(t *testing.T) {
shutdown, _ := newCouper("testdata/endpoints/22_couper.hcl", test.New(t))
defer shutdown()

expected := map[string][]string{
"B": {"true"},
"B2": {"false"},
"Ba": {"", ""}, // TODO fix: "true", "false"
"Ba2": {"", ""}, // TODO fix: "false", "true"
"N": {"1"},
"N2": {"2"},
"Na": {"1", "2"},
"Na2": {"3", "4"},
"S": {"str"},
"S2": {"asdf"},
"Sa": {"s1", "s2"},
"Sa2": {"s3", "s4"},
}
helper := test.New(t)
res, err := http.PostForm("http://localhost:8080/1", url.Values{})
helper.Must(err)

if res.StatusCode != http.StatusOK {
t.Errorf("Unexpected status: want: 200, got %d", res.StatusCode)
}

b, err := io.ReadAll(res.Body)
helper.Must(res.Body.Close())
helper.Must(err)

type result struct {
PostForm, Query, Headers map[string][]string
}
r := result{}
helper.Must(json.Unmarshal(b, &r))
if diff := cmp.Diff(r.Query, expected); diff != "" {
t.Error(diff)
}
if diff := cmp.Diff(r.PostForm, expected); diff != "" {
t.Error(diff)
}
for k, v := range expected {
if diff := cmp.Diff(r.Headers[k], v); diff != "" {
t.Error(diff)
}
}
for k, v := range expected {
if diff := cmp.Diff(res.Header[k], v); diff != "" {
t.Error(diff)
}
}
}

func Test_toSlice2(t *testing.T) {
shutdown, _ := newCouper("testdata/endpoints/22_couper.hcl", test.New(t))
defer shutdown()

expected := map[string][]string{
"B": {"true"},
"Ba": {"", ""}, // TODO fix: "true", "false"
"N": {"1"},
"Na": {"1", "2"},
"S": {"str"},
"Sa": {"s1", "s2"},
}
helper := test.New(t)
res, err := http.Get("http://localhost:8080/2")
helper.Must(err)

if res.StatusCode != http.StatusOK {
t.Errorf("Unexpected status: want: 200, got %d", res.StatusCode)
}

b, err := io.ReadAll(res.Body)
helper.Must(res.Body.Close())
helper.Must(err)

type result struct {
Headers map[string][]string
}
r := result{}
helper.Must(json.Unmarshal(b, &r))
for k, v := range expected {
if diff := cmp.Diff(r.Headers[k], v); diff != "" {
t.Error(diff)
}
}
for k, v := range expected {
if diff := cmp.Diff(res.Header[k], v); diff != "" {
t.Error(diff)
}
}
}
2 changes: 1 addition & 1 deletion server/http_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4250,7 +4250,7 @@ func TestFunctions(t *testing.T) {
"X-Default-9": "",
"X-Default-10": "",
"X-Default-11": "0",
"X-Default-12": "",
"X-Default-12": "false",
"X-Default-13": `{"a":1}`,
"X-Default-14": `{"a":1}`,
"X-Default-15": `[1,2]`,
Expand Down
106 changes: 106 additions & 0 deletions server/testdata/endpoints/22_couper.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
server "cl" {
api {
endpoint "/1" {
proxy {
backend = "be"
}
set_query_params = {
B = true
N = 1
S = "str"
Ba = [true, false]
Na = [1, 2]
Sa = ["s1", "s2"]
}
add_query_params = {
B2 = false
N2 = 2
S2 = "asdf"
Ba2 = [false, true]
Na2 = [3, 4]
Sa2 = ["s3", "s4"]
}
set_form_params = {
B = true
N = 1
S = "str"
Ba = [true, false]
Na = [1, 2]
Sa = ["s1", "s2"]
}
add_form_params = {
B2 = false
N2 = 2
S2 = "asdf"
Ba2 = [false, true]
Na2 = [3, 4]
Sa2 = ["s3", "s4"]
}
set_request_headers = {
B = true
N = 1
S = "str"
Ba = [true, false]
Na = [1, 2]
Sa = ["s1", "s2"]
}
add_request_headers = {
B2 = false
N2 = 2
S2 = "asdf"
Ba2 = [false, true]
Na2 = [3, 4]
Sa2 = ["s3", "s4"]
}
set_response_headers = {
B = true
N = 1
S = "str"
Ba = [true, false]
Na = [1, 2]
Sa = ["s1", "s2"]
}
add_response_headers = {
B2 = false
N2 = 2
S2 = "asdf"
Ba2 = [false, true]
Na2 = [3, 4]
Sa2 = ["s3", "s4"]
}
}

endpoint "/2" {
request {
url = "/anything"
backend = "be"
headers = {
B = true
N = 1
S = "str"
Ba = [true, false]
Na = [1, 2]
Sa = ["s1", "s2"]
}
}
response {
headers = {
B = true
N = 1
S = "str"
Ba = [true, false]
Na = [1, 2]
Sa = ["s1", "s2"]
}
body = backend_responses.default.body
}
}
}
}

definitions {
backend "be" {
origin = "${env.COUPER_TEST_BACKEND_ADDR}"
path = "/anything"
}
}

0 comments on commit 4cbe626

Please sign in to comment.