尝试解析HTTP请求时,Ruby Web服务器挂起

时间:2015-09-19 08:11:22

标签: ruby sockets http web

我正在进行一项任务,要求我在Ruby中实现Web服务器而不使用任何库。我有一个基本的服务器设置来返回"Hello World"响应,我准备进入下一步。

下一步是根据HTTP请求生成HTTP响应。这是我遇到麻烦的地方,似乎程序中的while循环导致服务器挂起。

网络服务器的代码:

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页面。但是,通过添加while循环,我无法再加载页面,并且字符串"DONE with while loop!"永远不会打印到控制台中。

有谁知道为什么我的网络服务器挂了?我接近这个问题完全错了吗?

1 个答案:

答案 0 :(得分:0)

在发送完所有请求后,您对socket.gets的呼叫将继续等待更多数据,阻止任何进一步的进展。它无法知道这是一个HTTP调用,并且请求已经完成。

HTTP request由标题组成,然后是一个空白行,表示标题的结尾。您的代码需要注意这一空白行。您可以通过将循环更改为以下内容来完成此操作:

while (line = socket.gets).chomp != ''

这适用于没有正文的请求,例如GET,但在使用正文处理请求时更加困难。在这种情况下,您需要解析Content-Length的标头,以便知道从套接字读取多少数据。对于chunked请求,它仍然更加复杂,您可能不需要在作业中走得那么远。