Repository: tipsy/javalin (kotlin)

Issue:
Path Parameters Unavailable in beforeMatched
**Actual behavior (the bug)**
After upgrading to Javalin 6.0.0, when using the beforeMatched hook, ctx.pathParamMap() returns an empty map, and accessing named path parameters via ctx.pathParam("name") does not work as expected. 

**Expected behavior**
The expected behavior is that within the beforeMatched hook, ctx.pathParamMap() and ctx.pathParam() should work as in the other normal route handlers.

**To Reproduce**
```kotlin
import io.javalin.Javalin
import io.javalin.apibuilder.ApiBuilder.get

fun main() {
    val app = Javalin.create { javalinConfig ->
        javalinConfig.router.apiBuilder {
            get("/{test}") {
                println("get: " + it.pathParamMap())
            }
        }
    }.start(7000)

    app.beforeMatched {
        println("before matched: " + it.pathParamMap())
    }
}
```
```
HTTP GET /test
before matched: {}
get: {test=test}
```

Pull request description:
This fixes #2085 but it is basically adds a special case. Still unsure if we would want this.

Fixes #2085

Patch:
diff --git a/javalin/src/main/java/io/javalin/http/servlet/DefaultTasks.kt b/javalin/src/main/java/io/javalin/http/servlet/DefaultTasks.kt
index 019e18470..24ae15c21 100644
--- a/javalin/src/main/java/io/javalin/http/servlet/DefaultTasks.kt
+++ b/javalin/src/main/java/io/javalin/http/servlet/DefaultTasks.kt
@@ -25,9 +25,19 @@ object DefaultTasks {
             ctx.setRouteRoles(servlet.matchedRoles(ctx, requestUri)) // set roles for the matched handler
             servlet.willMatch(ctx, requestUri)
         }
+        val httpHandlerOrNull by javalinLazy {
+            servlet.router.findHttpHandlerEntries(ctx.method(), requestUri).firstOrNull()
+        }
         servlet.router.findHttpHandlerEntries(HandlerType.BEFORE_MATCHED, requestUri).forEach { entry ->
             if (willMatch) {
-                submitTask(LAST, Task(skipIfExceptionOccurred = true) { entry.handle(ctx, requestUri) })
+                submitTask(LAST, Task(skipIfExceptionOccurred = true) {
+                    val httpHandler = httpHandlerOrNull
+                    if (httpHandler != null && entry.endpoint.path == "*") {
+                        entry.endpoint.handle(ctx.update(httpHandler, requestUri))
+                    } else {
+                        entry.handle(ctx, requestUri)
+                    }
+                })
             }
         }
     }


Test patch:
diff --git a/javalin/src/test/java/io/javalin/TestBeforeAfterMatched.kt b/javalin/src/test/java/io/javalin/TestBeforeAfterMatched.kt
index a57bf17ff..5c8ee89e6 100644
--- a/javalin/src/test/java/io/javalin/TestBeforeAfterMatched.kt
+++ b/javalin/src/test/java/io/javalin/TestBeforeAfterMatched.kt
@@ -316,4 +316,15 @@ class TestBeforeAfterMatched {
             assertThat(slash.status).isEqualTo(HttpStatus.OK.code)
             assertThat(slash.headers.getFirst("X-After")).isEqualTo("true")
         }
+
+    @Test
+    fun `gh-2085 pathParamMap works with beforeMatched`() =
+        TestUtil.test(Javalin.create { config ->
+            config.router.mount {
+                it.beforeMatched { ctx -> ctx.result(ctx.pathParamMap().toString()) }
+                it.get("/{path}") { ctx -> ctx.result(ctx.result() + "/" + ctx.pathParamMap()) }
+            }
+        }) { _, http ->
+            assertThat(http.getBody("/a-value")).isEqualTo("{path=a-value}/{path=a-value}")
+        }
 }