class

ServerX::AppServer::BodyReader

Inherits IO < Reference < Object

Request body reader: serves from the connection buffer, refilling from the socket for bodies that don't fit; decodes chunked bodies on the fly. Tracks pos/filled so the transport knows where the next pipelined request begins once the body is consumed.

Constructors

new(io : IO, buf : Bytes, pos : Int32, filled : Int32, max_body : Int64, mode : Mode, remaining : Int64 = 0_i64)
Source

Instance methods

drain

Reads the body to its end so the transport can resume framing.

Source
filled
Source
malformed?
Source
overflow?
Source
pos

Returns the current position (in bytes) in this IO.

The IO class raises on this method, but some subclasses, notable IO::FileDescriptor and IO::Memory implement it.

File.write("testfile", "hello")

file = File.new("testfile")
file.pos     # => 0
file.gets(2) # => "he"
file.pos     # => 2
Source
read(slice : Bytes) : Int32

Reads at most slice.size bytes from this IO into slice. Returns the number of bytes read, which is 0 if and only if there is no more data to read (so checking for 0 is the way to detect end of file).

io = IO::Memory.new "hello"
slice = Bytes.new(4)
io.read(slice) # => 4
slice          # => Bytes[104, 101, 108, 108]
io.read(slice) # => 1
slice          # => Bytes[111, 101, 108, 108]
io.read(slice) # => 0
Source
reset(pos : Int32, filled : Int32, mode : Mode, remaining : Int64) : Nil

Returns the reader to a pristine state for the next request on the same connection (one reader is pooled per connection). Every field that carries per-request state must be reset here — a missed one would corrupt framing (request-smuggling class), so the soak test exercises fixed and chunked bodies back to back.

Source
write(slice : Bytes) : Nil

Writes the contents of slice into this IO.

io = IO::Memory.new
slice = Bytes.new(4) { |i| ('a'.ord + i).to_u8 }
io.write(slice)
io.to_s # => "abcd"
Source

Nested types