我正在编写一个小型网络服务器。我想阅读HTTP Request
. 它在没有身体参与的情况下起作用。但是当发送正文时,我无法以令人满意的方式阅读正文的内容。
我通过读取来自客户端的数据TCPSocket
。该TCPSocket::gets
方法读取直到接收到正文的数据。HTTP 请求正文的结束没有分隔符或EOF
发送信号。HTTP/1.1 规范 - 第 4.4 节列出了五种获取消息长度的情况。第 1 点)有效。第 2) 点和第 4) 点与我的申请无关。第 5 点)不是一个选项,因为我需要发送回复。
我可以读取该Content-Length
字段的值。read(contentlength)
但是当我试图通过or来“说服” TCPSocket 读取 HTTP 请求的最后一部分时rcv(contentlength)
,我没有成功。逐行阅读,直到\r\n
分隔标题和正文的工作,但在那之后我被卡住了 - 至少在我想要的方式上。
所以我的问题是:
有没有可能像我在代码中想要的那样做?有没有更好的方法来实现我HTTP Request
正确阅读的目标(我真的希望)?
这是可运行的代码。我想工作的部分在评论中。
#!/usr/bin/ruby
require 'socket'
server = TCPServer.new 2000
loop do
Thread.start(server.accept) do |client|
hascontent = false
contentlength = 0
content = ""
request = ""
#This seems to work, but I'm not really happy with it, too much is happening in
#the loop
while(buf = client.readpartial(4096))
request = request + buf
split = request.split("\r\n")
puts request
puts request.dump
puts split.length
puts split.inspect
if(request.index("\r\n\r\n")>0)
break
end
end
#This part is commented out because it doesn't work
=begin
while(line = client.gets)
puts ":" + line
request = request + line
if(line.start_with?("Content-Length"))
hascontent = true
split = line.split(' ')
contentlength = split[1]
end
if(line == "\r\n" and !hascontent)
break
end
if(line == "\r\n" and hascontent)
puts "Trying to get content :P"
puts contentlength
puts content.length
puts client.inspect
#tried read, with and without parameter, rcv, also with and
#without param and their nonblocking couterparts
#where does my thought process go in the wrong direction
while(readin = client.readpartial(contentlength))
puts readin
content = content + readin
end
break
end
end
=end
puts request
client.close
end