Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix eval.toSlice() #805

Merged
merged 4 commits into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
}
}
Loading