-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This solves #13.
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,47 +17,85 @@ | |
*/ | ||
package com.lascala.http | ||
|
||
import com.lascala.http.HttpConstants._ | ||
|
||
import akka.util.{ ByteString, ByteStringBuilder } | ||
import HttpConstants._ | ||
import java.io.File | ||
import org.apache.tika.Tika | ||
import java.io.FileInputStream | ||
import java.util.Date | ||
import java.util.Locale | ||
import java.text.SimpleDateFormat | ||
import java.util.TimeZone | ||
|
||
trait HttpResponse { | ||
def lastModified: Date = null | ||
def body: ByteString | ||
def status: ByteString | ||
def reason: ByteString | ||
def mimeType: String | ||
def shouldKeepAlive: Boolean | ||
|
||
// default charset to utf-8 for now but should be editable in the future | ||
def contentType = if (!mimeType.isEmpty) ByteString(s"Content-Type: ${mimeType}") else ByteString("") | ||
def contentType = ByteString(s"Content-Type: ${mimeType}") | ||
def cacheControl = ByteString("Cache-Control: no-cache") | ||
def contentLength = ByteString(s"Content-Length: ${body.length.toString}") | ||
} | ||
|
||
object HttpResponse { | ||
val version = ByteString("HTTP/1.1") | ||
val date = ByteString("Date: ") | ||
val server = ByteString("Server: lascala-http") | ||
val connection = ByteString("Connection: ") | ||
val keepAlive = ByteString("Keep-Alive") | ||
val close = ByteString("Close") | ||
|
||
val date = ByteString("Date: ") | ||
val lastModified = ByteString("Last-Modified: ") | ||
|
||
def httpDateFormat = { | ||
val dateFormat = new SimpleDateFormat(RFC1123_DATE_PATTERN, Locale.ENGLISH) | ||
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")) | ||
dateFormat | ||
} | ||
|
||
def httpDate(date: Date) = ByteString(httpDateFormat.format(date)) | ||
|
||
def bytes(rsp: HttpResponse) = { | ||
(new ByteStringBuilder ++= | ||
version ++= SP ++= rsp.status ++= SP ++= rsp.reason ++= CRLF ++= | ||
(if(rsp.body.nonEmpty) rsp.contentType ++ CRLF else ByteString.empty) ++= | ||
(if(rsp.body.nonEmpty || rsp.mimeType.nonEmpty) rsp.contentType ++ CRLF else ByteString.empty) ++= | ||
rsp.cacheControl ++= CRLF ++= | ||
date ++= ByteString(new java.util.Date().toString) ++= CRLF ++= | ||
date ++= httpDate(new Date) ++= CRLF ++= | ||
Option(rsp.lastModified).map(lastModified ++ httpDate(_) ++ CRLF).getOrElse(ByteString("")) ++= | ||
server ++= CRLF ++= | ||
rsp.contentLength ++= CRLF ++= | ||
connection ++= (if (rsp.shouldKeepAlive) keepAlive else close) ++= CRLF ++= CRLF ++= rsp.body).result | ||
} | ||
} | ||
|
||
case class OKFileResponse(file: File, shouldKeepAlive: Boolean = true) extends HttpResponse { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
rampart81
|
||
def readFile(file: File) = { | ||
val resource = new Array[Byte](file.length.toInt) | ||
val in = new FileInputStream(file) | ||
in.read(resource) | ||
in.close() | ||
ByteString(resource) | ||
} | ||
val body = readFile(file) | ||
val mimeType = new Tika().detect(file) | ||
val status = ByteString("200") | ||
val reason = ByteString("OK") | ||
override def lastModified = new Date(file.lastModified) | ||
} | ||
|
||
case class OKResponse(body: ByteString, shouldKeepAlive: Boolean = true, mimeType: String = "text/html") extends HttpResponse { | ||
val status = ByteString("200") | ||
val reason = ByteString("OK") | ||
} | ||
|
||
case class NotModifiedResponse(body: ByteString = ByteString.empty, shouldKeepAlive: Boolean = false, mimeType: String = "") extends HttpResponse { | ||
val status = ByteString("304") | ||
val reason = ByteString("Not Modified") | ||
} | ||
|
||
case class NotFoundError(body: ByteString = ByteString.empty, shouldKeepAlive: Boolean = false, mimeType: String = "") extends HttpResponse { | ||
val status = ByteString("404") | ||
val reason = ByteString("Not Found") | ||
|
@@ -72,18 +110,3 @@ case class InternalServerError(body: ByteString = ByteString.empty, shouldKeepAl | |
val status = ByteString("500") | ||
val reason = ByteString("Internal Server Error") | ||
} | ||
|
||
/** | ||
* HTTP 상수 모음 | ||
*/ | ||
object HttpConstants { | ||
val SP = ByteString(" ") | ||
val HT = ByteString("\t") | ||
val CRLF = ByteString("\r\n") | ||
val COLON = ByteString(":") | ||
val PERCENT = ByteString("%") | ||
val PATH = ByteString("/") | ||
val QUERY = ByteString("?") | ||
} | ||
|
||
|
File 객체를 받는 OKResponse가 필요해서 부득이 이렇게 분리해버렸는데, OKResponse 하나로 다 처리하는 방법은 없을까요? @codeport/http-pull