diff --git a/routes.go b/routes.go index 83999a3..4a86c63 100644 --- a/routes.go +++ b/routes.go @@ -99,7 +99,7 @@ func (m *RouteMux) AddRoute(method string, pattern string, handler http.HandlerF if strings.HasPrefix(part, ":") { expr := "([^/]+)" //a user may choose to override the defult expression - // similar to expressjs: ‘/user/:id([0-9]+)’ + // similar to expressjs: ‘/user/:id([0-9]+)’ if index := strings.Index(part, "("); index != -1 { expr = part[index:] part = part[:index] @@ -138,13 +138,24 @@ func (m *RouteMux) Filter(filter http.HandlerFunc) { // FilterParam adds the middleware filter iff the REST URL parameter exists. func (m *RouteMux) FilterParam(param string, filter http.HandlerFunc) { - if !strings.HasPrefix(param,":") { - param = ":"+param + if !strings.HasPrefix(param, ":") { + param = ":" + param } m.Filter(func(w http.ResponseWriter, r *http.Request) { p := r.URL.Query().Get(param) - if len(p) > 0 { filter(w, r) } + if len(p) > 0 { + filter(w, r) + } + }) +} + +// FilterParam adds the middleware filter if the prefix path exists. +func (m *RouteMux) FilterPrefixPath(path string, filter http.HandlerFunc) { + m.Filter(func(w http.ResponseWriter, r *http.Request) { + if strings.HasPrefix(r.URL.Path, path) { + filter(w, r) + } }) } diff --git a/routes_test.go b/routes_test.go index 5af10c1..06ccab4 100644 --- a/routes_test.go +++ b/routes_test.go @@ -32,6 +32,18 @@ var FilterId = func(w http.ResponseWriter, r *http.Request) { } } +var FilterPrefixPath = func(w http.ResponseWriter, r *http.Request) { + token := r.Header.Get("Token") + secret := r.Header.Get("Secret") + + if token == "mytoken" && secret == "mysecret" { + w.WriteHeader(http.StatusOK) + + } else { + http.Error(w, "", http.StatusUnauthorized) + } +} + // TestAuthOk tests that an Auth handler will append the // username and password to to the request URL, and will // continue processing the request by invoking the handler. @@ -148,6 +160,61 @@ func TestFilterParam(t *testing.T) { } +// TestFilterParam tests the ability to apply middleware +// function to filter all routes with specified parameter +// in the REST url +func TestFilterPrefixPath(t *testing.T) { + + r, _ := http.NewRequest("GET", "/someotherprefix", nil) + w := httptest.NewRecorder() + + // first test that the prefix path filter does not trigger + handler := new(RouteMux) + handler.Get("/prefix", HandlerOk) + handler.Get("/prefix/mypath", HandlerOk) //prefix is the base bath + handler.Get("/someotherprefix", HandlerErr) + handler.FilterPrefixPath("/prefix", FilterPrefixPath) + handler.ServeHTTP(w, r) + + if w.Code != http.StatusBadRequest { + t.Errorf("Code set to [%v]; want [%v]", w.Code, http.StatusBadRequest) + } + + // now test the prefix path filter does trigger + r, _ = http.NewRequest("GET", "/prefix", nil) + r.Header.Set("Token", "mytoken") + r.Header.Set("Secret", "mysecret") + w = httptest.NewRecorder() + handler.ServeHTTP(w, r) + + if w.Code != http.StatusOK { + t.Errorf("Did not apply Prefix path Filter. Code set to [%v]; want [%v]", w.Code, http.StatusOK) + } + + // test ok for /prefix as base path + r, _ = http.NewRequest("GET", "/prefix/mypath", nil) + r.Header.Set("Token", "mytoken") + r.Header.Set("Secret", "mysecret") + w = httptest.NewRecorder() + handler.ServeHTTP(w, r) + + if w.Code != http.StatusOK { + t.Errorf("Did not apply Prefix base path Filter. Code set to [%v]; want [%v]", w.Code, http.StatusOK) + } + + //test when secret is incorrect + r, _ = http.NewRequest("GET", "/prefix", nil) + r.Header.Set("Token", "mytoken") + r.Header.Set("Secret", "incorrectsecret") + w = httptest.NewRecorder() + handler.ServeHTTP(w, r) + + if w.Code != http.StatusUnauthorized { + t.Errorf("Did not apply Prefix path Filter. Code set to [%v]; want [%v]", w.Code, http.StatusUnauthorized) + } + +} + // Benchmark_RoutedHandler runs a benchmark against // the RouteMux using the default settings. func Benchmark_RoutedHandler(b *testing.B) {