Module: Rack::Reproxy

Defined in:
lib/rack/reproxy.rb

Overview

Reproxy

Allow Rack responses to be proxied from a different URL. It’s like Rack::Sendfile, but for any HTTP backend.

Rack apps can return a URI as a response body (or an X-Reproxy-Url header) and we pass it upstream to Nginx/Apache/Lighttpd to serve.

This is an approach pioneered by MogileFS using perlbal to reproxy file requests to an internal storage backend.

Proxing to an internal app: serving private files

Rack::Sendfile can efficiently serve files from the local filesystem. But that means you have to have your files NFS-mounted on all your app servers, and you have to know their physical paths.

Instead, you can expose your file server as a private HTTP service and reproxy requests to it. Get rid of fussy NFS mounts and just stream files back from your internal server.

Proxying to yourself

You can reproxy requests back to your own app, too. This is useful when you you’d like to HTTP-cache private, authenticated content. You can’t put a public HTTP cache in front of your app, but you can put it in the middle!

Your app receives a request, authenticates, and proxies its own response via an internal HTTP cache that’s backed by… your app.

Nginx

# In config.ru

use Rack::Reproxy::Nginx, location: '/reproxy'

# Nginx config

location /reproxy {
  internal;
  set $reproxy_url $upstream_http_x_reproxy_url;
  proxy_pass $reproxy_url;
}

Apache with mod_reproxy

# In config.ru

use Rack::Reproxy::Apache

# Apache config

<Location />
  AllowReproxy on
  PreserveHeaders Content-Type Content-Disposition ETag Last-Modified
</Location>

Lighttpd

# In config.ru

use Rack::Reproxy::Lighttpd

# Lighttpd config

proxy-core.allow-x-rewrite = "enable"

Rack

Wait, what? Yeah, you can reproxy without doing an HTTP roundtrip by immediately redispatching back to your own app. This only becomes useful when you do something like reproxy through Rack::Cache.

# In config.ru

use Rack::Reproxy::Rack

# To proxy to a different Rack app

use Rack::Reproxy::Rack, app: SomeInternalApp.new

Defined Under Namespace

Classes: Apache, Lighttpd, Middleware, Nginx, Rack