2015-09-19 43 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

我明白了...謝謝你對如何處理身體請求的回答和建議!我認爲請求行和標題是我需要的這個任務:)。 –