Mercurial > maze-src
comparison 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 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:1eef88068f9f |
|---|---|
| 1 require 'net/http/server/stream' | |
| 2 | |
| 3 require 'net/protocol' | |
| 4 require 'stringio' | |
| 5 | |
| 6 module Net | |
| 7 class HTTP < Protocol | |
| 8 module Server | |
| 9 # | |
| 10 # Handles reading and writing to Chunked Transfer-Encoded streams. | |
| 11 # | |
| 12 # @since 0.2.0 | |
| 13 # | |
| 14 class ChunkedStream < Stream | |
| 15 | |
| 16 # | |
| 17 # Initializes the chuked stream. | |
| 18 # | |
| 19 # @param [#read, #write, #flush] socket | |
| 20 # The socket to read from and write to. | |
| 21 # | |
| 22 def initialize(socket) | |
| 23 super(socket) | |
| 24 | |
| 25 @buffer = '' | |
| 26 end | |
| 27 | |
| 28 # | |
| 29 # Reads a chunk from the stream. | |
| 30 # | |
| 31 # @param [Integer] length | |
| 32 # | |
| 33 # @param [#<<] buffer | |
| 34 # The optional buffer to append the data to. | |
| 35 # | |
| 36 # @return [String, nil] | |
| 37 # A chunk from the stream. | |
| 38 # | |
| 39 # @raise [ArgumentError] | |
| 40 # The buffer did not respond to `#<<`. | |
| 41 # | |
| 42 # @since 0.2.0 | |
| 43 # | |
| 44 def read(length=4096,buffer='') | |
| 45 unless buffer.respond_to?(:<<) | |
| 46 raise(ArgumentError,"buffer must respond to #<<") | |
| 47 end | |
| 48 | |
| 49 until @buffer.length >= length | |
| 50 length_line = @socket.readline("\r\n").chomp | |
| 51 chunk_length = length_line.split(';',2).first.to_i(16) | |
| 52 | |
| 53 # read the chunk | |
| 54 @buffer << @socket.read(chunk_length) | |
| 55 | |
| 56 # chomp the terminating CRLF | |
| 57 @socket.read(2) | |
| 58 | |
| 59 # end-of-stream | |
| 60 break if chunk_length == 0 | |
| 61 end | |
| 62 | |
| 63 # clear the buffer before appending | |
| 64 buffer.replace('') | |
| 65 | |
| 66 unless @buffer.empty? | |
| 67 # empty a slice of the buffer | |
| 68 buffer << @buffer.slice!(0,length) | |
| 69 return buffer | |
| 70 end | |
| 71 end | |
| 72 | |
| 73 # | |
| 74 # Writes data to the chunked stream. | |
| 75 # | |
| 76 # @param [String] data | |
| 77 # The data to write to the stream. | |
| 78 # | |
| 79 # @return [Integer] | |
| 80 # The length of the data written. | |
| 81 # | |
| 82 # @since 0.2.0 | |
| 83 # | |
| 84 def write(data) | |
| 85 length = data.length | |
| 86 | |
| 87 # do not write empty chunks | |
| 88 unless length == 0 | |
| 89 # write the chunk length | |
| 90 @socket.write("%X\r\n" % length) | |
| 91 | |
| 92 # write the data | |
| 93 @socket.write(data) | |
| 94 @socket.write("\r\n") | |
| 95 @socket.flush | |
| 96 end | |
| 97 | |
| 98 return length | |
| 99 end | |
| 100 | |
| 101 # | |
| 102 # Closes the chunked stream. | |
| 103 # | |
| 104 # @since 0.2.0 | |
| 105 # | |
| 106 def close | |
| 107 # last chunk | |
| 108 @socket.write("0\r\n\r\n") | |
| 109 @socket.flush | |
| 110 end | |
| 111 | |
| 112 end | |
| 113 end | |
| 114 end | |
| 115 end |
