Class: Rbkb::Http::ChunkedBody

Inherits:
Body
  • Object
show all
Defined in:
lib/rbkb/http/body.rb

Overview

ChunkedBody is designed for handling an HTTP body when using a “Transfer-Encoding: chunked” HTTP header.

Constant Summary collapse

DEFAULT_CHUNK_SIZE =
2048

Instance Attribute Summary

Attributes inherited from Body

#base, #expect_length

Instance Method Summary collapse

Methods inherited from Body

#capture_complete?, #data, #data=, #get_content_length, #get_content_type, #initialize, parse, #reset_capture, #reset_capture!

Methods included from CommonInterface

#_common_init, #opts, #opts=

Constructor Details

This class inherits a constructor from Rbkb::Http::Body

Instance Method Details

#capture(str) ⇒ Object

Throws :expect_length with ‘true’ when given incomplete data and expects to be called again with more body data to parse.

The caller can also detect this condition by checking the expect_length attribute but must still handle the throw().

See also reset_capture and reset_capture!



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/rbkb/http/body.rb', line 157

def capture(str)
  # chunked encoding is gross...
  if @expect_length
    sio = StringIO.new(@last_chunk.to_s + str)
  else
    sio = StringIO.new(str)
    self.data=""
  end
  @last_chunk = nil

  @expect_length = true
  while not sio.eof?
    unless m=/^([a-fA-F0-9]+)\s*(;[[:print:]\s]*)?\r?\n$/.match(line=sio.readline)
      raise "invalid chunk at #{line.chomp.inspect}"
    end
    if (chunksz = m[1].hex) == 0
      @expect_length = false
      # XXX ignore Trailer headers
      break
    end

    if ( (not sio.eof?) and 
         (chunk=sio.read(chunksz)) and 
         chunk.size == chunksz and 
         (not sio.eof?) and (extra = sio.readline) and
         (not sio.eof?) and (extra << sio.readline)
       )
      if extra =~ /^\r?\n\r?\n$/
        yield(chunk) if block_given?
        self << chunk
      else
        raise "expected CRLF"
      end
    else
      @last_chunk = line + chunk.to_s + extra.to_s
      break
    end
  end
  throw(:expect_length, @expect_length) if @expect_length
  return self
end

#to_raw(csz = nil) {|_self, out.last| ... } ⇒ Object

Yields:

  • (_self, out.last)

Yield Parameters:



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/rbkb/http/body.rb', line 200

def to_raw(csz=nil)
  csz ||= (@opts[:output_chunk_size] || DEFAULT_CHUNK_SIZE)
  unless csz.kind_of? Integer and csz > 0
    raise "chunk size must be an integer >= 1"
  end

  out=[]
  i=0
  while i <= self.size
    chunk = self[i, csz]
    out << "#{chunk.size.to_s(16)}\r\n#{chunk}\r\n\r\n"
    yield(self, out.last) if block_given?
    i+=csz
  end
  out << "0\r\n"
  yield(self, out.last) if block_given?
  return out.join
end