ruby - rails - Рубиновый веб-сервер, зависающий при попытке проанализировать HTTP-запрос



ruby web server (1)

Я работаю над заданием, которое требует, чтобы я реализовал веб-сервер в Ruby без использования каких-либо библиотек. У меня есть базовая настройка сервера, чтобы вернуть ответ "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 и смог получить страницу Hello World в моем браузере, используя localhost:2345/test . Однако с добавлением цикла while я больше не могу загружать страницу и строку "DONE with while loop!" никогда не печатается в консоли.

Кто-нибудь знает, почему мой веб-сервер висит? Неужели я совершенно неправильно подхожу к проблеме?


Ваш вызов socket.gets будет продолжать ждать дополнительных данных после отправки всего запроса, блокируя дальнейший прогресс. Он не знает, что это HTTP-вызов, и запрос завершен.

Запрос HTTP состоит из заголовков, а затем пустой строки, указывающей конец заголовков. Ваш код должен искать эту пустую строку. Вы можете сделать это, изменив свой цикл на что-то вроде этого:

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

Это будет работать для запросов, у которых нет тела, такого как GET , но при обработке запросов с помощью тел все сложнее. В этом случае вам нужно будет разобрать заголовки для Content-Length , чтобы узнать, сколько данных нужно читать из сокета. Еще более сложным для чанк- запросов является то, что вам не нужно заходить так далеко в ваше задание.





web