evil-proxy 0.0.2

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f4c501bef2b64e58b8393c8cc73a6516739f8b87
4
+ data.tar.gz: 9f8c54251a54e7f68cb47b04363ea746ed0956e1
5
+ SHA512:
6
+ metadata.gz: dc6113ee6f3043cc8ddd8e70dc4423dc717281c5eb589cbc878531fa2019b280b09d1fbb8c9ae789d7b2c1ce8d93d4ad44f061a7c6ff8b67506838c44dc85b4c
7
+ data.tar.gz: c598d95d33cdbaf4ec131697f3b95015f39f5a31dda3fe8043522d912d9ed9bbf0a0ad903fa51e251def4f3f7829facaa4af45aa4bc20f5873028408312cc8e1
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in evil-proxy.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Theo Li <bbtfrr@gmail.com>
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,114 @@
1
+ # EvilProxy
2
+
3
+ A ruby http proxy to do :imp: things.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'evil-proxy'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install evil-proxy
18
+
19
+ ## Usage
20
+
21
+ #### Basic usage: hooks
22
+
23
+ ```ruby
24
+ require 'evil-proxy'
25
+
26
+ # EvilProxy::HTTPProxyServer is a subclass of Webrick::HTTPProxyServer;
27
+ # it takes the same parameters.
28
+ proxy = EvilProxy::HTTPProxyServer.new Port: 8080
29
+
30
+ proxy.before_request do |req|
31
+ # Do evil things
32
+ # Note that, different from Webrick::HTTPProxyServer,
33
+ # `req.body` is writable.
34
+ end
35
+
36
+ proxy.before_response do |req, res|
37
+ # Here `res.body` is also writable.
38
+ end
39
+
40
+ trap "INT" do proxy.shutdown end
41
+ trap "TERM" do proxy.shutdown end
42
+
43
+ proxy.start
44
+ ```
45
+
46
+ Available hooks including `when_initialize`, `when_start`, `when_shutdown`,
47
+ `before_request`, `before_response`, `(before|after)_(get|head|post|options|connect)`.
48
+
49
+ #### Plugin: store
50
+
51
+ If you want to save the network traffic, you can use `store` plugin,
52
+ network traffic will be saved in `store.yml`.
53
+ ```ruby
54
+ require 'evil-proxy'
55
+ require 'evil-proxy/store'
56
+
57
+ proxy = EvilProxy::HTTPProxyServer.new Port: 8080
58
+
59
+ proxy.store_filter do |req, res|
60
+ # Optional, if you don't set `store_filter`, evil-proxy
61
+ # will save all the network traffic.
62
+ res.unparsed_uri =~ /www.google.com/
63
+ end
64
+
65
+ ...
66
+ ```
67
+
68
+ #### Plugin: async
69
+ Start the proxy server asnychronously, which means start server in a background thread;
70
+ with it, you can check the `store` when runing the proxy server.
71
+ ```ruby
72
+ require 'evil-proxy'
73
+ require 'evil-proxy/async'
74
+ require 'evil-proxy/store'
75
+ require 'yaml'
76
+
77
+ proxy = EvilProxy::HTTPProxyServer.new Port: 8080
78
+
79
+ proxy.start
80
+
81
+ loop do
82
+ # Do something with `proxy.store`
83
+ puts proxy.store.to_yaml
84
+ proxy.clean_store # if needed
85
+ sleep 10
86
+ end
87
+
88
+ ...
89
+ ```
90
+
91
+ #### Plugin: selenium
92
+ Use `proxy.selenium_proxy` to create a instance of `Selenium::WebDriver::Proxy`.
93
+
94
+ ```ruby
95
+ require 'evil-proxy'
96
+ require 'evil-proxy/selenium'
97
+ require 'selenium/webdriver'
98
+
99
+ proxy = EvilProxy::HTTPProxyServer.new Port: 8080
100
+ proxy.start
101
+
102
+ driver = Selenium::WebDriver.for :chrome, proxy: proxy.selenium_proxy
103
+
104
+ ...
105
+ ```
106
+
107
+
108
+ ## Contributing
109
+
110
+ 1. Fork it ( https://github.com/bbtfr/evil-proxy/fork )
111
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
112
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
113
+ 4. Push to the branch (`git push origin my-new-feature`)
114
+ 5. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'evil-proxy/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "evil-proxy"
8
+ spec.version = EvilProxy::VERSION
9
+ spec.authors = ["Theo"]
10
+ spec.email = ["bbtfrr@gmail.com"]
11
+ spec.summary = %q{A ruby http proxy to do EVIL things.}
12
+ spec.description = %q{A ruby http proxy to do EVIL things.}
13
+ spec.homepage = "https://github.com/bbtfr/evil-proxy"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake"
23
+ end
@@ -0,0 +1,7 @@
1
+ require "evil-proxy/version"
2
+ require "evil-proxy/httpproxy"
3
+ require "evil-proxy/httprequest"
4
+
5
+ module EvilProxy
6
+ # Your code goes here...
7
+ end
@@ -0,0 +1,19 @@
1
+ EvilProxy::HTTPProxyServer.class_eval do
2
+ attr_reader :thread
3
+ alias_method :original_start, :start
4
+ alias_method :original_shutdown, :shutdown
5
+
6
+ def start
7
+ @thread = Thread.new do
8
+ self.original_start
9
+ end
10
+ end
11
+
12
+ def shutdown
13
+ @thread.exit
14
+ end
15
+
16
+ def join
17
+ @thread.join
18
+ end
19
+ end
@@ -0,0 +1,83 @@
1
+ require 'webrick'
2
+ require 'webrick/httpproxy'
3
+
4
+ class EvilProxy::HTTPProxyServer < WEBrick::HTTPProxyServer
5
+ VALID_CALBACKS = Array.new
6
+ DEFAULT_CALLBACKS = Hash.new
7
+
8
+ def initialize *args
9
+ initialize_callbacks
10
+ fire :when_initialize, *args
11
+ super
12
+ end
13
+
14
+ def start
15
+ begin
16
+ fire :when_start
17
+ super
18
+ ensure
19
+ fire :when_shutdown
20
+ end
21
+ end
22
+
23
+ def fire key, *args
24
+ return unless @callbacks[key]
25
+ @callbacks[key].each do |callback|
26
+ instance_exec *args, &callback
27
+ end
28
+ end
29
+
30
+ def proxy_service req, res
31
+ fire :before_request, req
32
+ super
33
+ fire :before_response, req, res
34
+ end
35
+
36
+ VALID_CALBACKS << :when_initialize
37
+ VALID_CALBACKS << :when_start
38
+ VALID_CALBACKS << :when_shutdown
39
+ VALID_CALBACKS << :before_request
40
+ VALID_CALBACKS << :before_response
41
+
42
+ %w(GET HEAD POST OPTIONS CONNECT).each do |method|
43
+ do_method = "do_#{method}".to_sym
44
+ do_method_without_callbacks = "#{do_method}_without_callbacks".to_sym
45
+ before_method = "before_#{method.downcase}".to_sym
46
+ after_method = "after_#{method.downcase}".to_sym
47
+
48
+ VALID_CALBACKS << before_method
49
+ VALID_CALBACKS << after_method
50
+
51
+ alias_method do_method_without_callbacks, do_method
52
+ define_method do_method do |req, res|
53
+ fire before_method, req
54
+ send do_method_without_callbacks, req, res
55
+ fire after_method, req, res
56
+ end
57
+ end
58
+
59
+ VALID_CALBACKS.each do |callback|
60
+ define_method callback do |&block|
61
+ @callbacks[callback] ||= []
62
+ @callbacks[callback] << block
63
+ end
64
+ end
65
+
66
+ private
67
+ def initialize_callbacks
68
+ @callbacks = Hash.new
69
+ DEFAULT_CALLBACKS.each do |key, callbacks|
70
+ @callbacks[key] = callbacks.clone
71
+ end
72
+ end
73
+
74
+ class << self
75
+ VALID_CALBACKS.each do |callback|
76
+ define_method callback do |&block|
77
+ DEFAULT_CALLBACKS[callback] ||= []
78
+ DEFAULT_CALLBACKS[callback] << block
79
+ end
80
+ end
81
+ end
82
+
83
+ end
@@ -0,0 +1,11 @@
1
+ WEBrick::HTTPRequest.class_eval do
2
+ alias_method :original_body, :body
3
+ def body
4
+ @evil_body || original_body
5
+ end
6
+
7
+ def body= body
8
+ @evil_body = body
9
+ end
10
+
11
+ end
@@ -0,0 +1,19 @@
1
+ require 'evil-proxy/async'
2
+
3
+ EvilProxy::HTTPProxyServer.class_eval do
4
+ def selenium_proxy *protocols
5
+ require 'selenium-webdriver' unless defined?(Selenium)
6
+
7
+ protocols.push :http if protocols.empty?
8
+ unless (protocols - [:http, :ssl, :ftp]).empty?
9
+ raise "Invalid protocol specified. Must be one of: :http, :ssl, or :ftp."
10
+ end
11
+
12
+ host = @config[:BindAddress] || "127.0.0.1"
13
+ port = @config[:Port]
14
+
15
+ proxy_mapping = Hash.new
16
+ protocols.each do |proto| proxy_mapping[proto] = "#{host}:#{port}" end
17
+ Selenium::WebDriver::Proxy.new(proxy_mapping)
18
+ end
19
+ end
@@ -0,0 +1,61 @@
1
+ require 'yaml'
2
+
3
+ EvilProxy::HTTPProxyServer.class_eval do
4
+ attr_reader :store
5
+
6
+ when_initialize do
7
+ clean_store
8
+ end
9
+
10
+ when_shutdown do
11
+ dump_store
12
+ end
13
+
14
+ before_response do |req, res|
15
+ @store << [ req, res ] if match_store_filter req, res
16
+ end
17
+
18
+ def store_filter &block
19
+ @store_filter = block
20
+ end
21
+
22
+ def match_store_filter req, res
23
+ return true unless @store_filter
24
+ instance_exec req, res, &@store_filter
25
+ end
26
+
27
+ def clean_store
28
+ @store = []
29
+ end
30
+
31
+ def dump_store filename = "store.yml"
32
+ previous_store = YAML.load(File.read(filename)) || [] rescue []
33
+ File.open filename, "w" do |file|
34
+ file.puts YAML.dump(previous_store + store_as_params)
35
+ end
36
+ clean_store
37
+ end
38
+
39
+ def store_as_params
40
+ @store.map do |req, res|
41
+ Hash.new.tap do |params|
42
+ params["request"] = Hash.new.tap do |request|
43
+ request["method"] = req.request_method
44
+ request["url"] = req.unparsed_uri
45
+ request["headers"] = Hash.new.tap do |headers|
46
+ req.header.each do |key, value|
47
+ headers[key] = value.join(",")
48
+ end
49
+ end
50
+ request["body"] = req.body if req.body
51
+ request["time"] = req.request_time
52
+ end
53
+ params["response"] = Hash.new.tap do |response|
54
+ response["headers"] = res.header
55
+ response["body"] = res.body if req.body
56
+ response["status"] = res.status
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,3 @@
1
+ module EvilProxy
2
+ VERSION = "0.0.2"
3
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: evil-proxy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Theo
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: A ruby http proxy to do EVIL things.
42
+ email:
43
+ - bbtfrr@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - ".gitignore"
49
+ - Gemfile
50
+ - LICENSE.txt
51
+ - README.md
52
+ - Rakefile
53
+ - evil-proxy.gemspec
54
+ - lib/evil-proxy.rb
55
+ - lib/evil-proxy/async.rb
56
+ - lib/evil-proxy/httpproxy.rb
57
+ - lib/evil-proxy/httprequest.rb
58
+ - lib/evil-proxy/selenium.rb
59
+ - lib/evil-proxy/store.rb
60
+ - lib/evil-proxy/version.rb
61
+ homepage: https://github.com/bbtfr/evil-proxy
62
+ licenses:
63
+ - MIT
64
+ metadata: {}
65
+ post_install_message:
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubyforge_project:
81
+ rubygems_version: 2.4.6
82
+ signing_key:
83
+ specification_version: 4
84
+ summary: A ruby http proxy to do EVIL things.
85
+ test_files: []