summaryrefslogtreecommitdiff
path: root/cask/src
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2018-08-09 00:36:25 +0800
committerLi Haoyi <haoyi.sg@gmail.com>2018-08-09 00:36:25 +0800
commitfe17f0a465a49433867ea4917fd4938a7d2b6609 (patch)
tree04f04f15df5c33325d7da24fad8085587c465895 /cask/src
parentb1969928a179bfa833cab528d544a1f77cf24987 (diff)
downloadcask-fe17f0a465a49433867ea4917fd4938a7d2b6609.tar.gz
cask-fe17f0a465a49433867ea4917fd4938a7d2b6609.tar.bz2
cask-fe17f0a465a49433867ea4917fd4938a7d2b6609.zip
Add `@cask.decorators.compress` utility
Allow for decorators to be applied across `cask.Routes` or `cask.Main`
Diffstat (limited to 'cask/src')
-rw-r--r--cask/src/cask/decorators/compress.scala43
-rw-r--r--cask/src/cask/internal/Router.scala9
-rw-r--r--cask/src/cask/main/Decorators.scala1
-rw-r--r--cask/src/cask/main/Main.scala3
-rw-r--r--cask/src/cask/main/Routes.scala2
5 files changed, 50 insertions, 8 deletions
diff --git a/cask/src/cask/decorators/compress.scala b/cask/src/cask/decorators/compress.scala
new file mode 100644
index 0000000..fc67dd4
--- /dev/null
+++ b/cask/src/cask/decorators/compress.scala
@@ -0,0 +1,43 @@
+package cask.decorators
+import java.io.{ByteArrayOutputStream, OutputStream}
+import java.util.zip.{DeflaterOutputStream, GZIPOutputStream}
+
+import cask.internal.Router
+import cask.model.{ParamContext, Response}
+
+import collection.JavaConverters._
+class compress extends cask.Decorator{
+ def wrapFunction(ctx: ParamContext, delegate: Delegate) = {
+ val acceptEncodings = ctx.exchange.getRequestHeaders.get("Accept-Encoding").asScala.flatMap(_.split(", "))
+ delegate(Map()) match{
+ case Router.Result.Success(v) =>
+ val (newData, newHeaders) = if (acceptEncodings.exists(_.toLowerCase == "gzip")) {
+ new Response.Data {
+ def write(out: OutputStream): Unit = {
+ val wrap = new GZIPOutputStream(out)
+ v.data.write(wrap)
+ wrap.flush()
+ wrap.close()
+ }
+ } -> Seq("Content-Encoding" -> "gzip")
+ }else if (acceptEncodings.exists(_.toLowerCase == "deflate")){
+ new Response.Data {
+ def write(out: OutputStream): Unit = {
+ val wrap = new DeflaterOutputStream(out)
+ v.data.write(wrap)
+ wrap.flush()
+ }
+ } -> Seq("Content-Encoding" -> "deflate")
+ }else v.data -> Nil
+ Router.Result.Success(
+ Response(
+ newData,
+ v.statusCode,
+ v.headers ++ newHeaders,
+ v.cookies
+ )
+ )
+ case e: Router.Result.Error => e
+ }
+ }
+}
diff --git a/cask/src/cask/internal/Router.scala b/cask/src/cask/internal/Router.scala
index 7ad0c18..c66e8d2 100644
--- a/cask/src/cask/internal/Router.scala
+++ b/cask/src/cask/internal/Router.scala
@@ -217,14 +217,9 @@ class Router[C <: Context](val c: C) {
val argValuesSymbol = q"${c.fresh[TermName]("argValues")}"
val argSigsSymbol = q"${c.fresh[TermName]("argSigs")}"
val ctxSymbol = q"${c.fresh[TermName]("ctx")}"
- if (method.paramLists.length > argReaders.length) c.abort(
- method.pos,
- s"Endpoint ${method.name}'s number of parameter lists (${method.paramLists.length}) " +
- s"cannot be more than the number of decorators (${argReaders.length})"
- )
val argData = for(argListIndex <- method.paramLists.indices) yield{
- val annotDeserializeType = annotDeserializeTypes(argListIndex)
- val argReader = argReaders(argListIndex)
+ val annotDeserializeType = annotDeserializeTypes.lift(argListIndex).getOrElse(tq"scala.Any")
+ val argReader = argReaders.lift(argListIndex).getOrElse(q"cask.main.NoOpParser.instanceAny")
val flattenedArgLists = method.paramss(argListIndex)
def hasDefault(i: Int) = {
val defaultName = s"${method.name}$$default$$${i + 1}"
diff --git a/cask/src/cask/main/Decorators.scala b/cask/src/cask/main/Decorators.scala
index 1bd8867..73d8c19 100644
--- a/cask/src/cask/main/Decorators.scala
+++ b/cask/src/cask/main/Decorators.scala
@@ -75,4 +75,5 @@ class NoOpParser[Input, T] extends ArgReader[Input, T, ParamContext] {
}
object NoOpParser{
implicit def instance[Input, T] = new NoOpParser[Input, T]
+ implicit def instanceAny[T] = new NoOpParser[Any, T]
} \ No newline at end of file
diff --git a/cask/src/cask/main/Main.scala b/cask/src/cask/main/Main.scala
index 5558a08..4a8182b 100644
--- a/cask/src/cask/main/Main.scala
+++ b/cask/src/cask/main/Main.scala
@@ -15,6 +15,7 @@ class Main(servers0: Routes*) extends BaseMain{
def allRoutes = servers0.toSeq
}
abstract class BaseMain{
+ def mainDecorators = Seq.empty[cask.main.Decorator]
def allRoutes: Seq[Routes]
val port: Int = 8080
val host: String = "localhost"
@@ -77,7 +78,7 @@ abstract class BaseMain{
// delegate throwing on them
}catch{case e: Throwable => Router.Result.Error.Exception(e) }
- rec(metadata.decorators.toList, Nil)match{
+ rec((metadata.decorators ++ routes.decorators ++ mainDecorators).toList, Nil)match{
case Router.Result.Success(response: Response) => writeResponse(exchange, response)
case e: Router.Result.Error =>
diff --git a/cask/src/cask/main/Routes.scala b/cask/src/cask/main/Routes.scala
index 0dea657..7b47731 100644
--- a/cask/src/cask/main/Routes.scala
+++ b/cask/src/cask/main/Routes.scala
@@ -70,6 +70,8 @@ object Routes{
}
trait Routes{
+
+ def decorators = Seq.empty[cask.main.Decorator]
private[this] var metadata0: Routes.RoutesEndpointsMetadata[this.type] = null
def caskMetadata =
if (metadata0 != null) metadata0