Reformating configuration and examples for PDF (Scala, and leftovers). See #2413
This commit is contained in:
parent
309bb53d98
commit
08ef942242
46 changed files with 330 additions and 191 deletions
|
|
@ -50,10 +50,16 @@ object HttpServer {
|
|||
val rsp = request match {
|
||||
case Request("GET", "ping" :: Nil, _, _, headers, _) ⇒
|
||||
OKResponse(ByteString("<p>pong</p>"),
|
||||
request.headers.exists { case Header(n, v) ⇒ n.toLowerCase == "connection" && v.toLowerCase == "keep-alive" })
|
||||
request.headers.exists {
|
||||
case Header(n, v) ⇒
|
||||
n.toLowerCase == "connection" && v.toLowerCase == "keep-alive"
|
||||
})
|
||||
case req ⇒
|
||||
OKResponse(ByteString("<p>" + req.toString + "</p>"),
|
||||
request.headers.exists { case Header(n, v) ⇒ n.toLowerCase == "connection" && v.toLowerCase == "keep-alive" })
|
||||
request.headers.exists {
|
||||
case Header(n, v) ⇒
|
||||
n.toLowerCase == "connection" && v.toLowerCase == "keep-alive"
|
||||
})
|
||||
}
|
||||
socket write OKResponse.bytes(rsp).compact
|
||||
if (!rsp.keepAlive) socket.close()
|
||||
|
|
@ -64,7 +70,8 @@ object HttpServer {
|
|||
//#actor-companion
|
||||
|
||||
//#request-class
|
||||
case class Request(meth: String, path: List[String], query: Option[String], httpver: String, headers: List[Header], body: Option[ByteString])
|
||||
case class Request(meth: String, path: List[String], query: Option[String],
|
||||
httpver: String, headers: List[Header], body: Option[ByteString])
|
||||
case class Header(name: String, value: String)
|
||||
//#request-class
|
||||
|
||||
|
|
@ -118,13 +125,15 @@ object HttpIteratees {
|
|||
|
||||
//#read-path
|
||||
def readPath = {
|
||||
def step(segments: List[String]): IO.Iteratee[List[String]] = IO peek 1 flatMap {
|
||||
case PATH ⇒ IO drop 1 flatMap (_ ⇒ readUriPart(pathchar) flatMap (segment ⇒ step(segment :: segments)))
|
||||
case _ ⇒ segments match {
|
||||
case "" :: rest ⇒ IO Done rest.reverse
|
||||
case _ ⇒ IO Done segments.reverse
|
||||
def step(segments: List[String]): IO.Iteratee[List[String]] =
|
||||
IO peek 1 flatMap {
|
||||
case PATH ⇒ IO drop 1 flatMap (_ ⇒ readUriPart(pathchar) flatMap (
|
||||
segment ⇒ step(segment :: segments)))
|
||||
case _ ⇒ segments match {
|
||||
case "" :: rest ⇒ IO Done rest.reverse
|
||||
case _ ⇒ IO Done segments.reverse
|
||||
}
|
||||
}
|
||||
}
|
||||
step(Nil)
|
||||
}
|
||||
//#read-path
|
||||
|
|
@ -140,14 +149,17 @@ object HttpIteratees {
|
|||
val alpha = Set.empty ++ ('a' to 'z') ++ ('A' to 'Z') map (_.toByte)
|
||||
val digit = Set.empty ++ ('0' to '9') map (_.toByte)
|
||||
val hexdigit = digit ++ (Set.empty ++ ('a' to 'f') ++ ('A' to 'F') map (_.toByte))
|
||||
val subdelim = Set('!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=') map (_.toByte)
|
||||
val subdelim = Set('!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=') map
|
||||
(_.toByte)
|
||||
val pathchar = alpha ++ digit ++ subdelim ++ (Set(':', '@') map (_.toByte))
|
||||
val querychar = pathchar ++ (Set('/', '?') map (_.toByte))
|
||||
|
||||
def readUriPart(allowed: Set[Byte]): IO.Iteratee[String] = for {
|
||||
str ← IO takeWhile allowed map ascii
|
||||
pchar ← IO peek 1 map (_ == PERCENT)
|
||||
all ← if (pchar) readPChar flatMap (ch ⇒ readUriPart(allowed) map (str + ch + _)) else IO Done str
|
||||
all ← if (pchar) readPChar flatMap (ch ⇒ readUriPart(allowed) map
|
||||
(str + ch + _))
|
||||
else IO Done str
|
||||
} yield all
|
||||
|
||||
def readPChar = IO take 3 map {
|
||||
|
|
@ -173,15 +185,18 @@ object HttpIteratees {
|
|||
value ← IO takeUntil CRLF flatMap readMultiLineValue
|
||||
} yield Header(ascii(name), ascii(value))
|
||||
|
||||
def readMultiLineValue(initial: ByteString): IO.Iteratee[ByteString] = IO peek 1 flatMap {
|
||||
case SP ⇒ IO takeUntil CRLF flatMap (bytes ⇒ readMultiLineValue(initial ++ bytes))
|
||||
case _ ⇒ IO Done initial
|
||||
}
|
||||
def readMultiLineValue(initial: ByteString): IO.Iteratee[ByteString] =
|
||||
IO peek 1 flatMap {
|
||||
case SP ⇒ IO takeUntil CRLF flatMap (
|
||||
bytes ⇒ readMultiLineValue(initial ++ bytes))
|
||||
case _ ⇒ IO Done initial
|
||||
}
|
||||
//#read-headers
|
||||
|
||||
//#read-body
|
||||
def readBody(headers: List[Header]) =
|
||||
if (headers.exists(header ⇒ header.name == "Content-Length" || header.name == "Transfer-Encoding"))
|
||||
if (headers.exists(header ⇒ header.name == "Content-Length" ||
|
||||
header.name == "Transfer-Encoding"))
|
||||
IO.takeAll map (Some(_))
|
||||
else
|
||||
IO Done None
|
||||
|
|
@ -210,7 +225,8 @@ object OKResponse {
|
|||
date ++= ByteString(new java.util.Date().toString) ++= CRLF ++=
|
||||
server ++= CRLF ++=
|
||||
contentLength ++= ByteString(rsp.body.length.toString) ++= CRLF ++=
|
||||
connection ++= (if (rsp.keepAlive) keepAlive else close) ++= CRLF ++= CRLF ++= rsp.body result
|
||||
connection ++= (if (rsp.keepAlive) keepAlive else close) ++= CRLF ++=
|
||||
CRLF ++= rsp.body result
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue