Skip to content

Commit

Permalink
Minor rewrite of streaming upload example.
Browse files Browse the repository at this point in the history
  • Loading branch information
ioquatix committed Jan 3, 2024
1 parent f7c755d commit 76fd6ca
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 78 deletions.
108 changes: 51 additions & 57 deletions examples/streaming_upload/config.ru
Original file line number Diff line number Diff line change
Expand Up @@ -5,65 +5,59 @@
require 'digest'
require 'securerandom'

module Protocol
module HTTP1
class Connection
def write_continue
@stream.write("HTTP/1.1 100 Continue\r\n\r\n")
@stream.flush
end
end
end
end

class BodyHandler
attr_reader :time, :md5, :size, :uuid

def initialize(input, length)
@uuid = SecureRandom.uuid
@input = input
@length = length
end

def receive
start = Time.now
@md5 = Digest::MD5.new
@size = 0
@done = false

until @done
begin
chunk = @input.read(10_240) # read will raise EOF so we have to check
rescue EOFError
puts "Seems we're done"
chunk = nil
end
if chunk.nil?
@done = true
else
@md5.update(chunk)
@size += chunk.bytesize
@done = true if @length == @size
end
end

@time = Time.now - start
end
attr_reader :time, :md5, :size, :uuid

def initialize(input, length)
@uuid = SecureRandom.uuid
@input = input
@length = length
end

def receive
start = Time.now
@md5 = Digest::MD5.new
@size = 0
@done = false

until @done
begin
chunk = @input.read(1024*1024) # read will raise EOF so we have to check
rescue EOFError
Console.info(self, "Received EOF")
chunk = nil
end

if chunk.nil?
@done = true
else
@md5.update(chunk)
@size += chunk.bytesize
@done = true if @length == @size
end
end

@time = Time.now - start
end
end

run lambda { |env|
request = env['protocol.http.request']
handler = BodyHandler.new(env['rack.input'], env['CONTENT_LENGTH'])
puts "#{env['REQUEST_METHOD']} #{handler.uuid}: #{request.path} #{env['CONTENT_LENGTH']}"

if env['REQUEST_METHOD'] == 'POST'
request.connection.write_continue if request.headers['expect'] == ['100-continue']
handler.receive
msg = "Uploaded #{handler.uuid}: #{handler.md5} #{handler.time} #{handler.size}"
puts msg
[200, {}, [msg]]
else
sleep 1
[200, {}, ["#{env['REQUEST_METHOD']}: #{request.path}\n"]]
end
request = env['protocol.http.request']
handler = BodyHandler.new(env['rack.input'], env['CONTENT_LENGTH'])
Console.info(self, "#{env['REQUEST_METHOD']} #{handler.uuid}: #{request.path} #{env['CONTENT_LENGTH']}")

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

handler.receive

Console.info(handler, "Received #{handler.size} bytes in #{handler.time} seconds", uuid: handler.uuid, md5: handler.md5)

[200, {}, ["Uploaded #{handler.uuid}: #{handler.md5} #{handler.time} #{handler.size}"]]
else
sleep 1
[200, {}, ["#{env['REQUEST_METHOD']}: #{request.path}\n"]]
end
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
GEM
remote: https://rubygems.org/
specs:
async (2.5.0)
async (2.8.0)
console (~> 1.10)
fiber-annotation
io-event (~> 1.1)
timers (~> 4.1)
async-container (0.16.12)
async
async-io
async-http (0.60.1)
async-http (0.61.0)
async (>= 1.25)
async-io (>= 1.28)
async-pool (>= 0.2)
protocol-http (~> 0.24.0)
protocol-http1 (~> 0.15.0)
protocol-http (~> 0.25.0)
protocol-http1 (~> 0.16.0)
protocol-http2 (~> 0.15.0)
traces (>= 0.8.0)
traces (>= 0.10.0)
async-http-cache (0.4.3)
async-http (~> 0.56)
async-io (1.34.3)
async-io (1.38.1)
async
async-pool (0.4.0)
async (>= 1.25)
build-environment (1.13.0)
console (1.16.2)
console (1.23.3)
fiber-annotation
fiber-local
falcon (0.42.3)
async
Expand All @@ -38,36 +40,38 @@ GEM
process-metrics (~> 0.2.0)
protocol-rack (~> 0.1)
samovar (~> 2.1)
fiber-annotation (0.2.0)
fiber-local (1.0.0)
io-event (1.1.7)
io-event (1.4.0)
localhost (1.1.10)
mapping (1.1.1)
openssl (3.1.0)
openssl (3.2.0)
process-metrics (0.2.1)
console (~> 1.8)
samovar (~> 2.1)
protocol-hpack (1.4.2)
protocol-http (0.24.1)
protocol-http1 (0.15.0)
protocol-http (0.25.0)
protocol-http1 (0.16.1)
protocol-http (~> 0.22)
protocol-http2 (0.15.1)
protocol-hpack (~> 1.4)
protocol-http (~> 0.18)
protocol-rack (0.2.4)
protocol-rack (0.4.1)
protocol-http (~> 0.23)
rack (>= 1.0)
rack (3.0.7)
samovar (2.1.4)
rack (3.0.8)
samovar (2.2.0)
console (~> 1.0)
mapping (~> 1.0)
timers (4.3.5)
traces (0.9.1)
traces (0.11.1)

PLATFORMS
ruby
x86_64-linux

DEPENDENCIES
falcon

BUNDLED WITH
2.4.6
2.5.3
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,15 @@

The filesize was 82078050 bytes.




## concurrent requests

```
bundle exec falcon host ./falcon.rb
> bundle exec falcon host ./falcon.rb
```


```
> dd if=/dev/zero of=./testfile bs=82078050 count=1
> ab -n 100 -c 8 -p ./testfile -H "Expect: 100-continue" http://localhost:9292/
This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Expand Down

0 comments on commit 76fd6ca

Please sign in to comment.