object WebServer {
def main(args: Array[String]) {
println("Server listening...")
val port = getPort(args)
val socket = new ServerSocket(port)
process(port, socket)
}
private def process(port: Int, socket: ServerSocket) {
while (true) {
val connection = socket.accept
val request = new HttpRequest(connection)
(new Thread(request)).start
}
}
private def getPort(args: Array[String]) = {
if (args.length > 0)
args(0).toInt
else
Configs.HTTP_PORT
}
}
object Configs {
val CRLF = "\r\n"
val HTTP_PORT = 8080
val BUF_SIZE = 8192
val MAX_OBJECT_SIZE = 100000
val HTTP_404 = """
Object not found!
Error 404
www.sawp.com.br
"""
}
class HttpRequest(s: Socket) extends Runnable {
private val is = s.getInputStream
private val os = new DataOutputStream(s.getOutputStream)
private val br = new BufferedReader(new InputStreamReader(is))
private val requestLineHTTPRequest = br.readLine
override def run {
showServerMessage()
val fileName = extractFilenameFromRequestLine(requestLineHTTPRequest)
try {
val fis = new FileInputStream(fileName)
processRequestedFile(fis, fileName)
} catch {
case e: FileNotFoundException =>
processFileNotFound()
case e: Exception => println("Error -> HttpRequest: " + e)
}
closeStreamsAndSockets()
println("-.-" * 20)
this.finalize
}
private def processRequestedFile(fis: FileInputStream, fn: String) {
println("Request file: " + fn)
val statusLine = "HTTP/1.0 200 OK" + Configs.CRLF
val contentTypeLine = "Content-Type: " + contentType(fn) + Configs.CRLF
sendContents(statusLine: String, contentTypeLine: String)
sendBytes(fis, os)
fis.close
}
private def processFileNotFound() {
println("File not found request")
val statusLine = "HTTP/1.0 404 Not Found" + Configs.CRLF
val contentTypeLine = "Content-Type: text/html" + Configs.CRLF
val entityBody = Configs.HTTP_404
sendContents(statusLine, contentTypeLine)
sendEntityBody(entityBody)
}
private def sendContents(statusLine: String, contentTypeLine: String) {
os.writeBytes(statusLine)
os.writeBytes(contentTypeLine)
os.writeBytes(Configs.CRLF)
}
private def sendEntityBody(entityBody: String) {
os.writeBytes(entityBody)
}
private def closeStreamsAndSockets() {
os.close
br.close
s.close
}
private def showServerMessage() {
println("Request received:")
println(requestLineHTTPRequest)
var headerLine = br.readLine
while (headerLine.length != 0) {
println(headerLine)
headerLine = br.readLine
}
}
private def extractFilenameFromRequestLine(request: String) = {
val tokens = new StringTokenizer(request)
tokens.nextToken
val fileName = "." + tokens.nextToken
fileName
}
private def sendBytes(fis: FileInputStream, os: OutputStream) {
val buffer = new Array[Byte](1024)
var bytes = 0
do {
os.write(buffer, 0, bytes)
bytes = fis.read(buffer)
} while (bytes >= 0)
}
private def contentType(fileName: String): String =
if (fileName.endsWith(".htm") || fileName.endsWith(".html"))
"text/html"
else
"application/octet-stream"
}