module Rack::Reproxy
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