summaryrefslogtreecommitdiff
path: root/cask/src/cask/endpoints
diff options
context:
space:
mode:
Diffstat (limited to 'cask/src/cask/endpoints')
-rw-r--r--cask/src/cask/endpoints/FormEndpoint.scala14
-rw-r--r--cask/src/cask/endpoints/JsonEndpoint.scala52
-rw-r--r--cask/src/cask/endpoints/StaticEndpoints.scala19
-rw-r--r--cask/src/cask/endpoints/WebEndpoints.scala18
-rw-r--r--cask/src/cask/endpoints/WebSocketEndpoint.scala22
5 files changed, 78 insertions, 47 deletions
diff --git a/cask/src/cask/endpoints/FormEndpoint.scala b/cask/src/cask/endpoints/FormEndpoint.scala
index 471c5e5..6f65786 100644
--- a/cask/src/cask/endpoints/FormEndpoint.scala
+++ b/cask/src/cask/endpoints/FormEndpoint.scala
@@ -1,7 +1,7 @@
package cask.endpoints
import cask.internal.{Router, Util}
-import cask.main.Endpoint
+import cask.main.HttpEndpoint
import cask.model._
import io.undertow.server.handlers.form.FormParserFactory
@@ -43,14 +43,13 @@ object FormReader{
def read(ctx: Request, label: String, input: Seq[FormEntry]) = input.map(_.asInstanceOf[FormFile])
}
}
-class postForm(val path: String, override val subpath: Boolean = false) extends Endpoint {
- type Output = Response
+class postForm(val path: String, override val subpath: Boolean = false)
+ extends HttpEndpoint[Response.Raw, Seq[FormEntry]] {
val methods = Seq("post")
- type Input = Seq[FormEntry]
type InputParser[T] = FormReader[T]
def wrapFunction(ctx: Request,
- delegate: Map[String, Input] => Router.Result[Output]): Router.Result[Response] = {
+ delegate: Delegate): Router.Result[Response.Raw] = {
try {
val formData = FormParserFactory.builder().build().createParser(ctx.exchange).parseBlocking()
delegate(
@@ -62,11 +61,12 @@ class postForm(val path: String, override val subpath: Boolean = false) extends
)
} catch{case e: Exception =>
Router.Result.Success(cask.model.Response(
- "Unable to parse form data: " + e + "\n" + Util.stackTraceString(e)
+ "Unable to parse form data: " + e + "\n" + Util.stackTraceString(e),
+ statusCode = 400
))
}
}
- def wrapPathSegment(s: String): Input = Seq(FormValue(s, new io.undertow.util.HeaderMap))
+ def wrapPathSegment(s: String): Seq[FormEntry] = Seq(FormValue(s, new io.undertow.util.HeaderMap))
}
diff --git a/cask/src/cask/endpoints/JsonEndpoint.scala b/cask/src/cask/endpoints/JsonEndpoint.scala
index e0d1257..6d3db82 100644
--- a/cask/src/cask/endpoints/JsonEndpoint.scala
+++ b/cask/src/cask/endpoints/JsonEndpoint.scala
@@ -1,11 +1,13 @@
package cask.endpoints
-import java.io.ByteArrayOutputStream
+import java.io.{ByteArrayOutputStream, InputStream, OutputStream, OutputStreamWriter}
import cask.internal.{Router, Util}
-import cask.main.Endpoint
+import cask.main.HttpEndpoint
+import cask.model.Response.DataCompanion
import cask.model.{Request, Response}
+import collection.JavaConverters._
sealed trait JsReader[T] extends Router.ArgReader[ujson.Value, T, cask.model.Request]
object JsReader{
@@ -26,13 +28,24 @@ object JsReader{
}
}
}
-class postJson(val path: String, override val subpath: Boolean = false) extends Endpoint{
- type Output = Response
+trait JsonData extends Response.Data
+object JsonData extends DataCompanion[JsonData]{
+ implicit class JsonDataImpl[T: upickle.default.Writer](t: T) extends JsonData{
+ def write(out: OutputStream) = {
+ val writer = new OutputStreamWriter(out)
+ implicitly[upickle.default.Writer[T]].write(new ujson.BaseRenderer(writer), t)
+ writer.flush()
+ }
+ }
+}
+
+class postJson(val path: String, override val subpath: Boolean = false)
+ extends HttpEndpoint[Response[JsonData], ujson.Value]{
val methods = Seq("post")
- type Input = ujson.Js.Value
type InputParser[T] = JsReader[T]
+ override type OuterReturned = Router.Result[Response.Raw]
def wrapFunction(ctx: Request,
- delegate: Map[String, Input] => Router.Result[Output]): Router.Result[Response] = {
+ delegate: Delegate): Router.Result[Response.Raw] = {
val obj = for{
str <-
try {
@@ -41,21 +54,38 @@ class postJson(val path: String, override val subpath: Boolean = false) extends
Right(new String(boas.toByteArray))
}
catch{case e: Throwable => Left(cask.model.Response(
- "Unable to deserialize input JSON text: " + e + "\n" + Util.stackTraceString(e)
+ "Unable to deserialize input JSON text: " + e + "\n" + Util.stackTraceString(e),
+ statusCode = 400
))}
json <-
try Right(ujson.read(str))
catch{case e: Throwable => Left(cask.model.Response(
- "Input text is invalid JSON: " + e + "\n" + Util.stackTraceString(e)
+ "Input text is invalid JSON: " + e + "\n" + Util.stackTraceString(e),
+ statusCode = 400
))}
obj <-
try Right(json.obj)
- catch {case e: Throwable => Left(cask.model.Response("Input JSON must be a dictionary"))}
+ catch {case e: Throwable => Left(cask.model.Response(
+ "Input JSON must be a dictionary",
+ statusCode = 400
+ ))}
} yield obj.toMap
obj match{
- case Left(r) => Router.Result.Success(r)
+ case Left(r) => Router.Result.Success(r.map(Response.Data.StringData))
case Right(params) => delegate(params)
}
}
- def wrapPathSegment(s: String): Input = ujson.Js.Str(s)
+ def wrapPathSegment(s: String): ujson.Value = ujson.Str(s)
}
+
+class getJson(val path: String, override val subpath: Boolean = false)
+ extends HttpEndpoint[Response[JsonData], Seq[String]]{
+ val methods = Seq("get")
+ type InputParser[T] = QueryParamReader[T]
+ override type OuterReturned = Router.Result[Response.Raw]
+ def wrapFunction(ctx: Request, delegate: Delegate): Router.Result[Response.Raw] = {
+
+ delegate(WebEndpoint.buildMapFromQueryParams(ctx))
+ }
+ def wrapPathSegment(s: String) = Seq(s)
+} \ No newline at end of file
diff --git a/cask/src/cask/endpoints/StaticEndpoints.scala b/cask/src/cask/endpoints/StaticEndpoints.scala
index fd194ca..0abfcf5 100644
--- a/cask/src/cask/endpoints/StaticEndpoints.scala
+++ b/cask/src/cask/endpoints/StaticEndpoints.scala
@@ -1,15 +1,13 @@
package cask.endpoints
-import cask.main.Endpoint
+import cask.main.HttpEndpoint
import cask.model.Request
-class staticFiles(val path: String) extends Endpoint{
- type Output = String
+class staticFiles(val path: String) extends HttpEndpoint[String, Seq[String]]{
val methods = Seq("get")
- type Input = Seq[String]
type InputParser[T] = QueryParamReader[T]
override def subpath = true
- def wrapFunction(ctx: Request, delegate: Delegate): Returned = {
+ def wrapFunction(ctx: Request, delegate: Delegate): OuterReturned = {
delegate(Map()).map(t =>
cask.model.StaticFile(
(cask.internal.Util.splitPath(t) ++ ctx.remainingPathSegments)
@@ -19,16 +17,15 @@ class staticFiles(val path: String) extends Endpoint{
)
}
- def wrapPathSegment(s: String): Input = Seq(s)
+ def wrapPathSegment(s: String): Seq[String] = Seq(s)
}
-class staticResources(val path: String, resourceRoot: ClassLoader = getClass.getClassLoader) extends Endpoint{
- type Output = String
+class staticResources(val path: String, resourceRoot: ClassLoader = getClass.getClassLoader)
+ extends HttpEndpoint[String, Seq[String]]{
val methods = Seq("get")
- type Input = Seq[String]
type InputParser[T] = QueryParamReader[T]
override def subpath = true
- def wrapFunction(ctx: Request, delegate: Delegate): Returned = {
+ def wrapFunction(ctx: Request, delegate: Delegate): OuterReturned = {
delegate(Map()).map(t =>
cask.model.StaticResource(
(cask.internal.Util.splitPath(t) ++ ctx.remainingPathSegments)
@@ -39,5 +36,5 @@ class staticResources(val path: String, resourceRoot: ClassLoader = getClass.get
)
}
- def wrapPathSegment(s: String): Input = Seq(s)
+ def wrapPathSegment(s: String): Seq[String] = Seq(s)
}
diff --git a/cask/src/cask/endpoints/WebEndpoints.scala b/cask/src/cask/endpoints/WebEndpoints.scala
index ab3b480..8bb3bae 100644
--- a/cask/src/cask/endpoints/WebEndpoints.scala
+++ b/cask/src/cask/endpoints/WebEndpoints.scala
@@ -1,19 +1,22 @@
package cask.endpoints
import cask.internal.Router
-import cask.main.Endpoint
+import cask.main.HttpEndpoint
import cask.model.{Request, Response}
import collection.JavaConverters._
-trait WebEndpoint extends Endpoint{
- type Output = Response
- type Input = Seq[String]
+trait WebEndpoint extends HttpEndpoint[Response.Raw, Seq[String]]{
type InputParser[T] = QueryParamReader[T]
def wrapFunction(ctx: Request,
- delegate: Map[String, Input] => Router.Result[Output]): Router.Result[Response] = {
-
+ delegate: Delegate): Router.Result[Response.Raw] = {
+ delegate(WebEndpoint.buildMapFromQueryParams(ctx))
+ }
+ def wrapPathSegment(s: String) = Seq(s)
+}
+object WebEndpoint{
+ def buildMapFromQueryParams(ctx: Request) = {
val b = Map.newBuilder[String, Seq[String]]
val queryParams = ctx.exchange.getQueryParameters
for(k <- queryParams.keySet().iterator().asScala){
@@ -22,9 +25,8 @@ trait WebEndpoint extends Endpoint{
deque.toArray(arr)
b += (k -> (arr: Seq[String]))
}
- delegate(b.result())
+ b.result()
}
- def wrapPathSegment(s: String) = Seq(s)
}
class get(val path: String, override val subpath: Boolean = false) extends WebEndpoint{
val methods = Seq("get")
diff --git a/cask/src/cask/endpoints/WebSocketEndpoint.scala b/cask/src/cask/endpoints/WebSocketEndpoint.scala
index f747341..842d508 100644
--- a/cask/src/cask/endpoints/WebSocketEndpoint.scala
+++ b/cask/src/cask/endpoints/WebSocketEndpoint.scala
@@ -3,22 +3,24 @@ package cask.endpoints
import cask.internal.Router
import cask.model.Request
import io.undertow.websockets.WebSocketConnectionCallback
-
+import collection.JavaConverters._
sealed trait WebsocketResult
object WebsocketResult{
- implicit class Response(val value: cask.model.Response) extends WebsocketResult
+ implicit class Response[T](value0: cask.model.Response[T])
+ (implicit f: T => cask.model.Response.Data) extends WebsocketResult{
+ def value = value0.map(f)
+ }
implicit class Listener(val value: WebSocketConnectionCallback) extends WebsocketResult
}
-class websocket(val path: String, override val subpath: Boolean = false) extends cask.main.BaseEndpoint{
- type Output = WebsocketResult
+class websocket(val path: String, override val subpath: Boolean = false)
+ extends cask.main.Endpoint[WebsocketResult, Seq[String]]{
val methods = Seq("websocket")
- type Input = Seq[String]
type InputParser[T] = QueryParamReader[T]
- type Returned = Router.Result[WebsocketResult]
- def wrapFunction(ctx: Request, delegate: Delegate): Returned = delegate(Map())
-
- def wrapPathSegment(s: String): Input = Seq(s)
-
+ type OuterReturned = Router.Result[WebsocketResult]
+ def wrapFunction(ctx: Request, delegate: Delegate): OuterReturned = {
+ delegate(WebEndpoint.buildMapFromQueryParams(ctx))
+ }
+ def wrapPathSegment(s: String): Seq[String] = Seq(s)
}