Skip to content

Commit

Permalink
feat: remove WrapM adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
tigerwill90 committed Jan 24, 2024
1 parent 8914742 commit d751a4f
Show file tree
Hide file tree
Showing 3 changed files with 1 addition and 112 deletions.
10 changes: 1 addition & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand All @@ -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`,
Expand Down
16 changes: 0 additions & 16 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
}
}
87 changes: 0 additions & 87 deletions context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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")
})
}

0 comments on commit d751a4f

Please sign in to comment.