socketry / falcon

A high-performance web server for Ruby, supporting HTTP/1, HTTP/2 and TLS.
https://socketry.github.io/falcon/
MIT License
2.54k stars 79 forks source link

streaming upload example #206

Closed pschrammel closed 6 months ago

pschrammel commented 1 year ago

Types of Changes

streaming_upload example added with support for 100-continue (which is hack but works). There's still an issue that EOFError is not rescuable (run the "ab" command as described in the README and you'll see it).

Contribution

pschrammel commented 11 months ago

@ioquatix can you have a short look at at? I still can't understand why it sometimes is crashing. It might have to do with exceptions in a fiber. Perhaps you have an idea how to make the thing robust.

pschrammel commented 6 months ago

@ioquatix do you have time to give me some hints?

ioquatix commented 6 months ago

Sorry, I'll take a look today.

ioquatix commented 6 months ago

The example looks okay to me, I'll merge it and try it out.

ioquatix commented 6 months ago

Nice example! I made some minor changes and played around with the code. It looks pretty decent to me. Notably we introduced support for interim responses:

  if env['REQUEST_METHOD'] == 'POST'
    if request.headers['expect']&.include?('100-continue')
      request.write_interim_response(Protocol::HTTP::Response[100])
    end

I think that the reason why you are getting corruption at the end is probably ab is not gracefully shutting down and instead just dropping all the connections at the end. I'm not sure why it would do this so I'll investigate a bit further, still not 100% convinced there isn't a bug somewhere on my end.

ioquatix commented 6 months ago

Yeah, my guess is when you have -c n where n > 1, ab will write as many requests per connection as possible, and when it hits the request limit, immediately terminates all connections. In a real world system, you'd need to just drop these requests (i.e. EOFError represents a failed upload).