Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: go-chi/chi
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v3.1.2
Choose a base ref
...
head repository: go-chi/chi
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v3.1.3
Choose a head ref
  • 3 commits
  • 3 files changed
  • 2 contributors

Commits on Jul 24, 2017

  1. Update basicWriter.bytes with ReadFrom result (#234)

    mrbanzai authored and Peter Kieltyka committed Jul 24, 2017
    Copy the full SHA
    54701e3 View commit details

Commits on Jul 25, 2017

  1. Fix WrapWriter.ReadFrom() with Tee (#235)

    VojtechVitek authored and Peter Kieltyka committed Jul 25, 2017
    Copy the full SHA
    2f33244 View commit details
  2. Implement router tree Walker, an analogy to filepath.Walk (#222)

    * Implement router tree Walker, an analogy to filepath.Walk
    
    func Walk(r Routes, walkFn WalkFunc) error
    type WalkFunc func(method string, route string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) error
    
    * Move Walker to tree.go
    VojtechVitek authored and Peter Kieltyka committed Jul 25, 2017

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    524a020 View commit details
Showing with 63 additions and 2 deletions.
  1. +6 −2 middleware/wrap_writer.go
  2. +44 −0 tree.go
  3. +13 −0 tree_test.go
8 changes: 6 additions & 2 deletions middleware/wrap_writer.go
Original file line number Diff line number Diff line change
@@ -111,11 +111,15 @@ func (f *httpFancyWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
}
func (f *httpFancyWriter) ReadFrom(r io.Reader) (int64, error) {
if f.basicWriter.tee != nil {
return io.Copy(&f.basicWriter, r)
n, err := io.Copy(&f.basicWriter, r)
f.basicWriter.bytes += int(n)
return n, err
}
rf := f.basicWriter.ResponseWriter.(io.ReaderFrom)
f.basicWriter.maybeWriteHeader()
return rf.ReadFrom(r)
n, err := rf.ReadFrom(r)
f.basicWriter.bytes += int(n)
return n, err
}

var _ http.CloseNotifier = &httpFancyWriter{}
44 changes: 44 additions & 0 deletions tree.go
Original file line number Diff line number Diff line change
@@ -760,3 +760,47 @@ type Route struct {
Handlers map[string]http.Handler
SubRoutes Routes
}

// WalkFunc is the type of the function called for each method and route visited by Walk.
type WalkFunc func(method string, route string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) error

// Walk walks any router tree that implements Routes interface.
func Walk(r Routes, walkFn WalkFunc) error {
return walk(r, walkFn, "")
}

func walk(r Routes, walkFn WalkFunc, parentRoute string, parentMw ...func(http.Handler) http.Handler) error {
for _, route := range r.Routes() {
mws := make([]func(http.Handler) http.Handler, len(parentMw))
copy(mws, parentMw)
mws = append(mws, r.Middlewares()...)

if route.SubRoutes != nil {
if err := walk(route.SubRoutes, walkFn, parentRoute+route.Pattern, mws...); err != nil {
return err
}
continue
}

for method, handler := range route.Handlers {
if method == "*" {
// Ignore a "catchAll" method, since we pass down all the specific methods for each route.
continue
}

fullRoute := parentRoute + route.Pattern

if chain, ok := handler.(*ChainHandler); ok {
if err := walkFn(method, fullRoute, chain.Endpoint, append(mws, chain.Middlewares...)...); err != nil {
return err
}
} else {
if err := walkFn(method, fullRoute, handler, mws...); err != nil {
return err
}
}
}
}

return nil
}
13 changes: 13 additions & 0 deletions tree_test.go
Original file line number Diff line number Diff line change
@@ -424,3 +424,16 @@ func BenchmarkTreeGet(b *testing.B) {
tr.FindRoute(mctx, mGET, "/ping/123/456")
}
}

func TestWalker(t *testing.T) {
r := bigMux()

// Walk the muxBig router tree.
if err := Walk(r, func(method string, route string, handler http.Handler, middlewares ...func(http.Handler) http.Handler) error {
t.Logf("%v %v", method, route)

return nil
}); err != nil {
t.Error(err)
}
}