Skip to content

Instantly share code, notes, and snippets.

@johnl
Created August 11, 2010 22:33
Show Gist options
  • Save johnl/519915 to your computer and use it in GitHub Desktop.
Save johnl/519915 to your computer and use it in GitHub Desktop.
little test app to generate SHA1 hashes for HTTP uploads on the fly, without storing them on disk. Uses Rainbows and Revactor
#
# This little test app generates SHA1 hashes for HTTP uploads on the
# fly, without storing them on disk.
# By John Leach <john@johnleach.co.uk> (with help from Eric Wong)
#
# Start the server like this:
#
# rainbows -c rainbows.conf.rb rainbows-sha1.ru
#
# I've been testing this with Revactor, which requires Ruby 1.9
#
# Use with the following rainbows.conf.rb:
#
# ENV['RACK_ENV'] = nil # we don't want lint to be loaded
# worker_processes 2
# Rainbows! do
# use :Revactor
# client_max_body_size nil
# end
#
# You can upload files like this:
#
# curl -v -T /path/to/a/file/to/upload http://localhost:8080/
#
# You can upload infinite data to test concurrency like this:
#
# dd if=/dev/zero bs=16k | curl -v -T - http://localhost:8080/test.bin
#
# Spawn as many of these as you like :) You'll notice regular debug
# output from the server telling you the upload progress of each
# concurrent upload.
#
# If all is well, your disk space should not decrease during the
# uploads and the ram usage of the server should not balloon.
bs = ENV['bs'] ? ENV['bs'].to_i : 16384
require 'digest/sha1'
use Rack::CommonLogger
use Rack::ShowExceptions
use Rack::ContentLength
app = lambda do |env|
# Tell all expect requests we're happy to accept
/\A100-continue\z/i =~ env['HTTP_EXPECT'] and
return [ 100, {}, [] ]
input = env["rack.input"]
if input.respond_to?(:tmp)
tmp = input.tmp
# Hack to prevent request being written to disk
tmp.respond_to?(:reopen) and tmp.reopen('/dev/null', 'w+')
end
digest = Digest::SHA1.new
recv_bytes = 0
last_time = Time.now.to_i
last_recv_bytes = 0
req_id = rand(0xffff)
while buf = input.read(bs)
recv_bytes += buf.size
digest.update(buf)
if (recv_bytes / bs) % 10000 == 9999
time_diff = Time.now.to_i - last_time + 1
recv_bytes_diff = recv_bytes - last_recv_bytes
speed = (recv_bytes_diff / time_diff) / 1024
recv_meg = recv_bytes / 1024 / 1024
msg = "req #{req_id}: #{recv_meg}M so far, (#{speed}k/s)\n"
env['rack.errors'].write msg
last_time = Time.now.to_i
last_recv_bytes = recv_bytes
end
end
[ 200, {
'Content-Type' => 'text/plain',
'SHA1' => digest.hexdigest,
'Received-Bytes' => recv_bytes.to_s
}, [''] ]
end
run app
ENV['RACK_ENV'] = nil # we don't want lint to be loaded
worker_processes 2
Rainbows! do
use :Revactor
client_max_body_size nil
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment