Reputation: 568
If I run the following code:
require 'stringio'
chunked_data = StringIO.new("7\r\nHello, \r\n6\r\nworld!\r\n0\r\n")
data = ""
until chunked_data.eof?
if chunk_head = chunked_data.gets("\r\n")
print chunk_head
if chunk = chunked_data.read(chunk_head.to_i)
print chunk
data << chunk
end
end
end
I get this output:
7
Hello,
6
world!
0
According to the docs, the gets
method takes a separator and returns the next line based on that separator. If I replace the \r\n
in the string and separator with .
, then the separator functionality seems to no longer work and I get this:
7.Hello, .6.world!.0.
What's going on?
Upvotes: 2
Views: 339
Reputation: 114138
To see what's actually going on, let's replace print
with a more explicit output:
require 'stringio'
def parse(chunked_data, separator)
data = ""
until chunked_data.eof?
if chunk_head = chunked_data.gets(separator)
puts "chunk_head: #{chunk_head.inspect}"
if chunk = chunked_data.read(chunk_head.to_i)
puts " chunk: #{chunk.inspect}"
data << chunk
end
end
end
data
end
result = parse(StringIO.new("7\r\nHello, \r\n6\r\nworld!\r\n0\r\n"), "\r\n")
puts " result: #{result.inspect}"
Output:
chunk_head: "7\r\n"
chunk: "Hello, "
chunk_head: "\r\n"
chunk: ""
chunk_head: "6\r\n"
chunk: "world!"
chunk_head: "\r\n"
chunk: ""
chunk_head: "0\r\n"
chunk: ""
Now with a .
:
result = parse(StringIO.new("7.Hello, .6.world!.0."), ".")
puts " result: #{result.inspect}"
Output:
chunk_head: "7."
chunk: "Hello, "
chunk_head: "."
chunk: ""
chunk_head: "6."
chunk: "world!"
chunk_head: "."
chunk: ""
chunk_head: "0."
chunk: ""
result: "Hello, world!"
As you can see, it works either way and the result is identical.
Although the result is correct, there seems to be a bug in your code: you don't read the separator after chunk
. This can be fixed by adding a chunked_data.gets(separator)
or chunked_data.read(separator.bytesize)
after the if/end
block:
def parse(chunked_data, separator)
data = ""
until chunked_data.eof?
if chunk_head = chunked_data.gets(separator)
puts "chunk_head: #{chunk_head.inspect}"
if chunk = chunked_data.read(chunk_head.to_i)
puts " chunk: #{chunk.inspect}"
data << chunk
end
chunked_data.read(separator.bytesize)
end
end
data
end
result = parse(StringIO.new("7.Hello, .6.world!.0."), ".")
puts " result: #{result.inspect}"
Output:
chunk_head: "7."
chunk: "Hello, "
chunk_head: "6."
chunk: "world!"
chunk_head: "0."
chunk: ""
result: "Hello, world!"
That looks better.
Upvotes: 2