尝试解析HTTP请求时Ruby Web服务器挂起 [英] Ruby Web Server Hanging When Trying To Parse HTTP Request

查看:225
本文介绍了尝试解析HTTP请求时Ruby Web服务器挂起的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am working on an assignment which requires me to implement a web server in Ruby without using any libraries. I have a basic server setup to return a "Hello World" response and I am ready to move onto the next step.

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

The next step is to generate HTTP Responses based on the HTTP Requests. This is where I am having trouble, it seems that the while loop in my program causes the server to hang.

Web服务器的代码:

The code for the web server:

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

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. 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. However, with the addition of the while loop, I am no longer able to load the page and the string "DONE with while loop!" is never printed into the console.

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

Does anyone know why my web server is hanging? Am I approaching the problem entirely wrong?

推荐答案

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

Your call to socket.gets will continue to wait for more data after all the request has been sent, blocking any further progress. It has no way of knowing that this is a HTTP call and the the request has finished.

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

A HTTP request consists of the headers and then a blank line indicating the end of the headers. 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 != ''

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

This will work for requests that don’t have a body, such as GETs, but things are more difficult when processing requests with bodies. 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. It is even more complex still for chunked requests, you may not need to go that far in your assignment.

这篇关于尝试解析HTTP请求时Ruby Web服务器挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆