I posted what I made while I was a disciple, so I will write it here as well!
In response to the http request sent from the browser (client), the content of the request is returned as it is with the http response! That is the echo server.
(Usually returns html files and images here)
Therefore, the goal is to display a character string such as "GET / ~~" (← request statement) on the browser.
httpserver.
import java.net.ServerSocket
import java.net.Socket
import java.io
import java.io.InputStream
import java.nio.charset.StandardCharsets
object HTTPServer {
def main(args: Array[String]): Unit = {
println("Hello HTTP Server!Strat----->")
//Create a server socket and bind the port number
val serverSocket = new ServerSocket(8000)
println("Serving HTTP on localhost port 8000 ...")
while (true) {
//Server socket continues to accept and wait
val socket = serverSocket.accept()
//input--Read http request
val input = socket.getInputStream
def readUntilEnd(is: InputStream, acc: List[Int] = Nil):String ={
is.read :: acc match {
case x if x.take(4) == List(10,13,10,13) => x.reverse.map(_.toChar).mkString //10,13 is a line break
case x => readUntilEnd(is, x)
}
}
//output--Send back http request
val output = socket.getOutputStream
val CRLF = "\r\n"
val responseBody = readUntilEnd(input)
val responseBodySize = responseBody.length
val responseText = "HTTP/1.1 200 OK" + CRLF +
"Content-Length: " + responseBodySize + CRLF +
"Content-Type: text/plain" + CRLF +
CRLF +
responseBody
output.write(responseText.getBytes(StandardCharsets.UTF_8))
//Close socket
input.close()
output.close()
}
serverSocket.close()
}
}
}
Basically, if I could find a method that would do what I wanted to do from here, I felt that it would be nearing completion. And if you understand the concept of this communication, the significance of the socket, and how it works, you can read the code.
text val input = socket.getInputStream
When you create an input stream with, information (http requests) will come through the tunnel.
I created a readUntilEnd method that reads it character by character and finally returns it as a single string of type String.
text def readUntilEnd(is: InputStream, acc: List[Int] = Nil):String ={ is.read :: acc match { case x if x.take (4) == List (10,13,10,13) => x.reverse.map (_.toChar) .mkString // 10,13 is a line break case x => readUntilEnd(is, x) } }
What is done in the pattern matching here is that if two line breaks are sent at the end of the http request statement, it is a conditional branch that stops recursion.
Since each character enters the list as a Byte type, at the end, turn it over (reverse) to make it a character, and use mkString to squeeze it into one character string from the list.
Similarly, create an output stream and pass the information according to the http response template. You don't have to have all the headers here, just the ones you need.
Put the necessary items in the response body into variables one by one in String type, convert them to Byte type at once with responseText, and apply the write method to the socket, and it will be sent as an http response!
Finally close the socket.
It feels pretty powerful, but the http server does this.
I think again that not everything is magically manipulated in an instant. Lol
Recommended Posts