-
-
Save rossabaker/1204885 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
trait HandlerArgs extends FiniteStateMachineActor { | |
def isInitial: Boolean | |
} | |
class Handler extends ((Request, HandlerArgs) => Response) | |
class Middleware extends (Handler => Handler) | |
object Server { | |
type ResponseWriter = Response => Result | |
val handler: Handler | |
object Executor { | |
@tailrec | |
def apply(handle: Handler, write: ResponseWriter, onError: ErrorHandler): Response = { | |
val res = handle(req, args) | |
if (!args.isInitial) onError(new YouCantDoThisRightHereNowException()) | |
if (!res.isInstanceOf[EndResponse]) { | |
write(res) | |
apply(handle, socket) | |
} else { | |
res | |
} | |
} | |
} | |
def apply(req: Request, args: HandlerArgs) = { | |
(future { Executor((r, a) => handler(r, a), socket.send _) } onComplete (socket.send _) onException (throw _)).get | |
} | |
} | |
sealed trait Response { | |
type ContentType | |
def headers: Map[String, String] | |
def content: ContentType | |
def update(statusLine: String, headers: Map[String, String], content: ContentType): ResponsePrelude | |
} | |
sealed trait ResponsePrelude extends Response { | |
def statusLine: String | |
def update(statusLine: String, headers: Map[String, String], content: ContentType): ResponsePrelude | |
} | |
sealed trait ResponseCompletion { self: Response => | |
} | |
sealed trait ResponsePart extends Response { | |
def update(headers: Map[String, String], content: ContentType): ResponsePart | |
} | |
case class BeginResponse[T : Manifest](statusLine: String, headers: Map[String, String], content: T) extends ResponsePrelude { | |
type ContentType = T | |
def update(statusLine: String = this.statusLine, headers: Map[String, String] = headers, content: ContentType = content): ResponsePrelude = | |
copy(statusLine, headers, content) | |
} | |
case class ResponseChunk[T : Manifest](headers: Map[String, String], content: T) { | |
type ContentType = T | |
def update(headers: Map[String, String] = headers, content: ContentType = content): ResponsePrelude = | |
copy(headers, content) | |
} | |
case class EndResponse[T: Manifest](headers: Map[String, String], content: T) extends ResponseCompletion { | |
type ContentType = T | |
def update(headers: Map[String, String] = headers, content: ContentType = content): ResponsePrelude = | |
copy(headers, content) | |
} | |
case class DefaultResponse[T: Manifest](statusLine: String, headers: Map[String, String], content: T) extends ResponsePrelude with ResponseCompletion { | |
type ContentType = T | |
def update(statusLine: String = this.statusLine, headers: Map[String, String] = headers, content: ContentType = content): ResponsePrelude = | |
copy(statusLine, headers, content) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment