Ruby 使用 gets 从套接字请求中读取行导致阻塞
Ruby use gets to read lines from a socket request causes blocking
我目前正在研究 ruby 并制作一个支持套接字的服务器。
现在我需要将套接字请求解析为 HTTP METHOD、URI、VERSION、HEADERS 和 BODY.
我了解到 headers 和 body 之间应该有一个空行,即
GET / HTTP/1.1
Host: localhost:8096
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:41.0) Gecko/20100101 Firefox/41.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.7,zh-CN;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
现在我正在尝试读取每一行并通过
解析它
@request = server.accept
while line = @request.gets
...
parse_request_line(line)
...
parse_header(line)
...
end
但是,当读入最后一个空行后,while 循环会被 gets 阻塞,因为它正在等待更多的输入。
我尝试将上面的代码修改为
@request = server.accept
while line = @request.gets
break if line.to_s.strip.length == 0
...
parse_request_line(line)
...
parse_header(line)
...
end
看起来可行,当遇到一个空行然后打破循环。
但是,当请求包含 body 时,break 将中断读取请求的其余部分,body.
即
获取 / HTTP/1.1
Host: localhost:8096
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:41.0) Gecko/20100101 Firefox/41.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.7,zh-CN;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
# here is an empty line between headers and body
This is a body .... some contents here
1213123123
然后我尝试了 Socket::recv。好像跟gets一样,会阻塞程序继续执行。
我现在不知道如何解决它。
有什么建议吗?
谢谢!
http 请求的结束通常由 body 的长度定义。这通常通过使用 content-length header 或使用分块传输编码(零大小的块结束请求)来给出。有关详细信息,请参阅
http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4.
没有特别的理由相信请求的结束body会发生和行尾,所以使用gets不是一个好主意。
只使用 read
应该就足够了,但是您需要计算您希望出现的字节数,以便您知道何时读完 body。
我目前正在研究 ruby 并制作一个支持套接字的服务器。 现在我需要将套接字请求解析为 HTTP METHOD、URI、VERSION、HEADERS 和 BODY.
我了解到 headers 和 body 之间应该有一个空行,即
GET / HTTP/1.1
Host: localhost:8096
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:41.0) Gecko/20100101 Firefox/41.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.7,zh-CN;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
现在我正在尝试读取每一行并通过
解析它@request = server.accept
while line = @request.gets
...
parse_request_line(line)
...
parse_header(line)
...
end
但是,当读入最后一个空行后,while 循环会被 gets 阻塞,因为它正在等待更多的输入。
我尝试将上面的代码修改为
@request = server.accept
while line = @request.gets
break if line.to_s.strip.length == 0
...
parse_request_line(line)
...
parse_header(line)
...
end
看起来可行,当遇到一个空行然后打破循环。 但是,当请求包含 body 时,break 将中断读取请求的其余部分,body.
即 获取 / HTTP/1.1
Host: localhost:8096
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:41.0) Gecko/20100101 Firefox/41.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.7,zh-CN;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
# here is an empty line between headers and body
This is a body .... some contents here
1213123123
然后我尝试了 Socket::recv。好像跟gets一样,会阻塞程序继续执行。 我现在不知道如何解决它。 有什么建议吗?
谢谢!
http 请求的结束通常由 body 的长度定义。这通常通过使用 content-length header 或使用分块传输编码(零大小的块结束请求)来给出。有关详细信息,请参阅 http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4.
没有特别的理由相信请求的结束body会发生和行尾,所以使用gets不是一个好主意。
只使用 read
应该就足够了,但是您需要计算您希望出现的字节数,以便您知道何时读完 body。