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