summaryrefslogtreecommitdiff
path: root/cask
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2018-07-25 19:19:35 +0800
committerLi Haoyi <haoyi.sg@gmail.com>2018-07-25 19:19:35 +0800
commitb985aa5d25d97794b26402f936c4323f977c4073 (patch)
tree60041c73efe6b25eff96db7a67e260e2f9f6614d /cask
parent072028c76efde19c459b35d9e2a6789f03baa1b0 (diff)
downloadcask-b985aa5d25d97794b26402f936c4323f977c4073.tar.gz
cask-b985aa5d25d97794b26402f936c4323f977c4073.tar.bz2
cask-b985aa5d25d97794b26402f936c4323f977c4073.zip
HTTP method distinction now works, by generating parallel routing trees one-per-method
Diffstat (limited to 'cask')
-rw-r--r--cask/src/cask/endpoints/FormEndpoint.scala1
-rw-r--r--cask/src/cask/endpoints/JsonEndpoint.scala1
-rw-r--r--cask/src/cask/endpoints/StaticEndpoints.scala1
-rw-r--r--cask/src/cask/endpoints/WebEndpoints.scala12
-rw-r--r--cask/src/cask/main/Main.scala18
-rw-r--r--cask/src/cask/main/Routes.scala3
6 files changed, 25 insertions, 11 deletions
diff --git a/cask/src/cask/endpoints/FormEndpoint.scala b/cask/src/cask/endpoints/FormEndpoint.scala
index 2c420e9..2b8cf25 100644
--- a/cask/src/cask/endpoints/FormEndpoint.scala
+++ b/cask/src/cask/endpoints/FormEndpoint.scala
@@ -36,6 +36,7 @@ object FormReader{
}
}
class postForm(val path: String, override val subpath: Boolean = false) extends Routes.Endpoint[Response]{
+ val methods = Seq("post")
type InputType = Seq[FormValue]
def wrapMethodOutput(t: Response) = t
def parseMethodInput[T](implicit p: FormReader[T]) = p
diff --git a/cask/src/cask/endpoints/JsonEndpoint.scala b/cask/src/cask/endpoints/JsonEndpoint.scala
index ffbe290..f172b2b 100644
--- a/cask/src/cask/endpoints/JsonEndpoint.scala
+++ b/cask/src/cask/endpoints/JsonEndpoint.scala
@@ -25,6 +25,7 @@ object JsReader{
}
}
class postJson(val path: String, override val subpath: Boolean = false) extends Routes.Endpoint[Response]{
+ val methods = Seq("post")
type InputType = ujson.Js.Value
def wrapMethodOutput(t: Response) = t
def parseMethodInput[T](implicit p: JsReader[T]) = p
diff --git a/cask/src/cask/endpoints/StaticEndpoints.scala b/cask/src/cask/endpoints/StaticEndpoints.scala
index 89e4f4a..937b9c2 100644
--- a/cask/src/cask/endpoints/StaticEndpoints.scala
+++ b/cask/src/cask/endpoints/StaticEndpoints.scala
@@ -6,6 +6,7 @@ import cask.main.Routes
import cask.model.{BaseResponse, ParamContext}
class static(val path: String) extends Routes.Endpoint[String] {
+ val methods = Seq("get")
type InputType = Seq[String]
override def subpath = true
def wrapOutput(t: String) = t
diff --git a/cask/src/cask/endpoints/WebEndpoints.scala b/cask/src/cask/endpoints/WebEndpoints.scala
index ed93c6c..14c21ce 100644
--- a/cask/src/cask/endpoints/WebEndpoints.scala
+++ b/cask/src/cask/endpoints/WebEndpoints.scala
@@ -27,9 +27,15 @@ trait WebEndpoint extends Routes.Endpoint[BaseResponse]{
.asInstanceOf[Router.Result[BaseResponse]]
}
}
-class get(val path: String, override val subpath: Boolean = false) extends WebEndpoint
-class post(val path: String, override val subpath: Boolean = false) extends WebEndpoint
-class put(val path: String, override val subpath: Boolean = false) extends WebEndpoint
+class get(val path: String, override val subpath: Boolean = false) extends WebEndpoint{
+ val methods = Seq("get")
+}
+class post(val path: String, override val subpath: Boolean = false) extends WebEndpoint{
+ val methods = Seq("post")
+}
+class put(val path: String, override val subpath: Boolean = false) extends WebEndpoint{
+ val methods = Seq("put")
+}
class route(val path: String, val methods: Seq[String], override val subpath: Boolean = false) extends WebEndpoint
abstract class QueryParamReader[T]
diff --git a/cask/src/cask/main/Main.scala b/cask/src/cask/main/Main.scala
index 680dd04..f7789e3 100644
--- a/cask/src/cask/main/Main.scala
+++ b/cask/src/cask/main/Main.scala
@@ -25,10 +25,14 @@ abstract class BaseMain{
route <- routes.caskMetadata.value.map(x => x: Routes.EndpointMetadata[_])
} yield (routes, route)
- lazy val routeTrie = DispatchTrie.construct[(Routes, Routes.EndpointMetadata[_])](0,
- for((route, metadata) <- routeList)
- yield (Util.splitPath(metadata.metadata.path): IndexedSeq[String], (route, metadata), metadata.metadata.subpath)
- )
+
+ lazy val routeTries = Seq("get", "put", "post")
+ .map { method =>
+ method -> DispatchTrie.construct[(Routes, Routes.EndpointMetadata[_])](0,
+ for ((route, metadata) <- routeList if metadata.endpoint.methods.contains(method))
+ yield (Util.splitPath(metadata.endpoint.path): IndexedSeq[String], (route, metadata), metadata.endpoint.subpath)
+ )
+ }.toMap
def handleError(statusCode: Int): Response = {
Response(
@@ -154,13 +158,13 @@ abstract class BaseMain{
}
lazy val defaultHandler = new HttpHandler() {
def handleRequest(exchange: HttpServerExchange): Unit = {
- routeTrie.lookup(Util.splitPath(exchange.getRequestPath).toList, Map()) match{
+ routeTries(exchange.getRequestMethod.toString.toLowerCase()).lookup(Util.splitPath(exchange.getRequestPath).toList, Map()) match{
case None => writeResponse(exchange, handleError(404))
case Some(((routes, metadata), bindings, remaining)) =>
- val result = metadata.metadata.handle(
+ val result = metadata.endpoint.handle(
ParamContext(exchange, remaining), bindings, routes,
metadata.entryPoint.asInstanceOf[
- EntryPoint[metadata.metadata.InputType, cask.main.Routes, cask.model.ParamContext]
+ EntryPoint[metadata.endpoint.InputType, cask.main.Routes, cask.model.ParamContext]
]
)
diff --git a/cask/src/cask/main/Routes.scala b/cask/src/cask/main/Routes.scala
index 33964fa..ee2b2b9 100644
--- a/cask/src/cask/main/Routes.scala
+++ b/cask/src/cask/main/Routes.scala
@@ -12,6 +12,7 @@ object Routes{
trait Endpoint[R]{
type InputType
val path: String
+ val methods: Seq[String]
def subpath: Boolean = false
def wrapMethodOutput(t: R): Any
def handle(ctx: ParamContext,
@@ -20,7 +21,7 @@ object Routes{
entryPoint: EntryPoint[InputType, Routes, cask.model.ParamContext]): Router.Result[BaseResponse]
}
- case class EndpointMetadata[T](metadata: Endpoint[_],
+ case class EndpointMetadata[T](endpoint: Endpoint[_],
entryPoint: EntryPoint[_, T, ParamContext])
case class RoutesEndpointsMetadata[T](value: EndpointMetadata[T]*)
object RoutesEndpointsMetadata{