diff options
author | Li Haoyi <haoyi.sg@gmail.com> | 2018-08-09 00:36:25 +0800 |
---|---|---|
committer | Li Haoyi <haoyi.sg@gmail.com> | 2018-08-09 00:36:25 +0800 |
commit | fe17f0a465a49433867ea4917fd4938a7d2b6609 (patch) | |
tree | 04f04f15df5c33325d7da24fad8085587c465895 /cask/src | |
parent | b1969928a179bfa833cab528d544a1f77cf24987 (diff) | |
download | cask-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.scala | 43 | ||||
-rw-r--r-- | cask/src/cask/internal/Router.scala | 9 | ||||
-rw-r--r-- | cask/src/cask/main/Decorators.scala | 1 | ||||
-rw-r--r-- | cask/src/cask/main/Main.scala | 3 | ||||
-rw-r--r-- | cask/src/cask/main/Routes.scala | 2 |
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 |