Mercurial > maze-src
diff net/http/server/chunked_stream.rb @ 0:1eef88068f9f tip
initial commit of maze game source
| author | ferencd |
|---|---|
| date | Sun, 15 Sep 2019 11:46:47 +0200 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/net/http/server/chunked_stream.rb Sun Sep 15 11:46:47 2019 +0200 @@ -0,0 +1,115 @@ +require 'net/http/server/stream' + +require 'net/protocol' +require 'stringio' + +module Net + class HTTP < Protocol + module Server + # + # Handles reading and writing to Chunked Transfer-Encoded streams. + # + # @since 0.2.0 + # + class ChunkedStream < Stream + + # + # Initializes the chuked stream. + # + # @param [#read, #write, #flush] socket + # The socket to read from and write to. + # + def initialize(socket) + super(socket) + + @buffer = '' + end + + # + # Reads a chunk from the stream. + # + # @param [Integer] length + # + # @param [#<<] buffer + # The optional buffer to append the data to. + # + # @return [String, nil] + # A chunk from the stream. + # + # @raise [ArgumentError] + # The buffer did not respond to `#<<`. + # + # @since 0.2.0 + # + def read(length=4096,buffer='') + unless buffer.respond_to?(:<<) + raise(ArgumentError,"buffer must respond to #<<") + end + + until @buffer.length >= length + length_line = @socket.readline("\r\n").chomp + chunk_length = length_line.split(';',2).first.to_i(16) + + # read the chunk + @buffer << @socket.read(chunk_length) + + # chomp the terminating CRLF + @socket.read(2) + + # end-of-stream + break if chunk_length == 0 + end + + # clear the buffer before appending + buffer.replace('') + + unless @buffer.empty? + # empty a slice of the buffer + buffer << @buffer.slice!(0,length) + return buffer + end + end + + # + # Writes data to the chunked stream. + # + # @param [String] data + # The data to write to the stream. + # + # @return [Integer] + # The length of the data written. + # + # @since 0.2.0 + # + def write(data) + length = data.length + + # do not write empty chunks + unless length == 0 + # write the chunk length + @socket.write("%X\r\n" % length) + + # write the data + @socket.write(data) + @socket.write("\r\n") + @socket.flush + end + + return length + end + + # + # Closes the chunked stream. + # + # @since 0.2.0 + # + def close + # last chunk + @socket.write("0\r\n\r\n") + @socket.flush + end + + end + end + end +end
