All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.scalatra.GZipSupport.scala Maven / Gradle / Ivy

The newest version!
package org.scalatra

import java.io.PrintWriter
import java.util.zip.GZIPOutputStream
import javax.servlet.{ WriteListener, ServletOutputStream }
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import javax.servlet.http.HttpServletResponseWrapper

/**
 * Scalatra handler for gzipped responses.
 */
trait GZipSupport extends Handler {
  self: ScalatraBase =>

  abstract override def handle(req: HttpServletRequest, res: HttpServletResponse): Unit = {
    withRequestResponse(req, res) {
      if (isGzip) {
        val gzos = new GZIPOutputStream(res.getOutputStream)
        val w = new PrintWriter(gzos)
        val r = response

        ScalatraBase onRenderedCompleted { _ =>
          w.flush()
          w.close()
        }

        val gzsos = new GZipServletOutputStream(gzos, r.getOutputStream)
        val wrapped = new WrappedGZipResponse(r, gzsos, w)
        ScalatraBase.onCompleted { _ =>
          wrapped.addHeader("Content-Encoding", "gzip")
        }
        super.handle(req, wrapped)
      } else {
        super.handle(req, res)
      }
    }
  }

  private class GZipServletOutputStream(gzos: GZIPOutputStream, orig: ServletOutputStream) extends ServletOutputStream {
    override def write(b: Int): Unit = gzos.write(b)
    override def setWriteListener(writeListener: WriteListener): Unit = orig.setWriteListener(writeListener)
    override def isReady: Boolean = orig.isReady()
  }

  private class WrappedGZipResponse(res: HttpServletResponse, gzsos: ServletOutputStream, w: PrintWriter) extends HttpServletResponseWrapper(res) {
    override def getOutputStream: ServletOutputStream = gzsos
    override def getWriter: PrintWriter = w
    override def setContentLength(i: Int) = {} // ignoring content length as it won't be the same when gzipped
  }

  /**
   * Returns true if Accept-Encoding contains gzip.
   */
  private[this] def isGzip(implicit request: HttpServletRequest): Boolean = {
    Option(request.getHeader("Accept-Encoding")).getOrElse("").toUpperCase.contains("GZIP")
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy