Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using Rack::Proxy as a middleware instead of using it as a standard Ruby class #55

Merged
merged 11 commits into from
May 19, 2016
19 changes: 19 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
sudo: false
cache: bundler
language: ruby
before_install:
- "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
- gem install bundler
- gem update bundler
script: bundle exec rake test
rvm:
- 2.0.0
- 2.1.5
- 2.2.2
- 2.2.3
- 2.3.0
- 2.3.1
env:
- RAILS_ENV=test RACK_ENV=test
notifications:
email: false
7 changes: 7 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ PATH
GEM
remote: http://rubygems.org/
specs:
power_assert (0.2.6)
rack (1.2.1)
rack-test (0.5.6)
rack (>= 1.0)
rake (0.9.2.2)
test-unit (3.1.5)
power_assert

PLATFORMS
ruby
Expand All @@ -19,3 +22,7 @@ DEPENDENCIES
rack-proxy!
rack-test
rake
test-unit

BUNDLED WITH
1.12.4
55 changes: 48 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
A request/response rewriting HTTP proxy. A Rack app.
Subclass `Rack::Proxy` and provide your `rewrite_env` and `rewrite_response` methods.
A request/response rewriting HTTP proxy. A Rack app. Subclass `Rack::Proxy` and provide your `rewrite_env` and `rewrite_response` methods.


## Example
Example
-------

```ruby
class Foo < Rack::Proxy
Expand Down Expand Up @@ -44,12 +43,54 @@ The same can be achieved for *all* requests going through the `Rack::Proxy` inst
Rack::Proxy.new(ssl_verify_none: true)
```

Using it as a middleware:
-------------------------

Example: Proxying only requests that end with ".php" could be done like this:

```ruby
require 'rack/proxy'
class RackPhpProxy < Rack::Proxy

def perform_request(env)
request = Rack::Request.new(env)
if request.path =~ %r{\.php}
env["HTTP_HOST"] = "localhost"
env["REQUEST_PATH"] = "/php/#{request.fullpath}"
super(env)
else
@app.call(env)
end
end
end
```

To use the middleware, please consider the following:

1) For Rails we could add a configuration in config/application.rb

```ruby
config.middleware.use RackPhpProxy, {ssl_verify_none: true}
```

2) For Sinatra or any Rack-based application:

```ruby
class MyAwesomeSinatra < Sinatra::Base
use RackPhpProxy, {ssl_verify_none: true}
end
```

This will allow to run the other requests through the application and only proxy the requests that match the condition from the middleware.

See tests for more examples.

## WARNING
WARNING
-------

Doesn't work with fakeweb/webmock. Both libraries monkey-patch net/http code.

## Todos
Todos
-----

* 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.
- 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.
8 changes: 7 additions & 1 deletion lib/rack/proxy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,13 @@ def reconstruct_header_name(name)
end

# @option opts [String, URI::HTTP] :backend Backend host to proxy requests to
def initialize(opts = {})
def initialize(app = nil, opts= {})
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would have to be backward compatible: if the first arg is a hash, then it should be assigned to the opts variable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, just wanted to make sure. Thank you

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still need that conditional check for the app param being a hash :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added the conditional

if app.is_a?(Hash)
opts = app
@app = nil
else
@app = app
end
@streaming = opts.fetch(:streaming, true)
@ssl_verify_none = opts.fetch(:ssl_verify_none, false)
@backend = URI(opts[:backend]) if opts[:backend]
Expand Down
1 change: 1 addition & 0 deletions rack-proxy.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ Gem::Specification.new do |s|

s.add_dependency("rack")
s.add_development_dependency("rack-test")
s.add_development_dependency("test-unit")
end
2 changes: 2 additions & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
require "rubygems"
require 'bundler/setup'
require 'bundler/gem_tasks'
require "test/unit"

require "rack"
Expand Down