Created
December 13, 2012 17:24
-
-
Save nraychaudhuri/4278105 to your computer and use it in GitHub Desktop.
Gzip compression of dynamic response in Play
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package plugin | |
import play.api._ | |
import play.api.mvc._ | |
import play.api.http.Writeable | |
import play.api.http.HeaderNames._ | |
import java.io.{ByteArrayInputStream, ByteArrayOutputStream} | |
import java.util.zip.GZIPOutputStream | |
import play.api.libs.concurrent.Promise | |
object GZip { | |
def gzip(input: Array[Byte]): Array[Byte] = { | |
val inputStream = new ByteArrayInputStream(input) | |
val byteArrayOut = new ByteArrayOutputStream(input.length) | |
val gzipper = new GZIPOutputStream(byteArrayOut) | |
val buf = new Array[Byte](4096) | |
var numBytesRead = inputStream read buf | |
while (numBytesRead > 0) { | |
gzipper.write(buf, 0, numBytesRead) | |
numBytesRead = inputStream read buf | |
} | |
// Clean up. | |
inputStream.close | |
gzipper.close | |
byteArrayOut.toByteArray | |
} | |
def gzipped(r: => Result)(implicit req: RequestHeader): Result = { | |
req.headers.get(ACCEPT_ENCODING).map(_.split(',').exists(_ == "gzip")) match { | |
case Some(true) => gzipResult(r) | |
case _ => r | |
} | |
} | |
private def gzipResult(r: => Result)(implicit req: RequestHeader): Result = r match { | |
case s:SimpleResult[_] => | |
SimpleResult(s.header, s.body)(gzippedWritable(s.writeable)).withHeaders(CONTENT_ENCODING -> "gzip") | |
case AsyncResult(p) => AsyncResult(p.map(r => gzipped(r))) | |
case _ => r | |
} | |
private def gzippedWritable[A](w: Writeable[A]): Writeable[A] = { | |
Writeable { a => | |
gzip(w.transform(a)) | |
} | |
} | |
} | |
//And inside the controller action we could use it like following: | |
def index = Action { implicit request => | |
gzipped { | |
Ok(views.html.index("hey")) | |
} | |
} | |
//or | |
def index = Action { implicit request => | |
gzipped { | |
Async { | |
Promise.pure(Ok(someJsonValue)) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment