diff --git a/README.md b/README.md index eee1da5..bcf8e70 100644 --- a/README.md +++ b/README.md @@ -378,7 +378,7 @@ func handle(c fox.Context) { ## Working with http.Handler Fox itself implements the `http.Handler` interface which make easy to chain any compatible middleware before the router. Moreover, the router -provides convenient `fox.WrapF`, `fox.WrapH` and `fox.WrapM` adapter to be use with `http.Handler`. +provides convenient `fox.WrapF` and `fox.WrapH` adapter to be use with `http.Handler`. The route parameters can be accessed by the wrapped handler through the `context.Context` when the adapters `fox.WrapF` and `fox.WrapH` are used. @@ -393,14 +393,6 @@ f := fox.New(fox.DefaultOptions()) f.MustHandle(http.MethodGet, "/articles/{id}", fox.WrapH(httpRateLimiter.RateLimit(articles))) ``` -Wrapping an `http.Handler` compatible middleware. Please note that `WrapM` is slated for deprecation in a forthcoming release. -````go -f := fox.New(fox.DefaultOptions(), fox.WithMiddleware(fox.WrapM(httpRateLimiter.RateLimit))) -f.MustHandle(http.MethodGet, "/articles/{id}", func(c fox.Context) { - _ = c.String(http.StatusOK, "Article id: %s\n", c.Param("id")) -}) -```` - ### Custom http.ResponseWriter Implementations When using custom `http.ResponseWriter` implementations, it's important to ensure that these implementations expose the required http interfaces. For HTTP/1.x requests, Fox expects the `http.ResponseWriter` to implement the `http.Flusher`, diff --git a/context.go b/context.go index 98b920c..fc1d143 100644 --- a/context.go +++ b/context.go @@ -391,19 +391,3 @@ func WrapH(h http.Handler) HandlerFunc { h.ServeHTTP(c.Writer(), c.Request()) } } - -// WrapM is an adapter for converting http.Handler middleware into a MiddlewareFunc. It does not work with middleware -// that wrap custom http.ResponseWriter (e.g. gzip). -// This API is EXPERIMENTAL and is likely to change in future release. -// Deprecated: WrapM is planned to be removed in v1.0.0. -func WrapM(m func(handler http.Handler) http.Handler) MiddlewareFunc { - return func(next HandlerFunc) HandlerFunc { - return func(c Context) { - adapter := m(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - c.SetRequest(r) - next(c) - })) - adapter.ServeHTTP(c.Writer(), c.Request()) - } - } -} diff --git a/context_test.go b/context_test.go index 8cb2b3a..b619f53 100644 --- a/context_test.go +++ b/context_test.go @@ -701,73 +701,6 @@ func TestWrapH(t *testing.T) { } } -func TestWrapM(t *testing.T) { - t.Parallel() - - wantSize := func(size int) func(next HandlerFunc) HandlerFunc { - return func(next HandlerFunc) HandlerFunc { - return func(c Context) { - next(c) - assert.Equal(t, size, c.Writer().Size()) - } - } - } - - cases := []struct { - name string - m MiddlewareFunc - wantStatus int - wantBody string - wantSize int - }{ - { - name: "using fox writer", - m: WrapM(func(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - req := r.Clone(r.Context()) - req.Header.Set("foo", "bar") - next.ServeHTTP(w, req) - }) - }), - wantStatus: http.StatusCreated, - wantBody: "foo bar", - wantSize: 7, - }, - { - name: "using fox writer without calling next", - m: WrapM(func(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - req := r.Clone(r.Context()) - req.Header.Set("foo", "bar") - w.WriteHeader(http.StatusUnauthorized) - _, _ = w.Write([]byte(http.StatusText(http.StatusUnauthorized))) - }) - }), - wantStatus: http.StatusUnauthorized, - wantBody: http.StatusText(http.StatusUnauthorized), - wantSize: 12, - }, - } - - for _, tc := range cases { - tc := tc - t.Run(tc.name, func(t *testing.T) { - t.Parallel() - f := New(WithMiddleware(wantSize(tc.wantSize), tc.m)) - require.NoError(t, f.Handle(http.MethodGet, "/foo", func(c Context) { - assert.Equal(t, "bar", c.Header("foo")) - _ = c.String(http.StatusCreated, "foo bar") - })) - - w := httptest.NewRecorder() - r := httptest.NewRequest(http.MethodGet, "/foo", nil) - f.ServeHTTP(w, r) - assert.Equal(t, tc.wantStatus, w.Code) - assert.Equal(t, tc.wantBody, w.Body.String()) - }) - } -} - // This example demonstrates how to capture the HTTP response body by using the TeeWriter method. // The TeeWriter method attaches the provided io.Writer (in this case a bytes.Buffer) to the existing ResponseWriter. // Unlike a typical io.MultiWriter, this implementation is designed to ensure that the ResponseWriter remains compatible @@ -789,23 +722,3 @@ func ExampleContext_TeeWriter() { _ = c.String(http.StatusOK, "Hello %s\n", c.Param("name")) }) } - -// This example demonstrates the usage of the WrapM function which is used to wrap an http.Handler middleware -// and returns a MiddlewareFunc function compatible with Fox. -func ExampleWrapM() { - authorizationMiddleware := func(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - token := r.Header.Get("Authorization") - if token != "valid-token" { - http.Error(w, "Invalid token", http.StatusUnauthorized) - return - } - next.ServeHTTP(w, r) - }) - } - - f := New(WithMiddleware(WrapM(authorizationMiddleware))) - f.MustHandle(http.MethodGet, "/foo", func(c Context) { - _ = c.String(http.StatusOK, "Authorized\n") - }) -}