Skip to content

Instantly share code, notes, and snippets.

@niwo
Created July 21, 2011 13:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save niwo/1097172 to your computer and use it in GitHub Desktop.
Save niwo/1097172 to your computer and use it in GitHub Desktop.
Measure http download speed including partial requests
#!/usr/bin/env ruby
# dlspeed.rb - niwo 2011
# test speed of http downloads: partial (tail, head) and full download
# Output is csv to stdout
#################################################
require 'optparse'
# This hash will hold all of the options
# parsed from the command-line by
# OptionParser.
options = {}
optparse = OptionParser.new do|opts|
# Set a banner, displayed at the top
# of the help screen.
opts.banner = "Usage: dlspeed.rb [options] directory | file1 file2 ..."
options[:host] = "localhost"
opts.on( '-h', '--host HOST', 'webserver host and domain' ) do |host|
options[:host] = host
end
options[:dir] = "/"
opts.on( '-d', '--dir DIR', 'webserver base directory' ) do |dir|
options[:dir] = dir
end
options[:port] = 80
opts.on( '-p', '--path PORT', Integer, 'webserver port' ) do |port|
options[:port] = port
end
options[:ext] = %w(.mp3 .mp4 .wmv .flv .avi .rm)
opts.on( '-e', '--extensions ext1,ext2,ext3', Array, 'considered file extensions' ) do |ext|
options[:ext] = ext
end
# This displays the help screen, all programs are
# assumed to have this option.
opts.on( '--help', 'Display this screen' ) do
puts opts
exit
end
end
#################################################
require 'net/http'
require 'uri'
class DlSpeed
def initialize(host, port , directory = "" )
@http = Net::HTTP.new(host, port)
@directory = directory
end
def run_test(files)
puts "date,file,file-size MB,slice-size MB,head time,head MB/s,head code,tail time,tail MB/s,tail code,full time,full MB/s,full code"
files.each do |file|
print "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")},#{file},#{(bytes_to_mb(filesize(file))).round(2)},#{(bytes_to_mb(slice(file))).round(2)},"
print recall_tail(file) + ","
print recall_head(file) + ","
puts recall(file)
end
end
def filesize(file)
@http.head(@directory + file)['content-length'].to_f
end
def slice(file, part = 4)
(filesize(file) / part)
end
def recall_tail(file)
code, time = http_download(file, {'Range' => "bytes=0-#{(slice(file) - 1).round}"} )
response_to_s(code, time, slice(file))
end
def recall_head(file)
code, time = http_download(file, {'Range' => "bytes=#{slice(file).round}-"} )
response_to_s(code, time, slice(file))
end
def recall(file)
code, time = http_download(file)
response_to_s(code, time, filesize(file))
end
def response_to_s(code, time, size)
"#{time.round(2)},#{throughput(size, time)},#{code}"
end
def throughput(size, time)
( bytes_to_mb(size) / time ).round(2)
end
def bytes_to_mb(bytes)
bytes/1024/1024
end
def http_download(file, headers = {})
start = Time.new
code = @http.get2(@directory + file, headers).code.to_i
stop = Time.new
download_time = stop - start
return code, download_time
end
end # DlSpeed
#########################################################
optparse.parse!
test_files = []
if ARGV.empty?
puts optparse.help
exit
else
if File.directory?(ARGV[0])
dir = Dir.new(ARGV[0])
dir.each do |path|
if options[:ext].include? File.extname(path)
test_files << File.basename(path)
end
end
else
ARGV.each do |path|
if options[:ext].include? File.extname(path)
test_files << File.basename(path)
end
end
end
end
dls = DlSpeed.new(options[:host], options[:port], options[:dir])
dls.run_test(test_files)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment