A summary of data about the Ruby ecosystem.

https://github.com/ncr/rack-proxy

A request/response rewriting HTTP proxy. A Rack app.
https://github.com/ncr/rack-proxy

Keywords from Contributors

crash-reporting activerecord rubygems activejob mvc background-jobs sidekiq rack jobs error-monitoring

Last synced: about 21 hours ago
JSON representation

Repository metadata

A request/response rewriting HTTP proxy. A Rack app.

README.md

A request/response rewriting HTTP proxy. A Rack app. Subclass Rack::Proxy and provide your rewrite_env and rewrite_response methods.

Installation

Add the following to your Gemfile:

gem 'rack-proxy', '~> 0.7.7'

Or install:

gem install rack-proxy

Use Cases

Below are some examples of real world use cases for Rack-Proxy. If you have done something interesting, add it to the list below and send a PR.

  • Allowing one app to act as central trust authority
    • handle accepting self-sign certificates for internal apps
    • authentication / authorization prior to proxying requests to a blindly trusting backend
    • avoiding CORs complications by proxying from same domain to another backend
  • subdomain based pass-through to multiple apps
  • Complex redirect rules
    • redirect pages with different extensions (ex: .php) to another app
    • useful for handling awkward redirection rules for moved pages
  • fan Parallel Requests: turning a single API request to multiple concurrent backend requests & merging results.
  • inserting or stripping headers required or problematic for certain clients

Options

Options can be set when initializing the middleware or overriding a method.

  • :streaming - defaults to true, but does not work on all Ruby versions, recommend to set to false
  • :ssl_verify_none - tell Net::HTTP to not validate certs
  • :ssl_version - tell Net::HTTP to set a specific ssl_version
  • :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.
  • :read_timeout - set proxy timeout it defaults to 60 seconds

To pass in options, when you configure your middleware you can pass them in as an optional hash.

Rails.application.config.middleware.use ExampleServiceProxy, backend: 'http://guides.rubyonrails.org', streaming: false

Examples

See and run the examples below from lib/rack_proxy_examples/. To mount any example into an existing Rails app:

  1. create config/initializers/proxy.rb
  2. modify the file to require the example file
require 'rack_proxy_examples/forward_host'

Forward request to Host and Insert Header

Test with require 'rack_proxy_examples/forward_host'

class ForwardHost < Rack::Proxy

  def rewrite_env(env)
    env["HTTP_HOST"] = "example.com"
    env
  end

  def rewrite_response(triplet)
    status, headers, body = triplet

    # example of inserting an additional header
    headers["X-Foo"] = "Bar"

    # if you rewrite env, it appears that content-length isn't calculated correctly
    # resulting in only partial responses being sent to users
    # you can remove it or recalculate it here
    headers["content-length"] = nil

    triplet
  end

end

Disable SSL session verification when proxying a server with e.g. self-signed SSL certs

Test with require 'rack_proxy_examples/trusting_proxy'

class TrustingProxy < Rack::Proxy

  def rewrite_env(env)
    env["HTTP_HOST"] = "self-signed.badssl.com"

    # We are going to trust the self-signed SSL
    env["rack.ssl_verify_none"] = true
    env
  end

  def rewrite_response(triplet)
    status, headers, body = triplet

    # if you rewrite env, it appears that content-length isn't calculated correctly
    # resulting in only partial responses being sent to users
    # you can remove it or recalculate it here
    headers["content-length"] = nil

    triplet
  end

end

The same can be achieved for all requests going through the Rack::Proxy instance by using

Rack::Proxy.new(ssl_verify_none: true)

Rails middleware example

Test with require 'rack_proxy_examples/example_service_proxy'

###
# This is an example of how to use Rack-Proxy in a Rails application.
#
# Setup:
# 1. rails new test_app
# 2. cd test_app
# 3. install Rack-Proxy in `Gemfile`
#    a. `gem 'rack-proxy', '~> 0.7.7'`
# 4. install gem: `bundle install`
# 5. create `config/initializers/proxy.rb` adding this line `require 'rack_proxy_examples/example_service_proxy'`
# 6. run: `SERVICE_URL=http://guides.rubyonrails.org rails server`
# 7. open in browser: `http://localhost:3000/example_service`
#
###
ENV['SERVICE_URL'] ||= 'http://guides.rubyonrails.org'

class ExampleServiceProxy < Rack::Proxy
  def perform_request(env)
    request = Rack::Request.new(env)

    # use rack proxy for anything hitting our host app at /example_service
    if request.path =~ %r{^/example_service}
        backend = URI(ENV['SERVICE_URL'])
        # most backends required host set properly, but rack-proxy doesn't set this for you automatically
        # even when a backend host is passed in via the options
        env["HTTP_HOST"] = backend.host

        # This is the only path that needs to be set currently on Rails 5 & greater
        env['PATH_INFO'] = ENV['SERVICE_PATH'] || '/configuring.html'

        # don't send your sites cookies to target service, unless it is a trusted internal service that can parse all your cookies
        env['HTTP_COOKIE'] = ''
        super(env)
    else
      @app.call(env)
    end
  end
end

Using as middleware to forward only some extensions to another Application

Test with require 'rack_proxy_examples/rack_php_proxy'

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

###
# Open http://localhost:3000/test.php to trigger proxy
###
class RackPhpProxy < Rack::Proxy

  def perform_request(env)
    request = Rack::Request.new(env)
    if request.path =~ %r{\.php}
      env["HTTP_HOST"] = ENV["HTTP_HOST"] ? URI(ENV["HTTP_HOST"]).host : "localhost"
      ENV["PHP_PATH"] ||= '/manual/en/tutorial.firstpage.php'

      # Rails 3 & 4
      env["REQUEST_PATH"] = ENV["PHP_PATH"] || "/php/#{request.fullpath}"
      # Rails 5 and above
      env['PATH_INFO'] = ENV["PHP_PATH"] || "/php/#{request.fullpath}"

      env['content-length'] = nil

      super(env)
    else
      @app.call(env)
    end
  end

  def rewrite_response(triplet)
    status, headers, body = triplet

    # if you proxy depending on the backend, it appears that content-length isn't calculated correctly
    # resulting in only partial responses being sent to users
    # you can remove it or recalculate it here
    headers["content-length"] = nil

    triplet
  end
end

To use the middleware, please consider the following:

  1. For Rails we could add a configuration in config/application.rb
  config.middleware.use RackPhpProxy, {ssl_verify_none: true}
  1. For Sinatra or any Rack-based application:
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.

SSL proxy for SpringBoot applications debugging

Whenever you need to debug communication with external services with HTTPS protocol (like OAuth based) you have to be able to access to your local web app through HTTPS protocol too. Typical way is to use nginx or Apache httpd as a reverse proxy but it might be inconvinuent for development environment. Simple proxy server is a better way in this case. The only what we need is to unpack incoming SSL queries and proxy them to a backend. We can prepare minimal set of files to create autonomous proxy server.

Create config.ru file:

#
# config.ru
#
require 'rack'
require 'rack-proxy'

class ForwardHost < Rack::Proxy
  def rewrite_env(env)
    env['HTTP_X_FORWARDED_HOST'] = env['SERVER_NAME']
    env['HTTP_X_FORWARDED_PROTO'] = env['rack.url_scheme']
    env
  end
end

run ForwardHost.new(backend: 'http://localhost:8080')

Create Gemfile file:

source "https://rubygems.org"

gem 'thin'
gem 'rake'
gem 'rack-proxy'

Create config.yml file with configuration of web server thin:

---
ssl: true
ssl-key-file: keys/domain.key
ssl-cert-file: keys/domain.crt
ssl-disable-verify: false

Create 'keys' directory and generate SSL key and certificates files domain.key and domain.crt

Run bundle exec thin start for running it with thin's default port.

Or use sudo -E thin start -C config.yml -p 443 for running with default for https:// port.

Don't forget to enable processing of X-Forwarded-... headers on your application side. Just add following strings to your resources/application.yml file.

---
server:
  tomcat:
    remote-ip-header: x-forwarded-for
    protocol-header:  x-forwarded-proto
  use-forward-headers:  true

Add some domain name like debug.your_app.com into your local /etc/hosts file like

127.0.0.1	debug.your_app.com

Next start the proxy and your app. And now you can access to your Spring application through SSL connection via https://debug.your_app.com URI in a browser.

Using SSL/TLS certificates with HTTP connection

This may be helpful, when third-party API has authentication by client TLS certificates and you need to proxy your requests and sign them with certificate.

Just specify Rack::Proxy SSL options and your request will use TLS HTTP connection:

# config.ru
. . .

cert_raw = File.read('./certs/rootCA.crt')
key_raw = File.read('./certs/key.pem')

cert = OpenSSL::X509::Certificate.new(cert_raw)
key = OpenSSL::PKey.read(key_raw)

use TLSProxy, cert: cert, key: key, use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_PEER, ssl_version: 'TLSv1_2'

And rewrite host for example:

# tls_proxy.rb
class TLSProxy < Rack::Proxy
  attr_accessor :original_request, :query_params

  def rewrite_env(env)
    env["HTTP_HOST"] = "client-tls-auth-api.com:443"
    env
  end
end

WARNING

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

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.
  • Improve and validate requirements for Host and Path rewrite rules
  • Ability to inject logger and set log level

Owner metadata


GitHub Events

Total
Last Year

Committers metadata

Last synced: 2 days ago

Total Commits: 157
Total Committers: 52
Avg Commits per committer: 3.019
Development Distribution Score (DDS): 0.535

Commits in past year: 0
Committers in past year: 0
Avg Commits per committer in past year: 0.0
Development Distribution Score (DDS) in past year: 0.0

Name Email Commits
Jacek Becela j****a@g****m 73
Rada Bogdan Raul r****e@y****m 10
Andrey Dolgikh l****r@y****u 5
André Laszlo l****o@k****o 5
Ben Marchant b****t@h****m 4
dependabot[bot] 4****] 3
Whitney Young w****g@f****m 3
Rick Fletcher f****h@p****m 3
Vladimir Temnikov v****v@a****m 2
Olle Jonsson o****n@g****m 2
Nicholas Hemsley n****s@g****m 2
Jake Worth j****e@j****m 2
Mikdiet m****t@g****m 2
sbopr s****t@x****m 2
Danny Guinther d****y@b****m 2
Tim Case t****m@2****t 1
Steve Hull s****e@t****m 1
Raul E Rangel R****l@d****m 1
Matt Colyer m****t@s****m 1
Exoth y****o@a****u 1
Dan Mayer d****r@o****m 1
Bevan Loon b****n@d****k 1
Adam Pohorecki a****m@p****l 1
Beth Skurrie b****h@b****m 1
Bill Abresch b****h@a****m 1
Filippos Vasilakis v****l@g****m 1
sandip mondal s****5@y****n 1
rssdev10 r****0@g****m 1
pex r****t@f****t 1
ooooooo-q o****q 1
and 22 more...

Committer domains:


Issue and Pull Request metadata

Last synced: 9 days ago

Total issues: 41
Total pull requests: 63
Average time to close issues: over 1 year
Average time to close pull requests: 7 months
Total issue authors: 38
Total pull request authors: 48
Average comments per issue: 1.73
Average comments per pull request: 1.48
Merged pull request: 51
Bot issues: 0
Bot pull requests: 9

Past year issues: 2
Past year pull requests: 0
Past year average time to close issues: N/A
Past year average time to close pull requests: N/A
Past year issue authors: 1
Past year pull request authors: 0
Past year average comments per issue: 0.0
Past year average comments per pull request: 0
Past year merged pull request: 0
Past year bot issues: 0
Past year bot pull requests: 0

More stats: https://issues.ecosyste.ms/repositories/lookup?url=https://github.com/ncr/rack-proxy

Top Issue Authors

  • jp (2)
  • nhemsley (2)
  • ioquatix (2)
  • tleish (1)
  • ndbroadbent (1)
  • pravi (1)
  • shomid (1)
  • amitfriedman12 (1)
  • rahulbir (1)
  • jonleighton (1)
  • glongman (1)
  • timwis (1)
  • Silex (1)
  • vladimirtemnikov (1)
  • jjb (1)

Top Pull Request Authors

  • dependabot[bot] (10)
  • nhemsley (4)
  • mikdiet (2)
  • binaryseed (2)
  • rfletcher (2)
  • olleolleolle (2)
  • pex (1)
  • danmayer (1)
  • glongman (1)
  • vasilakisfil (1)
  • jjb (1)
  • kaspergrubbe (1)
  • voikya (1)
  • psyho (1)
  • ooooooo-q (1)

Top Issue Labels

  • help needed (2)

Top Pull Request Labels

  • dependencies (10)

Package metadata

gem.coop: rack-proxy

A Rack app that provides request/response rewriting proxy capabilities with streaming.

  • Homepage: https://github.com/ncr/rack-proxy
  • Documentation: http://www.rubydoc.info/gems/rack-proxy/
  • Licenses: MIT
  • Latest release: 0.7.7 (published over 2 years ago)
  • Last Synced: 2026-03-02T02:32:23.534Z (1 day ago)
  • Versions: 43
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Downloads: 162,138,710 Total
  • Docker Downloads: 554,612,924
  • Rankings:
    • Dependent repos count: 0.0%
    • Dependent packages count: 0.0%
    • Average: 0.082%
    • Downloads: 0.156%
    • Docker downloads count: 0.173%
  • Maintainers (1)
rubygems.org: rack-proxy

A Rack app that provides request/response rewriting proxy capabilities with streaming.

  • Homepage: https://github.com/ncr/rack-proxy
  • Documentation: http://www.rubydoc.info/gems/rack-proxy/
  • Licenses: MIT
  • Latest release: 0.7.7 (published over 2 years ago)
  • Last Synced: 2026-03-02T01:30:50.886Z (1 day ago)
  • Versions: 43
  • Dependent Packages: 48
  • Dependent Repositories: 124,808
  • Downloads: 162,138,710 Total
  • Docker Downloads: 554,612,924
  • Rankings:
    • Dependent repos count: 0.108%
    • Downloads: 0.156%
    • Docker downloads count: 0.21%
    • Dependent packages count: 0.55%
    • Average: 1.208%
    • Forks count: 2.708%
    • Stargazers count: 3.515%
  • Maintainers (1)
ubuntu-24.04: ruby-rack-proxy

  • Homepage: https://github.com/ncr/rack-proxy
  • Licenses:
  • Latest release: 0.7.7-1 (published 25 days ago)
  • Last Synced: 2026-02-06T15:50:56.228Z (25 days ago)
  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
ubuntu-23.04: ruby-rack-proxy

  • Homepage: https://github.com/ncr/rack-proxy
  • Licenses:
  • Latest release: 0.7.4-1 (published 20 days ago)
  • Last Synced: 2026-02-11T06:47:26.167Z (20 days ago)
  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
    • Dependent repos count: 0.0%
    • Dependent packages count: 0.0%
    • Average: 100%
ubuntu-23.10: ruby-rack-proxy

  • Homepage: https://github.com/ncr/rack-proxy
  • Licenses:
  • Latest release: 0.7.6-2 (published 18 days ago)
  • Last Synced: 2026-02-13T18:30:18.031Z (18 days ago)
  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
    • Dependent repos count: 0.0%
    • Dependent packages count: 0.0%
    • Average: 100%
ubuntu-24.10: ruby-rack-proxy

  • Homepage: https://github.com/ncr/rack-proxy
  • Licenses:
  • Latest release: 0.7.7-1 (published 22 days ago)
  • Last Synced: 2026-02-09T17:04:33.023Z (22 days ago)
  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
debian-12: ruby-rack-proxy

  • Homepage: https://github.com/ncr/rack-proxy
  • Documentation: https://packages.debian.org/bookworm/ruby-rack-proxy
  • Licenses:
  • Latest release: 0.7.4-1 (published 18 days ago)
  • Last Synced: 2026-02-12T23:38:16.504Z (18 days ago)
  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
debian-13: ruby-rack-proxy

  • Homepage: https://github.com/ncr/rack-proxy
  • Documentation: https://packages.debian.org/trixie/ruby-rack-proxy
  • Licenses:
  • Latest release: 0.7.7-1 (published 19 days ago)
  • Last Synced: 2026-02-13T13:18:52.496Z (18 days ago)
  • Versions: 1
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Rankings:
    • Dependent repos count: 0.0%
    • Dependent packages count: 0.0%
    • Average: 100%

Dependencies

Gemfile rubygems
  • rake >= 0
Gemfile.lock rubygems
  • power_assert 0.2.6
  • rack 2.2.3
  • rack-proxy 0.7.2
  • rack-test 0.5.6
  • rake 13.0.6
  • test-unit 3.1.5
rack-proxy.gemspec rubygems
  • rack-test >= 0 development
  • test-unit >= 0 development
  • rack >= 0

Score: 30.694200648023486