rack-proxy 0.6.3 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7cd49adb5cd0843a5467ecf9cacc3a5d7f3c903d
4
- data.tar.gz: 64cc29bbc91ee24fbe14e200b3b69b5e8b2c0e71
3
+ metadata.gz: ce99adfb07beb9e42b72e91bd39860d2ec1efb7b
4
+ data.tar.gz: dfb0ede7fc70291ba58a24c7a478691f2fa5558f
5
5
  SHA512:
6
- metadata.gz: 2986ff1e4178e92f172cdedcd38a8f7617f7d532018c1d687edecfe0bd694583a4ba409620c875b86b4d836a0e9926be078fd8aa99052c724b4fdb9f2468a774
7
- data.tar.gz: 0915046fbf017fee515398ca66f78515a4fcfa551f95a6c9134cceebf54e310040f0cfce2d325e75f8e95e0d386647a98cf61247396d321a98d56ff1f133f120
6
+ metadata.gz: 602c219b1b8151a7b77f1e6751d0919cc320cc13c6b0c0ce2f4c2a7c16dca345688ad3b3a4a109480660856a0ee7125ec36d892c97a22fb92a973e8b0a7bc005
7
+ data.tar.gz: 897c3d1db3ab71a70ce88bb9437b4a7be25cae6db20b2601f20e227b558a4a6b02416997dad68b03a7d38d0d6948bca74d3739fabfd877c0876043ea42a34dc6
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rack-proxy (0.6.2)
4
+ rack-proxy (0.6.4)
5
5
  rack
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  A request/response rewriting HTTP proxy. A Rack app. Subclass `Rack::Proxy` and provide your `rewrite_env` and `rewrite_response` methods.
2
2
 
3
3
  Installation
4
- -------
4
+ ----
5
5
 
6
- Add the following to your Gemfile:
6
+ Add the following to your `Gemfile`:
7
7
 
8
8
  ```
9
- gem 'rack-proxy', '~> 0.6.3'
9
+ gem 'rack-proxy', '~> 0.6.4'
10
10
  ```
11
11
 
12
12
  Or install:
@@ -15,22 +15,72 @@ Or install:
15
15
  gem install rack-proxy
16
16
  ```
17
17
 
18
- Example
19
- -------
18
+ Use Cases
19
+ ----
20
+ Below are some examples of real world use cases for Rack-Proxy, done something interesting add the list below and send a PR.
21
+
22
+ * Allowing one app to act as central trust authority
23
+ * handle accepting self-sign certificates for internal apps
24
+ * authentication / authorization prior to proxying requests to a blindly trusting backend
25
+ * avoiding CORs complications by proxying from same domain to another backend
26
+ * subdomain based pass-through to multiple apps
27
+ * Complex redirect rules
28
+ * redirect pages with different extensions (ex: `.php`) to another app
29
+ * useful for handling awkward redirection rules for moved pages
30
+ * fan Parallel Requests: turning a single API request to [multiple concurrent backend requests](https://github.com/typhoeus/typhoeus#making-parallel-requests) & merging results.
31
+ * inserting or stripping headers required or problematic for certain clients
32
+
33
+ Options
34
+ ----
35
+
36
+ Options can be set when initializing the middleware or overriding a method.
37
+
38
+
39
+ * `:streaming` - defaults to `true`, but does not work on all Ruby versions, recommend to set to `false`
40
+ * `:ssl_verify_none` - tell `Net::HTTP` to not validate certs
41
+ * `:ssl_version` - tell `Net::HTTP` to set a specific `ssl_version`
42
+ * `:backend` - the URI parseable format of host and port of the target proxy backend. If not set it will assume the backend target is the same as the source.
43
+ * `:read_timeout` - set proxy timeout it defaults to 60 seconds
44
+
45
+ To pass in options, when you configure your middleware you can pass them in as an optional hash.
20
46
 
21
47
  ```ruby
22
- class Foo < Rack::Proxy
48
+ Rails.application.config.middleware.use ExampleServiceProxy, backend: 'http://guides.rubyonrails.org', streaming: false
49
+ ```
50
+
51
+ Examples
52
+ ----
53
+
54
+ See and run the examples below from `lib/rack_proxy_examples/`. To mount any example into an existing Rails app:
55
+
56
+ 1. create `config/initializers/proxy.rb`
57
+ 2. modify the file to require the example file
58
+ ```ruby
59
+ require 'rack_proxy_examples/forward_host'
60
+ ```
61
+
62
+ ### Forward request to Host and Insert Header
63
+
64
+ Test with `require 'rack_proxy_examples/forward_host'`
65
+
66
+ ```ruby
67
+ class ForwardHost < Rack::Proxy
23
68
 
24
69
  def rewrite_env(env)
25
70
  env["HTTP_HOST"] = "example.com"
26
-
27
71
  env
28
72
  end
29
73
 
30
74
  def rewrite_response(triplet)
31
75
  status, headers, body = triplet
32
76
 
77
+ # example of inserting an additional header
33
78
  headers["X-Foo"] = "Bar"
79
+
80
+ # if you rewrite env, it appears that content-length isn't calculated correctly
81
+ # resulting in only partial responses being sent to users
82
+ # you can remove it or recalculate it here
83
+ headers["content-length"] = nil
34
84
 
35
85
  triplet
36
86
  end
@@ -40,15 +90,30 @@ end
40
90
 
41
91
  ### Disable SSL session verification when proxying a server with e.g. self-signed SSL certs
42
92
 
93
+ Test with `require 'rack_proxy_examples/trusting_proxy'`
94
+
43
95
  ```ruby
44
96
  class TrustingProxy < Rack::Proxy
45
97
 
46
98
  def rewrite_env(env)
47
- env["rack.ssl_verify_none"] = true
99
+ env["HTTP_HOST"] = "self-signed.badssl.com"
48
100
 
101
+ # We are going to trust the self-signed SSL
102
+ env["rack.ssl_verify_none"] = true
49
103
  env
50
104
  end
51
105
 
106
+ def rewrite_response(triplet)
107
+ status, headers, body = triplet
108
+
109
+ # if you rewrite env, it appears that content-length isn't calculated correctly
110
+ # resulting in only partial responses being sent to users
111
+ # you can remove it or recalculate it here
112
+ headers["content-length"] = nil
113
+
114
+ triplet
115
+ end
116
+
52
117
  end
53
118
  ```
54
119
 
@@ -58,31 +123,98 @@ The same can be achieved for *all* requests going through the `Rack::Proxy` inst
58
123
  Rack::Proxy.new(ssl_verify_none: true)
59
124
  ```
60
125
 
61
- Using it as a middleware:
62
- -------------------------
126
+ ### Rails middleware example
127
+
128
+ Test with `require 'rack_proxy_examples/example_service_proxy'`
129
+
130
+ ```ruby
131
+ ###
132
+ # This is an example of how to use Rack-Proxy in a Rails application.
133
+ #
134
+ # Setup:
135
+ # 1. rails new test_app
136
+ # 2. cd test_app
137
+ # 3. install Rack-Proxy in `Gemfile`
138
+ # a. `gem 'rack-proxy', '~> 0.6.3'`
139
+ # 4. install gem: `bundle install`
140
+ # 5. create `config/initializers/proxy.rb` adding this line `require 'rack_proxy_examples/example_service_proxy'`
141
+ # 6. run: `SERVICE_URL=http://guides.rubyonrails.org rails server`
142
+ # 7. open in browser: `http://localhost:3000/example_service`
143
+ #
144
+ ###
145
+ ENV['SERVICE_URL'] ||= 'http://guides.rubyonrails.org'
146
+
147
+ class ExampleServiceProxy < Rack::Proxy
148
+ def perform_request(env)
149
+ request = Rack::Request.new(env)
150
+
151
+ # use rack proxy for anything hitting our host app at /example_service
152
+ if request.path =~ %r{^/example_service}
153
+ backend = URI(ENV['SERVICE_URL'])
154
+ # most backends required host set properly, but rack-proxy doesn't set this for you automatically
155
+ # even when a backend host is passed in via the options
156
+ env["HTTP_HOST"] = backend.host
157
+
158
+ # This is the only path that needs to be set currently on Rails 5 & greater
159
+ env['PATH_INFO'] = ENV['SERVICE_PATH'] || '/configuring.html'
160
+
161
+ # don't send your sites cookies to target service, unless it is a trusted internal service that can parse all your cookies
162
+ env['HTTP_COOKIE'] = ''
163
+ super(env)
164
+ else
165
+ @app.call(env)
166
+ end
167
+ end
168
+ end
169
+ ```
170
+
171
+ ### Using as middleware to forward only some extensions to another Application
172
+
173
+ Test with `require 'rack_proxy_examples/rack_php_proxy'`
63
174
 
64
175
  Example: Proxying only requests that end with ".php" could be done like this:
65
176
 
66
177
  ```ruby
67
- require 'rack/proxy'
178
+ ###
179
+ # Open http://localhost:3000/test.php to trigger proxy
180
+ ###
68
181
  class RackPhpProxy < Rack::Proxy
69
182
 
70
183
  def perform_request(env)
71
184
  request = Rack::Request.new(env)
72
185
  if request.path =~ %r{\.php}
73
- env["HTTP_HOST"] = "localhost"
74
- env["REQUEST_PATH"] = "/php/#{request.fullpath}"
186
+ env["HTTP_HOST"] = ENV["HTTP_HOST"] ? URI(ENV["HTTP_HOST"]).host : "localhost"
187
+ ENV["PHP_PATH"] ||= '/manual/en/tutorial.firstpage.php'
188
+
189
+ # Rails 3 & 4
190
+ env["REQUEST_PATH"] = ENV["PHP_PATH"] || "/php/#{request.fullpath}"
191
+ # Rails 5 and above
192
+ env['PATH_INFO'] = ENV["PHP_PATH"] || "/php/#{request.fullpath}"
193
+
194
+ env['content-length'] = nil
195
+
75
196
  super(env)
76
197
  else
77
198
  @app.call(env)
78
199
  end
79
200
  end
201
+
202
+ def rewrite_response(triplet)
203
+ status, headers, body = triplet
204
+
205
+ # if you proxy depending on the backend, it appears that content-length isn't calculated correctly
206
+ # resulting in only partial responses being sent to users
207
+ # you can remove it or recalculate it here
208
+ headers["content-length"] = nil
209
+
210
+ triplet
211
+ end
80
212
  end
81
213
  ```
82
214
 
83
215
  To use the middleware, please consider the following:
84
216
 
85
- 1) For Rails we could add a configuration in config/application.rb
217
+ 1) For Rails we could add a configuration in `config/application.rb`
86
218
 
87
219
  ```ruby
88
220
  config.middleware.use RackPhpProxy, {ssl_verify_none: true}
@@ -101,11 +233,13 @@ This will allow to run the other requests through the application and only proxy
101
233
  See tests for more examples.
102
234
 
103
235
  WARNING
104
- -------
236
+ ----
105
237
 
106
- Doesn't work with fakeweb/webmock. Both libraries monkey-patch net/http code.
238
+ Doesn't work with `fakeweb`/`webmock`. Both libraries monkey-patch net/http code.
107
239
 
108
240
  Todos
109
- -----
241
+ ----
110
242
 
111
- - Make the docs up to date with the current use case for this code: everything except streaming which involved a rather ugly monkey patch and only worked in 1.8, but does not work now.
243
+ * Make the docs up to date with the current use case for this code: everything except streaming which involved a rather ugly monkey patch and only worked in 1.8, but does not work now.
244
+ * Improve and validate requirements for Host and Path rewrite rules
245
+ * Ability to inject logger and set log level
@@ -4,11 +4,11 @@
4
4
  #
5
5
  # [status, headers, streamable_body]
6
6
  #
7
- # See http://github.com/aniero/rack-streaming-proxy
7
+ # See http://github.com/aniero/rack-streaming-proxy
8
8
  # for alternative that uses additional process.
9
9
  #
10
10
  # BTW I don't like monkey patching either
11
- # but this is not real monkey patching.
11
+ # but this is not real monkey patching.
12
12
  # I just added some methods and named them very uniquely
13
13
  # to avoid eventual conflicts. You're safe. Trust me.
14
14
  #
@@ -45,7 +45,7 @@ class Net::HTTP
45
45
  #
46
46
  # res
47
47
  # end
48
-
48
+
49
49
  def begin_request_hacked(req)
50
50
  begin_transport req
51
51
  req.exec @socket, @curr_http_version, edit_path(req.path)
@@ -56,7 +56,7 @@ class Net::HTTP
56
56
  @req_hacked, @res_hacked = req, res
57
57
  @res_hacked
58
58
  end
59
-
59
+
60
60
  def end_request_hacked
61
61
  @res_hacked.end_reading_body_hacked
62
62
  end_transport @req_hacked, @res_hacked
@@ -77,12 +77,12 @@ class Net::HTTPResponse
77
77
  # @socket = nil
78
78
  # end
79
79
  # end
80
-
80
+
81
81
  def begin_reading_body_hacked(sock, reqmethodallowbody)
82
82
  @socket = sock
83
83
  @body_exist = reqmethodallowbody && self.class.body_permitted?
84
84
  end
85
-
85
+
86
86
  def end_reading_body_hacked
87
87
  self.body
88
88
  @socket = nil
@@ -5,7 +5,7 @@ module Rack
5
5
 
6
6
  # Subclass and bring your own #rewrite_request and #rewrite_response
7
7
  class Proxy
8
- VERSION = "0.6.3"
8
+ VERSION = "0.6.4"
9
9
 
10
10
  class << self
11
11
  def extract_http_request_headers(env)
@@ -0,0 +1,40 @@
1
+ ###
2
+ # This is an example of how to use Rack-Proxy in a Rails application.
3
+ #
4
+ # Setup:
5
+ # 1. rails new test_app
6
+ # 2. cd test_app
7
+ # 3. install Rack-Proxy in `Gemfile`
8
+ # a. `gem 'rack-proxy', '~> 0.6.3'`
9
+ # 4. install gem: `bundle install`
10
+ # 5. create `config/initializers/proxy.rb` adding this line `require 'rack_proxy_examples/example_service_proxy'`
11
+ # 6. run: `SERVICE_URL=http://guides.rubyonrails.org rails server`
12
+ # 7. open in browser: `http://localhost:3000/example_service`
13
+ #
14
+ ###
15
+ ENV['SERVICE_URL'] ||= 'http://guides.rubyonrails.org'
16
+
17
+ class ExampleServiceProxy < Rack::Proxy
18
+ def perform_request(env)
19
+ request = Rack::Request.new(env)
20
+
21
+ # use rack proxy for anything hitting our host app at /example_service
22
+ if request.path =~ %r{^/example_service}
23
+ backend = URI(ENV['SERVICE_URL'])
24
+ # most backends required host set properly, but rack-proxy doesn't set this for you automatically
25
+ # even when a backend host is passed in via the options
26
+ env["HTTP_HOST"] = backend.host
27
+
28
+ # This is the only path that needs to be set currently on Rails 5 & greater
29
+ env['PATH_INFO'] = ENV['SERVICE_PATH'] || '/configuring.html'
30
+
31
+ # don't send your sites cookies to target service, unless it is a trusted internal service that can parse all your cookies
32
+ env['HTTP_COOKIE'] = ''
33
+ super(env)
34
+ else
35
+ @app.call(env)
36
+ end
37
+ end
38
+ end
39
+
40
+ Rails.application.config.middleware.use ExampleServiceProxy, backend: ENV['SERVICE_URL'], streaming: false
@@ -0,0 +1,24 @@
1
+ class ForwardHost < Rack::Proxy
2
+
3
+ def rewrite_env(env)
4
+ env["HTTP_HOST"] = "example.com"
5
+ env
6
+ end
7
+
8
+ def rewrite_response(triplet)
9
+ status, headers, body = triplet
10
+
11
+ # example of inserting an additional header
12
+ headers["X-Foo"] = "Bar"
13
+
14
+ # if you rewrite env, it appears that content-length isn't calculated correctly
15
+ # resulting in only partial responses being sent to users
16
+ # you can remove it or recalculate it here
17
+ headers["content-length"] = nil
18
+
19
+ triplet
20
+ end
21
+
22
+ end
23
+
24
+ Rails.application.config.middleware.use ForwardHost, backend: 'http://example.com', streaming: false
@@ -0,0 +1,37 @@
1
+ ###
2
+ # Open http://localhost:3000/test.php to trigger proxy
3
+ ###
4
+ class RackPhpProxy < Rack::Proxy
5
+
6
+ def perform_request(env)
7
+ request = Rack::Request.new(env)
8
+ if request.path =~ %r{\.php}
9
+ env["HTTP_HOST"] = ENV["HTTP_HOST"] ? URI(ENV["HTTP_HOST"]).host : "localhost"
10
+ ENV["PHP_PATH"] ||= '/manual/en/tutorial.firstpage.php'
11
+
12
+ # Rails 3 & 4
13
+ env["REQUEST_PATH"] = ENV["PHP_PATH"] || "/php/#{request.fullpath}"
14
+ # Rails 5 and above
15
+ env['PATH_INFO'] = ENV["PHP_PATH"] || "/php/#{request.fullpath}"
16
+
17
+ env['content-length'] = nil
18
+
19
+ super(env)
20
+ else
21
+ @app.call(env)
22
+ end
23
+ end
24
+
25
+ def rewrite_response(triplet)
26
+ status, headers, body = triplet
27
+
28
+ # if you proxy depending on the backend, it appears that content-length isn't calculated correctly
29
+ # resulting in only partial responses being sent to users
30
+ # you can remove it or recalculate it here
31
+ headers["content-length"] = nil
32
+
33
+ triplet
34
+ end
35
+ end
36
+
37
+ Rails.application.config.middleware.use RackPhpProxy, backend: ENV["HTTP_HOST"]='http://php.net', streaming: false
@@ -0,0 +1,24 @@
1
+ class TrustingProxy < Rack::Proxy
2
+
3
+ def rewrite_env(env)
4
+ env["HTTP_HOST"] = "self-signed.badssl.com"
5
+
6
+ # We are going to trust the self-signed SSL
7
+ env["rack.ssl_verify_none"] = true
8
+ env
9
+ end
10
+
11
+ def rewrite_response(triplet)
12
+ status, headers, body = triplet
13
+
14
+ # if you rewrite env, it appears that content-length isn't calculated correctly
15
+ # resulting in only partial responses being sent to users
16
+ # you can remove it or recalculate it here
17
+ headers["content-length"] = nil
18
+
19
+ triplet
20
+ end
21
+
22
+ end
23
+
24
+ Rails.application.config.middleware.use TrustingProxy, backend: 'https://self-signed.badssl.com', streaming: false
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
8
8
  s.platform = Gem::Platform::RUBY
9
9
  s.authors = ["Jacek Becela"]
10
10
  s.email = ["jacek.becela@gmail.com"]
11
- s.homepage = "http://rubygems.org/gems/rack-proxy"
11
+ s.homepage = "https://github.com/ncr/rack-proxy"
12
12
  s.summary = %q{A request/response rewriting HTTP proxy. A Rack app.}
13
13
  s.description = %q{A Rack app that provides request/response rewriting proxy capabilities with streaming.}
14
14
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-proxy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.3
4
+ version: 0.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jacek Becela
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-08 00:00:00.000000000 Z
11
+ date: 2018-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -71,12 +71,16 @@ files:
71
71
  - lib/rack-proxy.rb
72
72
  - lib/rack/http_streaming_response.rb
73
73
  - lib/rack/proxy.rb
74
+ - lib/rack_proxy_examples/example_service_proxy.rb
75
+ - lib/rack_proxy_examples/forward_host.rb
76
+ - lib/rack_proxy_examples/rack_php_proxy.rb
77
+ - lib/rack_proxy_examples/trusting_proxy.rb
74
78
  - rack-proxy.gemspec
75
79
  - test/http_streaming_response_test.rb
76
80
  - test/net_http_hacked_test.rb
77
81
  - test/rack_proxy_test.rb
78
82
  - test/test_helper.rb
79
- homepage: http://rubygems.org/gems/rack-proxy
83
+ homepage: https://github.com/ncr/rack-proxy
80
84
  licenses: []
81
85
  metadata: {}
82
86
  post_install_message:
@@ -95,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
99
  version: '0'
96
100
  requirements: []
97
101
  rubyforge_project: rack-proxy
98
- rubygems_version: 2.5.1
102
+ rubygems_version: 2.5.2.2
99
103
  signing_key:
100
104
  specification_version: 4
101
105
  summary: A request/response rewriting HTTP proxy. A Rack app.