简体   繁体   English

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

[英]Ruby Web Server Hanging When Trying To Parse HTTP Request

I am working on an assignment which requires me to implement a web server in Ruby without using any libraries. 我正在做一项作业,需要我在Ruby中实现Web服务器而不使用任何库。 I have a basic server setup to return a "Hello World" response and I am ready to move onto the next step. 我有一个基本的服务器设置,可以返回"Hello World"响应,并且可以继续进行下一步了。

The next step is to generate HTTP Responses based on the HTTP Requests. 下一步是根据HTTP请求生成HTTP响应。 This is where I am having trouble, it seems that the while loop in my program causes the server to hang. 这是我遇到麻烦的地方,似乎程序中的while循环导致服务器挂起。

The code for the web server: 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

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. 在上面的代码中,我试图将HTTP请求放入字符串http_request并进行解析以确定我要生成哪个HTTP响应。 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 . 我已经测试了我的代码,而没有while循环,并且能够使用localhost:2345/test浏览器中的Hello World页面。 However, with the addition of the while loop, I am no longer able to load the page and the string "DONE with while loop!" 但是,通过添加while循环,我不再能够加载页面和字符串"DONE with while loop!" is never printed into the console. 永远不会打印到控制台中。

Does anyone know why my web server is hanging? 有人知道为什么我的Web服务器挂起吗? Am I approaching the problem entirely wrong? 我解决这个问题完全错误吗?

Your call to socket.gets will continue to wait for more data after all the request has been sent, blocking any further progress. 发送所有请求后,对socket.gets调用将继续等待更多数据,从而阻止了任何进一步的处理。 It has no way of knowing that this is a HTTP call and the the request has finished. 它无法知道这是一个HTTP调用,并且请求已完成。

A HTTP request consists of the headers and then a blank line indicating the end of the headers. HTTP请求由标头组成,然后由空白行指示标头的末尾。 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 != ''

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. 这将适用于没有主体的请求,例如GET ,但是在处理具有主体的请求时,事情会更加困难。 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. 在这种情况下,您将需要解析Content-Length的标头,以便知道要从套接字读取多少数据。 It is even more complex still for chunked requests, you may not need to go that far in your assignment. 对于分块的请求来说,它甚至更加复杂,您可能不需要在分配中走得那么远。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM