2015-09-19 48 views
2

我的工作要求我在Ruby中实现一个Web服务器,而无需使用任何图书馆的任务。我有一个基本的服务器设置来返回"Hello World"响应,我准备好进入下一步。Ruby的Web服务器挂在试图解析HTTP请求

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

Web服务器的代码:

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!"也不会被打印到控制台中。

有谁知道为什么我的Web服务器是挂?我接近完全错误的问题吗?

回答

0

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

HTTP request由报头,然后一个空行指示报头的末尾。你的代码需要注意这个空行。你可以通过改变你的循环,像这样做:

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

这对于不具有主体的请求,如GET的工作,但处理与机构请求时会较为困难。在这种情况下,您需要解析Content-Length的头文件,以便知道从套接字读取多少数据。对于chunked的请求,它更加复杂,你可能不需要在你的任务中走得太远。

+0

所以没有一个通用的解决方案,让我保存整个请求转换成'string'以后可以解析?我打算将整个HTTP请求存储在'string'中,解析它以确定我需要在HTTP响应中发回的内容。 –

+0

@CrystalKemper一般不会,因为你需要知道请求体的末尾是为了停止读取数据,否则你最终只会阻塞并等待更多。您可以一次读取标题,然后处理它们。 – matt

+0

我明白了...谢谢你对如何处理身体请求的回答和建议!我认为请求行和标题是我需要的这个任务:)。 –