throttle 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in throttle.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # Throttle
2
+ Uses ipfw on Mac OSX to simulate slower connection speed.
3
+
4
+ ## Purpose
5
+ Many times I've found myself needing to test applications on slower connections. However, that is never an easy task. Throttle allows you to simulate a slower connection by allowing you to specify an exact bandwidth you would like to experience.
6
+
7
+ ## Development
8
+ At the moment the code is REAAAAAAL ugly and needs much improvement. There are also a lot more features I would like to add. Mostly being able to specify source and destination ip:port so you can filter which traffic will be throttled. Also the ability to have multiple filters going at once. Right now you can only have one.
9
+
10
+ ## Usage
11
+
12
+ ### Prerequisites
13
+
14
+ * Mac OSX 10.5, 10.6, 10.7
15
+ * ruby 1.8.7
16
+ * rubygems
17
+
18
+ ### Installation
19
+
20
+ ```
21
+ gem install throttle
22
+ ```
23
+
24
+ ### Getting Started
25
+ From the command line:
26
+
27
+ #### Start throttling
28
+
29
+ Limit traffic to 100 Kilobits per second
30
+ ```
31
+ throttle limit 100Kbit/s
32
+ ```
33
+
34
+ #### Current Status
35
+
36
+ List all current limits in place.
37
+
38
+ ```
39
+ throttle status
40
+ ```
41
+
42
+
43
+ #### Bandwidth
44
+
45
+ Bandwidth must be specified in [Kilo/Mega][bits/Bytes]/s.
46
+
47
+ * 500Kbps - 500 Kilobytes per second
48
+ * 1MBps - 1 Megabyte per second
49
+
50
+ IPFW doesn't allow bandwidth greater than 268 MBps.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/throttle ADDED
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require 'throttle'
5
+ rescue LoadError
6
+ require 'rubygems'
7
+ require 'throttle'
8
+ end
9
+
10
+ #throttle limit 500Kbps
11
+ #throttle limit 600Kbps
12
+ #throttle status
13
+ #throttle reset
14
+
15
+ def error(str)
16
+ puts "Error: #{str}"
17
+ end
18
+
19
+ throttle = Throttle.new
20
+
21
+ case ARGV[0]
22
+ when "limit"
23
+ if ARGV[1]
24
+ throttle.limit(ARGV[1])
25
+ puts "Currently throttled at : #{throttle.status}"
26
+ else
27
+ error("Please provide a valid bit rate to limit.")
28
+ end
29
+ when "status"
30
+ puts throttle.status
31
+ when "reset"
32
+ throttle.reset
33
+ puts throttle.status
34
+ else
35
+ puts "Throttle Help!"
36
+
37
+ puts "\nThrottling: "
38
+ puts "throttle limit [bandwidth]"
39
+ puts "throttle limit 500KBps"
40
+ puts "throttle limit 12Mbps"
41
+
42
+ puts "\nGet the current status:"
43
+ puts "throttle status"
44
+
45
+ puts "\nTurn off:"
46
+ puts "throttle reset"
47
+ end
@@ -0,0 +1,27 @@
1
+ module Throttle
2
+ module Bandwidth
3
+ def parse_bandwidth(str)
4
+ amount = nil
5
+ units = "KBp/s"
6
+
7
+ if /(\d*)/.match(str)
8
+ amount = Regexp.last_match(0).to_i
9
+
10
+ if /((K|M|k|m)(b|B)(p|P))/.match(str)
11
+ units = Regexp.last_match(0)
12
+ units.gsub!('P', 'p')
13
+ units.gsub!('/s', '')
14
+ units += '/s'
15
+ end
16
+
17
+ # Maximum allowed MBps
18
+ amount = 268 if units == "MBp/s" && amount > 268
19
+
20
+ "#{amount}#{units}"
21
+ else
22
+ nil
23
+ end
24
+ end
25
+ end
26
+ end
27
+
@@ -0,0 +1,34 @@
1
+ module Throttle
2
+ class Client
3
+ include Bandwidth
4
+
5
+ def status
6
+ pipes = Pipe.all
7
+ status = ""
8
+ pipes.each do |p|
9
+ status += "#{p.bandwidth}"
10
+ end
11
+
12
+ status = "No Limits." if status.empty?
13
+ return status
14
+ end
15
+
16
+ def reset
17
+ Pipe.reset
18
+ status
19
+ end
20
+
21
+ def limit(bandwidth)
22
+ Pipe.reset
23
+
24
+ options = {
25
+ :id => 1,
26
+ :bandwidth => parse_bandwidth(bandwidth)
27
+ }
28
+
29
+ Pipe.new(options).set
30
+ status
31
+ end
32
+ end
33
+ end
34
+
@@ -0,0 +1,15 @@
1
+ module Throttle
2
+ module Ipfw
3
+ def ipfw(args)
4
+ `sudo ipfw #{args}`
5
+ end
6
+
7
+ def parse_pipe_id(str)
8
+ if /^\d{5} pipe (\d*) .*$/.match(str)
9
+ Regexp.last_match(1).to_i
10
+ else
11
+ nil
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,93 @@
1
+ module Throttle
2
+ class Pipe
3
+ attr_accessor :id, :bandwidth, :rule_id
4
+
5
+ def self.all
6
+ pipes = []
7
+ pipe_lines = []
8
+
9
+ ipfw('list').split("\n").each do |line|
10
+ if /^\d{5} pipe.*$/.match(line)
11
+ pipe_lines << Regexp.last_match(0)
12
+ end
13
+ end
14
+
15
+ pipe_lines.each do |line|
16
+ id = parse_pipe_id(line)
17
+ bandwidth = Pipe.bandwidth(id)
18
+
19
+ pipes << Pipe.new({
20
+ :id => id,
21
+ :bandwidth => bandwidth
22
+ })
23
+ end
24
+
25
+ return pipes
26
+ end
27
+
28
+ def self.bandwidth(id)
29
+ output = ipfw("pipe #{id} show")
30
+
31
+ if /^\d{5}:\W*(\d*\.\d* \S*).*$/.match(output)
32
+ Regexp.last_match(1)
33
+ else
34
+ nil
35
+ end
36
+ end
37
+
38
+ def self.reset
39
+ Pipe.all.each do |pipe|
40
+ pipe.delete
41
+ end
42
+ end
43
+
44
+ def initialize(options = {})
45
+ @id = options[:id]
46
+ @bandwidth = options[:bandwidth]
47
+ end
48
+
49
+ def set
50
+ unless rule_id
51
+ ipfw("add pipe #{self.id} ip from any to any")
52
+ end
53
+
54
+ ipfw("pipe #{id} config bw #{self.bandwidth}")
55
+ end
56
+
57
+ def bandwidth
58
+ @bandwidth || "Inactive"
59
+ end
60
+
61
+ def rule_id
62
+ @rule_id ||= set_rule_id
63
+ end
64
+
65
+ def set_rule_id
66
+ regex = "^(\d{5}) pipe #{self.id}.*$"
67
+
68
+ if /^(\d{5}) pipe #{self.id}.*$/.match(ipfw("list"))
69
+ Regexp.last_match(1)
70
+ end
71
+ end
72
+
73
+ def delete
74
+ delete_rule
75
+
76
+ unless @bandwidth.nil?
77
+ ipfw("pipe #{@id} delete")
78
+ end
79
+ end
80
+
81
+ def delete_rule
82
+ if rule_id && rule_id != 0
83
+ ipfw("delete #{rule_id}")
84
+ end
85
+ end
86
+
87
+ private
88
+
89
+ include Ipfw
90
+ extend Ipfw
91
+ end
92
+ end
93
+
@@ -0,0 +1,3 @@
1
+ module Throttle
2
+ VERSION = "0.0.1"
3
+ end
data/lib/throttle.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'throttle/version'
2
+ require 'throttle/ipfw'
3
+ require 'throttle/bandwidth'
4
+ require 'throttle/pipe'
5
+ require 'throttle/client'
6
+
7
+ module Throttle
8
+ def self.new(*args)
9
+ Throttle::Client.new(*args)
10
+ end
11
+ end
data/throttle.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "throttle/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "throttle"
7
+ s.version = Throttle::VERSION
8
+ s.authors = ["brookemckim"]
9
+ s.email = ["brooke.mckim@gmail.com"]
10
+ s.homepage = "https://github.com/brookemckim/throttle"
11
+ s.summary = %q{Throttle bandwidth on OS X}
12
+ s.description = %q{Throttle your local bandwidth with IPFW on OSX}
13
+
14
+ s.rubyforge_project = "throttle"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ # s.add_runtime_dependency "rest-client"
24
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: throttle
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - brookemckim
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-11-09 00:00:00.000000000Z
13
+ dependencies: []
14
+ description: Throttle your local bandwidth with IPFW on OSX
15
+ email:
16
+ - brooke.mckim@gmail.com
17
+ executables:
18
+ - throttle
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - .gitignore
23
+ - Gemfile
24
+ - README.md
25
+ - Rakefile
26
+ - bin/throttle
27
+ - lib/throttle.rb
28
+ - lib/throttle/bandwidth.rb
29
+ - lib/throttle/client.rb
30
+ - lib/throttle/ipfw.rb
31
+ - lib/throttle/pipe.rb
32
+ - lib/throttle/version.rb
33
+ - throttle.gemspec
34
+ homepage: https://github.com/brookemckim/throttle
35
+ licenses: []
36
+ post_install_message:
37
+ rdoc_options: []
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ none: false
48
+ requirements:
49
+ - - ! '>='
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ requirements: []
53
+ rubyforge_project: throttle
54
+ rubygems_version: 1.8.10
55
+ signing_key:
56
+ specification_version: 3
57
+ summary: Throttle bandwidth on OS X
58
+ test_files: []