From 495830acd6976c8a2b39dd4aa4fdc105ad72de52 Mon Sep 17 00:00:00 2001 From: Jonathan Amsterdam Date: Wed, 13 Sep 2023 16:58:24 -0400 Subject: net/http: implement path value methods on Request Add Request.PathValue and Request.SetPathValue, and the fields on Request required to support them. Populate those fields in ServeMux.ServeHTTP. Updates #61410. Change-Id: Ic88cb865b0d865a30d3b35ece8e0382c58ef67d1 Reviewed-on: https://go-review.googlesource.com/c/go/+/528355 Run-TryBot: Jonathan Amsterdam Reviewed-by: Damien Neil TryBot-Result: Gopher Robot --- src/net/http/request_test.go | 90 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) (limited to 'src/net/http/request_test.go') diff --git a/src/net/http/request_test.go b/src/net/http/request_test.go index 5711164894..1aeb93fe14 100644 --- a/src/net/http/request_test.go +++ b/src/net/http/request_test.go @@ -16,6 +16,7 @@ import ( "math" "mime/multipart" . "net/http" + "net/http/httptest" "net/url" "os" "reflect" @@ -1414,3 +1415,92 @@ func TestErrNotSupported(t *testing.T) { t.Error("errors.Is(ErrNotSupported, errors.ErrUnsupported) failed") } } + +func TestPathValueNoMatch(t *testing.T) { + // Check that PathValue and SetPathValue work on a Request that was never matched. + var r Request + if g, w := r.PathValue("x"), ""; g != w { + t.Errorf("got %q, want %q", g, w) + } + r.SetPathValue("x", "a") + if g, w := r.PathValue("x"), "a"; g != w { + t.Errorf("got %q, want %q", g, w) + } +} + +func TestPathValue(t *testing.T) { + for _, test := range []struct { + pattern string + url string + want map[string]string + }{ + { + "/{a}/is/{b}/{c...}", + "/now/is/the/time/for/all", + map[string]string{ + "a": "now", + "b": "the", + "c": "time/for/all", + "d": "", + }, + }, + // TODO(jba): uncomment these tests when we implement path escaping (forthcoming). + // { + // "/names/{name}/{other...}", + // "/names/" + url.PathEscape("/john") + "/address", + // map[string]string{ + // "name": "/john", + // "other": "address", + // }, + // }, + // { + // "/names/{name}/{other...}", + // "/names/" + url.PathEscape("john/doe") + "/address", + // map[string]string{ + // "name": "john/doe", + // "other": "address", + // }, + // }, + } { + mux := NewServeMux() + mux.HandleFunc(test.pattern, func(w ResponseWriter, r *Request) { + for name, want := range test.want { + got := r.PathValue(name) + if got != want { + t.Errorf("%q, %q: got %q, want %q", test.pattern, name, got, want) + } + } + }) + server := httptest.NewServer(mux) + defer server.Close() + _, err := Get(server.URL + test.url) + if err != nil { + t.Fatal(err) + } + } +} + +func TestSetPathValue(t *testing.T) { + mux := NewServeMux() + mux.HandleFunc("/a/{b}/c/{d...}", func(_ ResponseWriter, r *Request) { + kvs := map[string]string{ + "b": "X", + "d": "Y", + "a": "Z", + } + for k, v := range kvs { + r.SetPathValue(k, v) + } + for k, w := range kvs { + if g := r.PathValue(k); g != w { + t.Errorf("got %q, want %q", g, w) + } + } + }) + server := httptest.NewServer(mux) + defer server.Close() + _, err := Get(server.URL + "/a/b/c/d/e") + if err != nil { + t.Fatal(err) + } +} -- cgit v1.3