尝试解析HTTP请求时Ruby Web服务器挂起
我正在进行一项任务,要求我在Ruby中实现Web服务器而不使用任何库。我有一个基本的服务器设置来返回Hello World
响应,我准备进入下一步。
I am working on an assignment which requires me to implement a web server in Ruby without using any libraries. I have a basic server setup to return a "Hello World"
response and I am ready to move onto the next step.
下一步是根据HTTP请求生成HTTP响应。这是我遇到麻烦的地方,似乎我的程序中的而
循环导致服务器挂起。
The next step is to generate HTTP Responses based on the HTTP Requests. This is where I am having trouble, it seems that the while
loop in my program causes the server to hang.
Web服务器的代码:
The code for the web server:
require 'socket'
server = TCPServer.new('localhost', 2345)
http_request = ""
loop do
socket = server.accept
request = socket.gets
while line = socket.gets
puts line
http_request << line
end
response = "Hello World!\n"
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
puts "DONE with while loop!"
socket.close
end
在上面的代码中,我试图将HTTP请求放入字符串 http_request
并解析它以确定我想要生成哪个HTTP响应。我在没有while循环的情况下测试了我的代码,并且能够使用 localhost:2345 / test
在我的浏览器中访问Hello World页面。但是,通过添加而
循环,我无法再加载页面和字符串DONE with while loop!
永远不会打印到控制台中。
In the code above, I am trying to put the HTTP request into a the string http_request
and parse that to determine which HTTP response I want to generate. I have tested my code without the while loop and was able to reach the Hello World page in my browser using localhost:2345/test
. However, with the addition of the while
loop, I am no longer able to load the page and the string "DONE with while loop!"
is never printed into the console.
有谁知道为什么我的网络服务器挂了?我接近这个问题完全错了吗?
Does anyone know why my web server is hanging? Am I approaching the problem entirely wrong?
您对 socket.gets $ c $的致电c>在发送完所有请求后将继续等待更多数据,阻止任何进一步的进展。它无法知道这是一个HTTP调用并且请求已经完成。
Your call to socket.gets
will continue to wait for more data after all the request has been sent, blocking any further progress. It has no way of knowing that this is a HTTP call and the the request has finished.
A HTTP请求由标题组成,然后是一个空白行,表示标题的结尾。您的代码需要注意这一空白行。您可以通过将循环更改为以下内容来执行此操作:
A HTTP request consists of the headers and then a blank line indicating the end of the headers. Your code needs to look out for this blank line. You could do this by changing your loop to something like this:
while (line = socket.gets).chomp != ''
这适用于没有正文的请求,例如 GET
s,但在使用正文处理请求时更加困难。在这种情况下,您需要解析 Content-Length
的标头,以便知道从套接字读取多少数据。对于 chunked 请求,它甚至更复杂,您可能不需要在任务中走得那么远。
This will work for requests that don’t have a body, such as GET
s, but things are more difficult when processing requests with bodies. In that case you will need to parse the headers for the Content-Length
in order to know how much data to read from the socket. It is even more complex still for chunked requests, you may not need to go that far in your assignment.