goliath-proxy 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.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YmYzOWNiNzNkYTdmNjkyOWFlZjZhZDkyMmVmYmIzZTlmMGJkNjdiOA==
5
+ data.tar.gz: !binary |-
6
+ MDdjZmViOTMwZmIwYjhiYTEwNDMzMTc1YTcwMThjZjRmMjMzZGM2NQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ Y2ViYjEyMTMyNzViMDI2MDFiNzA3YThiN2NmNTIyMDU4NWNmODEzMjZmMzhm
10
+ NWQ5ZDY1MWYxMjIxMWZmMTJiMmYyMzViNmI5ZGE2NDU0MzYxYmQwNmMwNWUx
11
+ YWQ3ODM1NjBmNTQ3MTYwOTdjNDA5YzUxMGI0YThkOGE1NGY1OWM=
12
+ data.tar.gz: !binary |-
13
+ NWMxNzM2ZDUxNjhiMDFhN2U2NTc5NjZiNDBhMDUyMDBlMTE0ODNlOGZlNmVh
14
+ MzI0MmM5MWU5ZmRiOTkwOWNkYjhmNjE2ODAxZDE0N2I0ZmY2Y2FhMDNmNjBm
15
+ MWY0Zjg2Mzk4ZDhiOTcwZjJjMDE4NjQ1ZjMxYTFiYWQ0MjMzNjQ=
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in goliath-proxy.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Gary Taylor
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,40 @@
1
+ # Goliath::Proxy
2
+
3
+ Allows goliath to be used as a http proxy server. The request that was proxied is forwarded on to the goliath application.
4
+ Useful for debugging proxies, test proxies or anywhere else where you may want to intercept requests via your goliath
5
+ application.
6
+
7
+ ## Caution
8
+
9
+ This code works, but is not yet finished. It allowed me to continue with my project and I intend to come back to this
10
+ and test it more thoroughly when my project is complete.
11
+
12
+ Saying that, dont be afraid to try it - just run it using a normal runner (like in the custom server example in goliath) - there is no binary for it yet
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ ```ruby
19
+ gem 'goliath-proxy'
20
+ ```
21
+
22
+ And then execute:
23
+
24
+ $ bundle
25
+
26
+ Or install it yourself as:
27
+
28
+ $ gem install goliath-proxy
29
+
30
+ ## Usage
31
+
32
+ TODO: Write usage instructions here
33
+
34
+ ## Contributing
35
+
36
+ 1. Fork it ( https://github.com/garytaylor/goliath-proxy/fork )
37
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
38
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
39
+ 4. Push to the branch (`git push origin my-new-feature`)
40
+ 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 'goliath/proxy/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "goliath-proxy"
8
+ spec.version = Goliath::Proxy::VERSION
9
+ spec.authors = ["Gary Taylor"]
10
+ spec.email = ["gary.taylor@hismessages.com"]
11
+ spec.summary = %q{Use goliath as a framework for a programmable proxy server}
12
+ spec.description = %q{Goliath is a fabulous framework for writing rack based web applications. With this gem, you can also use it to write web proxies in rack style.}
13
+ spec.homepage = "https://github.com/garytaylor/goliath-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.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ end
@@ -0,0 +1,6 @@
1
+ require "goliath/proxy/version"
2
+ require 'goliath/proxy/constants'
3
+ require 'goliath/proxy/runner'
4
+ require 'goliath/proxy/server'
5
+ require 'goliath/proxy/connection'
6
+
@@ -0,0 +1,113 @@
1
+ require 'goliath/proxy/constants'
2
+ module Goliath
3
+ module Proxy
4
+ class Connection < ::Goliath::Connection
5
+ include Constants
6
+ # This is intentionally completely overriden from the superclass's
7
+ # version as it is required to re use the listeners on the parser
8
+ # for a second time around if an SSL address is being proxied
9
+ def post_init
10
+ @current = nil
11
+ @requests = []
12
+ @pending = []
13
+ @parser = Http::Parser.new(self)
14
+ end
15
+ def on_headers_complete(h)
16
+ self.restarting = false
17
+ if @parser.http_method == 'CONNECT'
18
+ restart_with_ssl(@parser.request_url, h)
19
+ else
20
+
21
+ env = Goliath::Env.new
22
+ env[SERVER_PORT] = port.to_s
23
+ env[RACK_LOGGER] = logger
24
+ env[OPTIONS] = options
25
+ env[STATUS] = status
26
+ env[CONFIG] = config
27
+ env[REMOTE_ADDR] = remote_address
28
+ add_original_headers(env) if @ssl
29
+
30
+ r = Goliath::Request.new(@app, self, env)
31
+ r.parse_header(h, @parser) do
32
+ env[ASYNC_HEADERS] = api.method(:on_headers) if api.respond_to?(:on_headers)
33
+ env[ASYNC_BODY] = api.method(:on_body) if api.respond_to?(:on_body)
34
+ env[ASYNC_CLOSE] = api.method(:on_close) if api.respond_to?(:on_close)
35
+ end
36
+ modify_headers_for_ssl(env) if @ssl
37
+ @requests.push(r)
38
+
39
+ end
40
+ end
41
+
42
+ def restart_with_ssl(url, headers)
43
+ @ssl = url
44
+ self.restarting = true
45
+ @parser.reset! ##Prevent any further parsing of this as it is the CONNECT request which we dont do anything else with
46
+ @parser = Http::Parser.new(self)
47
+ @original_headers = headers.clone
48
+ send_data("HTTP/1.0 200 Connection established\r\nProxy-agent: goliath-proxy/0.0.0\r\n\r\n")
49
+ start_tls(
50
+ private_key_file: File.expand_path('../../../../mitm.key', __FILE__),
51
+ cert_chain_file: File.expand_path('../../../../mitm.crt', __FILE__)
52
+ )
53
+ end
54
+
55
+ def on_body(data)
56
+ @requests.first.parse(data)
57
+ end
58
+ def on_message_complete
59
+ self.restarting = false
60
+ req = @requests.shift
61
+
62
+ if @current.nil?
63
+ @current = req
64
+ @current.succeed
65
+ else
66
+ @pending.push(req)
67
+ end
68
+
69
+ req.process if !@parser.upgrade? && !req.env[:terminate_connection]
70
+
71
+ end
72
+
73
+ # Deliberately overriding this from the superclass as we want to prevent
74
+ # everything after parsing of the data IF this is restarting
75
+ def receive_data(data)
76
+ begin
77
+ @parser << data
78
+ return if restarting
79
+ if @parser.upgrade?
80
+ if !@current.env[UPGRADE_DATA]
81
+ @current.env[UPGRADE_DATA] = @parser.upgrade_data
82
+ @current.process
83
+ else
84
+ @current.parse(data)
85
+ end
86
+ end
87
+
88
+ rescue HTTP::Parser::Error => e
89
+ terminate_request(false)
90
+ end
91
+ end
92
+
93
+ private
94
+ attr_accessor :restarting
95
+
96
+ def add_original_headers(env)
97
+ @original_headers.each do |name, value|
98
+ converted_name = "HTTP_#{name.gsub(/-/, '_').upcase}"
99
+ env[converted_name] = value
100
+ end
101
+
102
+ end
103
+
104
+ def modify_headers_for_ssl(env)
105
+ uri = URI.parse(@parser.request_url)
106
+ url = "https://#{@ssl}#{[uri.path, uri.query].compact.join('?')}"
107
+ env['REQUEST_URI'] = url
108
+ env['HTTPS'] = 'on'
109
+ end
110
+
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,7 @@
1
+ module Goliath
2
+ module Proxy
3
+ module Constants
4
+ PROXY_HEADERS = 'goliath-proxy.headers'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,22 @@
1
+ require 'goliath/proxy'
2
+ module Goliath
3
+ module Proxy
4
+ class Runner < ::Goliath::Runner
5
+ # Sets up the Goliath server
6
+ #
7
+ # @param log [Logger] The logger to configure the server to log to
8
+ # @return [Server] an instance of a Goliath Proxy server
9
+ def setup_server(log = setup_logger)
10
+ server = Goliath::Proxy::Server.new(@address, @port)
11
+ server.logger = log
12
+ server.app = @app
13
+ server.api = @api
14
+ server.plugins = @plugins || []
15
+ server.options = @server_options
16
+ server
17
+ end
18
+
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,49 @@
1
+ require 'goliath/proxy/connection'
2
+ module Goliath
3
+ module Proxy
4
+ class Server < ::Goliath::Server
5
+ # Starts the server running. This will execute the reactor, load config and plugins and
6
+ # start listening for requests
7
+ #
8
+ # @return Does not return until the server has halted.
9
+ def start(&blk)
10
+ EM.epoll
11
+ EM.synchrony do
12
+ trap("INT") { stop }
13
+ trap("TERM") { stop }
14
+
15
+ if RUBY_PLATFORM !~ /mswin|mingw/
16
+ trap("HUP") { load_config(options[:config]) }
17
+ end
18
+
19
+ load_config(options[:config])
20
+ load_plugins
21
+
22
+ EM.set_effective_user(options[:user]) if options[:user]
23
+
24
+ config[Goliath::Constants::GOLIATH_SIGNATURE] = EM.start_server(address, port, Goliath::Proxy::Connection) do |conn|
25
+ if options[:ssl]
26
+ conn.start_tls(
27
+ :private_key_file => options[:ssl_key],
28
+ :cert_chain_file => options[:ssl_cert],
29
+ :verify_peer => options[:ssl_verify]
30
+ )
31
+ end
32
+
33
+ conn.port = port
34
+ conn.app = app
35
+ conn.api = api
36
+ conn.logger = logger
37
+ conn.status = status
38
+ conn.config = config
39
+ conn.options = options
40
+ end
41
+
42
+ blk.call(self) if blk
43
+ end
44
+ end
45
+
46
+
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,5 @@
1
+ module Goliath
2
+ module Proxy
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,22 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDojCCAooCCQCYeVsjl+UFxzANBgkqhkiG9w0BAQUFADCBkjELMAkGA1UEBhMC
3
+ VVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MSEwHwYDVQQK
4
+ ExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxFjAUBgNVBAMTDVB1ZmZpbmcgQmls
5
+ bHkxIzAhBgkqhkiG9w0BCQEWFG9sbHkuc21pdGhAZ21haWwuY29tMB4XDTEyMTAw
6
+ MjA2NDIxMVoXDTEzMTAwMjA2NDIxMVowgZIxCzAJBgNVBAYTAlVTMQswCQYDVQQI
7
+ EwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEhMB8GA1UEChMYSW50ZXJuZXQg
8
+ V2lkZ2l0cyBQdHkgTHRkMRYwFAYDVQQDEw1QdWZmaW5nIEJpbGx5MSMwIQYJKoZI
9
+ hvcNAQkBFhRvbGx5LnNtaXRoQGdtYWlsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD
10
+ ggEPADCCAQoCggEBALW7WQIIGCgUk28x1eIV0+VDG6SZV8dosJPU3WM4zLT0KLsv
11
+ 2+5KNO373KyXhIDQqkv+4+1myVYj5wkvDSFMLYvBTNmypS7Xh6+wyKjQQ5wupXoB
12
+ BNrJw5CbfUX9Kwq31H6aO1ItWZ6QHjW4dpE3AOu7ohwwyyL2Q0QkzTeP5b6SofbV
13
+ 9y1DpeH5L2an84LIjm1XrNbswY0p0CDT7TTsmYoXnw0MD5I73rT4arOOKWdVrD/G
14
+ lbvfcZN6c+nN713tGI9XfM5cQEXUsbSY4NKuF+jn7B2tsx+QRVwUyMwS8ZVpDt5q
15
+ DMBwROskWTMLKxeuxxpmjFWHlLuBlJ0M/rKII98CAwEAATANBgkqhkiG9w0BAQUF
16
+ AAOCAQEAMkhR7JDQKcYDy5Yb80cPIjw5kaEfTb+/Vh6DLLEtwEVIc2PcIvXCBZRo
17
+ 79Esa42BaNEaWPxRVAs0Doubh4IdGk9qp9a/71gqhi3iNe//depX5VLf1+5LnQtV
18
+ BbFruXUkzOF4kykm5Fcf9yQ9W951d0qaT6K9LefSsaoMrQjgKCeFAcIOXjqHyWns
19
+ KAO34C1kzAFemMY20RcgZf9/+09Zs/ZiDBeoWTc+juaa9zCgvg/1FKHqsA/iLg6/
20
+ VcdOquI9fJ5hRTZFkPoFLpxf2O1H3IpyNXmpcJDFvKfh7wIcHkLWIg5BFXc2S4+v
21
+ bNFEKqipZH+D9++jXGyumxA8VoZOOA==
22
+ -----END CERTIFICATE-----
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEowIBAAKCAQEAtbtZAggYKBSTbzHV4hXT5UMbpJlXx2iwk9TdYzjMtPQouy/b
3
+ 7ko07fvcrJeEgNCqS/7j7WbJViPnCS8NIUwti8FM2bKlLteHr7DIqNBDnC6legEE
4
+ 2snDkJt9Rf0rCrfUfpo7Ui1ZnpAeNbh2kTcA67uiHDDLIvZDRCTNN4/lvpKh9tX3
5
+ LUOl4fkvZqfzgsiObVes1uzBjSnQINPtNOyZihefDQwPkjvetPhqs44pZ1WsP8aV
6
+ u99xk3pz6c3vXe0Yj1d8zlxARdSxtJjg0q4X6OfsHa2zH5BFXBTIzBLxlWkO3moM
7
+ wHBE6yRZMwsrF67HGmaMVYeUu4GUnQz+sogj3wIDAQABAoIBAEM8cF7vDbjue+m8
8
+ 32wJNV9yJ60LSs2tLv9S1yHZpusgFl3DBDSyYcjW0TtNx6k9CnSZdkykJcNn/xeH
9
+ v+zc2VEGkF9O2Axvk3TuDB9hBlKnc3OjIt+rnF5JGN0nIKCTiNvaRi5ONwUSPwsT
10
+ F1L8rauJvR1+8/kYcaSplP+EjrSlvaKtUPNKfB8V6IktVLHiBUFs7nWoOGSaEB4/
11
+ 8jlji4s8xzVammTRg175mhOkgqdI+cWfXnn8PhOJZ2XjZz5eFOWxdvNldBbsm9Yc
12
+ g3URB9FpOPMY8DvgZNrAYp6/7C9ACecAIZAnDK0/aQOa95UeeCEbmAv59F2OqOc2
13
+ 35HUSrkCgYEA55e+o7pxUY7YPVopBz27JWANk/zwMN1ZgDlR87Q0ENmrjOB8kPmz
14
+ 02SHuVoXMPj/SD/S4J1NY2o7u5ofSpxUsdofCETsCeCbqhshRLqCu7yCjGagHknY
15
+ M4dJdRoFPN03gy+qHB7EKT0U89lvwRsjShc8h56wXsRHP6qM2uVgGyUCgYEAyOJh
16
+ ZPKBa0WVG9NxFS4Ej7CDpmWA415PyCrTK9cA2LCA0sWXHAhJ9guUx4zlqwLkfYBr
17
+ mmobAKjllFOUiECFLs49Oy/vD9Kw/ga9KO6eU9E/j9XHLVYupkPEVWeM7jzaQBul
18
+ CvMcPGgXX/84Xgtjjim8RuAPIgmRHSDfqRFUtbMCgYEAmQwxEiZuKMXLpY/luUFU
19
+ Yfi+QGRRnxlIwnIe9HzMQ651rl3UNEKwUi0HfLhKxzRmECsNgx6xO9fCrdHGiBoT
20
+ 5o0NIPvbORPUC3BuZesT5llHtN1FR37pf/QR2W9essBGpU1kj7zNSatyI0w4jFcQ
21
+ 1S/R8pYuXBI+O5bMCwS2pHkCgYBqFKG53RXav/PtrcqZlKNz/ZKH3DIj3zniSjsZ
22
+ e4BG7W4Z353cf8QO2i7G8fCWTgC7BYXNFRsNTiNuIHTfPrMV9HMBPl7PzEMK4iQh
23
+ 6WBSgr0+B3YWytv3kPGs5/HUHO5jzDVrgtX2UEGHwA7UGs+H0yJJiyhyoPqwlxuE
24
+ /FHvYQKBgEJaI/DaSpxJotq56lBHzTte1icbD8IFXMlbmWyIFxONWxlz98tQ2ypp
25
+ WhMGIzMsFE1X+P8vRbc865t36UMpucjRuAJ3MTeeCa60EghmdfajzA2ZWh/MnEyA
26
+ yvTr72g5gj5Yi/Zbiy1xeTo3UeaBxiCi8xyWAGodYg8891UVKqJu
27
+ -----END RSA PRIVATE KEY-----
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: goliath-proxy
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Gary Taylor
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-02 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.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description: Goliath is a fabulous framework for writing rack based web applications. With
42
+ this gem, you can also use it to write web proxies in rack style.
43
+ email:
44
+ - gary.taylor@hismessages.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - .gitignore
50
+ - Gemfile
51
+ - LICENSE.txt
52
+ - README.md
53
+ - Rakefile
54
+ - goliath-proxy.gemspec
55
+ - lib/goliath/proxy.rb
56
+ - lib/goliath/proxy/connection.rb
57
+ - lib/goliath/proxy/constants.rb
58
+ - lib/goliath/proxy/runner.rb
59
+ - lib/goliath/proxy/server.rb
60
+ - lib/goliath/proxy/version.rb
61
+ - mitm.crt
62
+ - mitm.key
63
+ homepage: https://github.com/garytaylor/goliath-proxy
64
+ licenses:
65
+ - MIT
66
+ metadata: {}
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ! '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 2.2.2
84
+ signing_key:
85
+ specification_version: 4
86
+ summary: Use goliath as a framework for a programmable proxy server
87
+ test_files: []