Greetings!
Recently I’ve been stuck on a problem serving XML via SSL with
WEBrick.
First problem: whatever document I’ve been returning as a body, client
never got more than 16k. With “keep_alive = true” client just hangs,
with “keep_alive = false” it ended up getting only 16383 bytes of
data. This seems to be OpenSSL limitation which is pretty difficult to
find out though. Anyway, it’s being resolved by lowering buffer sizes
and forcing WEBrick to chop the page with “chunked = true”. Maybe
there’s a point in forcing these buffer sizes when using SSL?
WEBrick::Config::HTTP[:InputBufferSize] = WEBrick::Config::HTTP
[:OutputBufferSize] = 1024
…
def do_GET (req, res)
…
res.chunked = true
…
end
This seemed to solve the first problem. And this was the point where
I’ve encountered the second one, that looks like a bug to me.
I have WEBrick coming with Rails, so maybe this is specific Rails bug.
So… I’ve started to get garbled XML documents. The reason turned out
to be a chunked encoding implementation in “send_body_string”.
remain = body ? @body.bytesize : 0
while buf = @body[@sent_size, @buffer_size]
break if buf.empty?
data = ""
data << format("%x", buf.bytesize) << CRLF
data << buf << CRLF
_write_data(socket, data)
@sent_size += buf.bytesize
end
@sent_size is getting incremented by the amount of BYTES sent, and
then it’s being used as an index in a Unicode @body, which is
incorrect. I’ve changed the code in a following way to make it work:
remain = body ? @body.bytesize : 0
buffer_sliding_pointer = 0
while buf = @body[buffer_sliding_pointer, @buffer_size]
break if @body.size <= buffer_sliding_pointer
data = ""
data << format("%x", buf.bytesize) << CRLF
data << buf << CRLF
_write_data(socket, data)
@sent_size += buf.bytesize
buffer_sliding_pointer += buf.size
end
(Leaving “break if buf.empty?” made the fscker send 4 additional bytes
even though the buffer_sliding_pointer pointed to the end of the
@body, so I had to change it also)
I hope I’ve been of any help!
Thank you.
Sincerely,
Ivan.