| 326 | } |
| 327 | |
| 328 | func (app *App) nextCustom(c CustomCtx) (bool, error) { |
| 329 | methodInt := c.getMethodInt() |
| 330 | treeHash := c.getTreePathHash() |
| 331 | // Get stack length |
| 332 | tree, ok := app.treeStack[methodInt][treeHash] |
| 333 | if !ok { |
| 334 | tree = app.treeStack[methodInt][0] |
| 335 | } |
| 336 | indexRoute := max(c.getIndexRoute()+1, 0) |
| 337 | |
| 338 | // Loop over the route stack starting from previous index; |
| 339 | // the clamp above plus the len(tree) guard keep tree[indexRoute] bounds-check free |
| 340 | for ; indexRoute < len(tree); indexRoute++ { |
| 341 | // Get *Route |
| 342 | route := tree[indexRoute] |
| 343 | |
| 344 | if route.mount { |
| 345 | continue |
| 346 | } |
| 347 | |
| 348 | // Check if it matches the request path |
| 349 | if !route.match(c.getDetectionPath(), c.Path(), c.getValues()) { |
| 350 | continue |
| 351 | } |
| 352 | if c.getSkipNonUseRoutes() && !route.use { |
| 353 | continue |
| 354 | } |
| 355 | |
| 356 | // Pass route reference and param values |
| 357 | c.setRoute(route) |
| 358 | // Non use handler matched |
| 359 | if !route.use { |
| 360 | c.setMatched(true) |
| 361 | } |
| 362 | // Execute first handler of route |
| 363 | if len(route.Handlers) > 0 { |
| 364 | c.setIndexHandler(0) |
| 365 | c.setIndexRoute(indexRoute) |
| 366 | return true, route.Handlers[0](c) |
| 367 | } |
| 368 | return true, nil // Stop scanning the stack |
| 369 | } |
| 370 | |
| 371 | // If c.Next() does not match, return 404 |
| 372 | // If no match, scan stack again if other methods match the request |
| 373 | // Moved from app.handler because middleware may break the route chain |
| 374 | if c.getSkipNonUseRoutes() { |
| 375 | return false, nil |
| 376 | } |
| 377 | |
| 378 | if c.getMatched() { |
| 379 | return false, ErrNotFound |
| 380 | } |
| 381 | |
| 382 | exists := false |
| 383 | methods := app.config.RequestMethods |
| 384 | for i := range methods { |
| 385 | // Skip original method |