Skip to content

Instantly share code, notes, and snippets.

@rossabaker
Created September 9, 2011 20:14
Show Gist options
  • Save rossabaker/1207207 to your computer and use it in GitHub Desktop.
Save rossabaker/1207207 to your computer and use it in GitHub Desktop.
import javax.servlet.annotation._
import grizzled.generator._
import scala.annotation._
import scala.util.Random
trait Request
case object Request extends Request
trait Handler extends (Request => Response)
case class Response(status: Int = 200, headers: Map[String, String] = Map.empty, body: Chunk)
sealed trait Chunk
case class BodyChunk(content: String, next: () => Chunk = () => Trailer())
extends Chunk
case class Trailer(headers: Map[String, String] = Map.empty) extends Chunk
object FuckYouHandler extends Handler {
def apply(req: Request): Response = Response(body = BodyChunk("fuck you"))
}
object RandomHandler extends Handler {
def apply(req: Request): Response = {
def chunk(i: Int): Chunk = {
if (Random.nextDouble < 0.9)
BodyChunk(i.toString, () => chunk(i + 1))
else
Trailer()
}
Response(body = chunk(0))
}
}
object CensorMiddleware {
def apply(handler: Handler): Handler = new Handler {
def apply(req: Request) = {
val res = handler.apply(req)
res.copy(body = censor(res.body))
}
}
def censor(chunk: Chunk) = chunk match {
case BodyChunk(content, next) =>
BodyChunk(content.replace("fuck", "f***"), next)
case chunk => chunk
}
}
class SsgiServlet extends HttpServlet {
val handler = CensorMiddleware(RandomHandler)
override def service(sReq: HttpServletRequest, sRes: HttpServletResponse) = {
val req = Request
val res = handler(req)
sRes.setStatus(res.status)
@tailrec
def renderChunk(chunk: Chunk): Unit = chunk match {
case chunk: BodyChunk =>
sRes.getWriter.println(chunk.content)
sRes.getWriter.flush()
renderChunk(chunk.next())
case Trailer(_) =>
sRes.getWriter.close()
}
renderChunk(res.body)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment