falcon icon indicating copy to clipboard operation
falcon copied to clipboard

Falcon and protocol body rewind

Open tleish opened this issue 3 months ago • 6 comments

We are currently using an older version of Falcon 0.42.3 (working on upgrading code to Ruby 3 soon) and using the ruby Grape API library. Grape calls input.read and then input.rewind, however if attempting to read again then the body is empty

see: https://github.com/ruby-grape/grape/blob/master/lib/grape/middleware/formatter.rb#L67-L79

I noticed that the body is Protocol::HTTP1::Body::Fixed which does not support rewind, but the Protocol::HTTP does support rewind. Debugging this a little, it appears falcon chooses the protocol on startup. It's not clear to me how falcon decided which protocol to use (at startup) and if it's possible to configure to use a different one that supports rewind.

tleish avatar Sep 02 '25 00:09 tleish

You might be able to use https://github.com/socketry/protocol-rack/blob/main/lib/protocol/rack/rewindable.rb or something like that. You can configure that as part of your application stack using:

rack ... do
  middleware do
    Protocol::Rack::Rewindable.new(super())
  end
end

or something to that effect.

ioquatix avatar Sep 02 '25 02:09 ioquatix

What's the overall logic behind choosing Protocol::HTTP vs Protocol::HTTP1?

tleish avatar Sep 02 '25 21:09 tleish

Protocol::HTTP is HTTP semantics, Protocol::HTTP1 is the HTTP/1.x protocol parser/semantics specifically.

ioquatix avatar Sep 03 '25 01:09 ioquatix

Ok, one last question. I'm curious as to why .read method does not throw an error, but also does not rewind the body. I'm more interested in the question of why not support rewind as expected. Is there something I should be aware of before I implement a middleware that supports it?

tleish avatar Sep 05 '25 16:09 tleish

read just means read everything available. If there is nothing available, nothing is read. Does that answer your question?

ioquatix avatar Sep 05 '25 22:09 ioquatix

Sorry, that was a typo. It meant to put .rewind (not.read). Why is .rewind essentially a no-op in falcon? Is there something I should be aware of before I implement a middleware that supports.rewind?

tleish avatar Sep 05 '25 22:09 tleish