diff --git a/error.go b/error.go index 09290c0..88e9d4a 100644 --- a/error.go +++ b/error.go @@ -41,7 +41,7 @@ func httpErr(prefix string, err error, r *http.Response, body []byte) *Error { inner: err, Msg: prefix + err.Error(), Status: r.StatusCode, - Headers: uniqueHeaders(r.Header), + Headers: mapFlatten(r.Header), Body: string(body), } } diff --git a/fetch.go b/fetch.go index aec9763..8360976 100644 --- a/fetch.go +++ b/fetch.go @@ -170,7 +170,7 @@ func Do[T any](url string, config ...Config) (T, error) { if isResponseWithEmpty(t) && firstDigit(res.StatusCode) == 2 { re := any(&t).(*Response[Empty]) re.Status = res.StatusCode - re.Headers = uniqueHeaders(res.Header) + re.Headers = mapFlatten(res.Header) return t, nil } @@ -198,7 +198,7 @@ func Do[T any](url string, config ...Config) (T, error) { valueOf := reflect.Indirect(reflect.ValueOf(&t)) valueOf.FieldByName("Status").SetInt(int64(res.StatusCode)) - valueOf.FieldByName("Headers").Set(reflect.ValueOf(uniqueHeaders(res.Header))) + valueOf.FieldByName("Headers").Set(reflect.ValueOf(mapFlatten(res.Header))) valueOf.FieldByName("Body").Set(reflect.ValueOf(resInstance).Elem()) return t, nil diff --git a/to_handler.go b/to_handler.go index 4d51839..415b290 100644 --- a/to_handler.go +++ b/to_handler.go @@ -80,7 +80,8 @@ func ToHandlerFunc[In any, Out any](apply ApplyFunc[In, Out]) http.HandlerFunc { valueOf := reflect.Indirect(reflect.ValueOf(&in)) valueOf.FieldByName("PathValues").Set(reflect.ValueOf(extractPathValues(r))) valueOf.FieldByName("Context").Set(reflect.ValueOf(r.Context())) - valueOf.FieldByName("Headers").Set(reflect.ValueOf(uniqueHeaders(r.Header))) + valueOf.FieldByName("Parameters").Set(reflect.ValueOf(mapFlatten(r.URL.Query()))) + valueOf.FieldByName("Headers").Set(reflect.ValueOf(mapFlatten(r.Header))) valueOf.FieldByName("Body").Set(reflect.ValueOf(resInstance).Elem()) } else if !isEmptyType(in) { err := readAndParseBody(r, &in) diff --git a/to_handler_test.go b/to_handler_test.go index 7f5deb9..c32c755 100644 --- a/to_handler_test.go +++ b/to_handler_test.go @@ -87,6 +87,22 @@ func TestToHandlerFunc_Header(t *testing.T) { assert(t, mw.status, 200) } +func TestToHandlerFunc_UrlParameter(t *testing.T) { + f := ToHandlerFunc(func(in Request[Empty]) (Empty, error) { + if in.Parameters["name"] != "Lola" { + t.Errorf("wrong in %v", in) + } + return Empty{}, nil + }) + mw := newMockWriter() + mux := http.NewServeMux() + mux.HandleFunc("/pets", f) + r, err := http.NewRequest("POST", "/pets?name=Lola", bytes.NewBuffer([]byte(``))) + assert(t, err, nil) + mux.ServeHTTP(mw, r) + assert(t, mw.status, 200) +} + func TestToHandlerFunc_ParseErrors(t *testing.T) { t.Run("Empty Request Body, Struct with fields", func(t *testing.T) { type Pet struct { diff --git a/wrappers.go b/wrappers.go index be9edff..949284e 100644 --- a/wrappers.go +++ b/wrappers.go @@ -29,15 +29,15 @@ type Response[T any] struct { Body T } -func uniqueHeaders(headers map[string][]string) map[string]string { - h := make(map[string]string, len(headers)) - for key, val := range headers { +func mapFlatten(m map[string][]string) map[string]string { + newM := make(map[string]string, len(m)) + for key, val := range m { if len(val) > 0 { // it takes the last element intentionally. - h[key] = val[len(val)-1] + newM[key] = val[len(val)-1] } } - return h + return newM } /* @@ -60,8 +60,11 @@ type Request[T any] struct { // there was no reliable way to extract them. // go1.23 introduced http.Request.Pattern allowing to list the wildcards. PathValues map[string]string - Headers map[string]string - Body T + // URL parameters. + Parameters map[string]string + // HTTP headers. + Headers map[string]string + Body T } // Empty represents an empty response or request body, skipping JSON handling.