From 47e31837aabfe0f9766fb85c1070fb33e837cfa8 Mon Sep 17 00:00:00 2001 From: Simon Guest Date: Fri, 8 Jan 2016 15:59:32 +1300 Subject: [PATCH] Added urlquery middleware, resolves #174. --- web/middleware/urlquery.go | 24 +++++++++++++++ web/middleware/urlquery_test.go | 53 +++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 web/middleware/urlquery.go create mode 100644 web/middleware/urlquery_test.go diff --git a/web/middleware/urlquery.go b/web/middleware/urlquery.go new file mode 100644 index 0000000..3738544 --- /dev/null +++ b/web/middleware/urlquery.go @@ -0,0 +1,24 @@ +package middleware + +import ( + "github.com/zenazn/goji/web" + "net/http" +) + +// UrlQueryKey is the context key for the URL Query +const UrlQueryKey string = "urlquery" + +// UrlQuery is a middleware to parse the URL Query parameters just once, +// and store the resulting url.Values in the context. +func UrlQuery(c *web.C, h http.Handler) http.Handler { + fn := func(w http.ResponseWriter, r *http.Request) { + if c.Env == nil { + c.Env = make(map[interface{}]interface{}) + } + c.Env[UrlQueryKey] = r.URL.Query() + + h.ServeHTTP(w, r) + } + + return http.HandlerFunc(fn) +} diff --git a/web/middleware/urlquery_test.go b/web/middleware/urlquery_test.go new file mode 100644 index 0000000..2364191 --- /dev/null +++ b/web/middleware/urlquery_test.go @@ -0,0 +1,53 @@ +package middleware + +import ( + "net/http" + "net/http/httptest" + "net/url" + "reflect" + "testing" + + "github.com/zenazn/goji/web" +) + +func testUrlQuery(r *http.Request, f func(*web.C, http.ResponseWriter, *http.Request)) *httptest.ResponseRecorder { + var c web.C + + h := func(w http.ResponseWriter, r *http.Request) { + f(&c, w, r) + } + m := UrlQuery(&c, http.HandlerFunc(h)) + w := httptest.NewRecorder() + m.ServeHTTP(w, r) + + return w +} + +func TestUrlQuery(t *testing.T) { + type testcase struct { + url string + expectedParams url.Values + } + + // we're not testing url.Query() here, but rather that the results of the query + // appear in the context + testcases := []testcase{ + testcase{"/", url.Values{}}, + testcase{"/?a=1&b=2&a=3", url.Values{"a": []string{"1", "3"}, "b": []string{"2"}}}, + testcase{"/?x=1&y=2&z=3#freddyishere", url.Values{"x": []string{"1"}, "y": []string{"2"}, "z": []string{"3"}}}, + } + + for _, tc := range testcases { + r, _ := http.NewRequest("GET", tc.url, nil) + testUrlQuery(r, + func(c *web.C, w http.ResponseWriter, r *http.Request) { + params := c.Env[UrlQueryKey].(url.Values) + if !reflect.DeepEqual(params, tc.expectedParams) { + t.Errorf("GET %s, UrlQuery middleware found %v, should be %v", tc.url, params, tc.expectedParams) + } + + w.Write([]byte{'h', 'i'}) + }, + ) + } +}