Rack is a common interface to interact with different ruby server
to understand the concept of http server, we just need to search for some ruby code that implement a tcp server without any library.
here is a potato for you
server = TCPServer.new('localhost', 12345)
loop do
socket = server.accept
request = socket.gets
response = "This is a server response"
socket.print "HTTP/1.1 200 OK\r\n" +
"Content-Type: text/plain\r\n" +
"Content-Length: #{response.bytesize}\r\n" +
"Connection: close\r\n"
socket.print "\r\n"
socket.print response
socket.close
end
For this snippet, you can handle 1 single request at a time (real single request) but the world doesn't allow you to do that, you need to serve response to user as quick as possible. That's why many ruby web server were invented.
These web servers try to handle multiple requests as the same time, by forking to many processes, or making more threads, or queuing requests... But the core idea is just server -> socket, then user send request to this socket and receive respone from this socket, then socket can be closed, and server will open a new socket for the next request.
So there are many ruby servers, their implements in a different way. Ofcourse, their intefaces won't be the same. But we are web developer, and we are rubyists, we just need a common interface for all of them. And also, we want to focus on handle the request, serving the response; other works should be taken care by someone else. Yes, we want to be able to experience different webserver to figgure out which one is the most suitable for a specific purpose. These are the reasons Rack was written.
Rack allows us to config the webserver name, then when we boot up the project by rack up command (or some thing built on top of rack), it will load the matched web server, create server instances and open the socket for receive user request.
Ofcourse it does more than that. Rack can do SSL, act like a vhost, become a proxy,... Also it supports multiple middlewares, like common logger, filereaper. Middleware is a class that is run before we process the user request.