Encontré este gran blog post sobre cómo usar Rack::Proxy
como una aplicación proxy independiente. El artículo explica cómo usa Rack::Proxy
para solicitudes de proxy al http://localhost:3000
a una aplicación en el puerto 3001
y solicita a http://localhost:3000/api
una aplicación en el puerto 3002
. Quiero hacer lo mismo, pero no quiero crear una aplicación de proxy por separado. En cambio, quiero que mi aplicación Rails principal envíe solicitudes de proxy al /blog
a una aplicación diferente.¿Cómo puedo usar Rack :: Proxy dentro de Rails para enviar solicitudes de proxy a una ruta específica a otra aplicación?
Respuesta
descubierto.
lib/proxy.rbrequire 'rack-proxy'
class Proxy < Rack::Proxy
def initialize(app)
@app = app
end
def rewrite_env(env)
# do magic in here
end
end
config/application.rb
config.middleware.use "Proxy"
Fwiw, que también acaba de abordar este problema. Algunos pueden encontrar el código completo útiles, ya que necesitaba más informados:
# lib/proxy_to_other.rb
class ProxyToOther < Rack::Proxy
def initialize(app)
@app = app
end
def call(env)
original_host = env["HTTP_HOST"]
rewrite_env(env)
if env["HTTP_HOST"] != original_host
perform_request(env)
else
# just regular
@app.call(env)
end
end
def rewrite_env(env)
request = Rack::Request.new(env)
if request.path =~ %r{^/prefix|^/other_prefix}
# do nothing
else
env["HTTP_HOST"] = "localhost:3000"
end
env
end
end
también:
# config/application.rb
# ...snip ...
module MyApplication
class Application < Rails::Application
# Custom Rack middlewares
config.middleware.use "ProxyToOther" if ["development", "test"].include? Rails.env
#...snip....
Esto supone que su aplicación que desea proxy de algunas peticiones para que se ejecuta en el puerto 3001. I supongamos que la aplicación a la que estás golpeando se puede ejecutar en cualquier puerto. Esto también asume que solo desea realizar el proxy en entornos de desarrollo y prueba, ya que tendrá una solución "real" en la producción & en etapas (por ejemplo, nginx o un balanceador de carga haciendo lo correcto).
Esto es grande.Si desea realizar un proxy a una aplicación arbitraria en Internet, también puede tener que establecer 'env [" SERVER_PORT "] = 80' –
" Esto también asume que solo desea realizar el proxy en entornos de desarrollo y prueba, porque usted ' Tendré una solución "real" en producción y puesta en escena (por ejemplo, nginx o un equilibrador de carga haciendo lo correcto) ". - ¿Porqué es eso? ¿No debería usar Rack :: Proxy en producción? –
@DavidLojudiceSobrinho sin duda podría, pero sería mejor hacer eso proxying con nginx/apache o un loadbalancer. Utilizará un hilo en su aplicación para hacer una solicitud HTTP sincrónica a otro servidor. Simplemente no es un uso inteligente de los recursos. – steve
Se trata de un pequeño cambio en la solución de Steve que utiliza un poco menos la comprensión interna de Rack::Proxy
:
require 'rack/proxy'
class MyProxy < Rack::Proxy
def initialize(app)
@app = app
end
def call(env)
# call super if we want to proxy, otherwise just handle regularly via call
(proxy?(env) && super) || @app.call(env)
end
def proxy?(env)
# do not alter env here, but return true if you want to proxy for this request.
return true
end
def rewrite_env(env)
# change the env here
env["HTTP_HOST"] = "some.other.host"
env
end
end
A continuación se muestra el código aún más fácil de proxy de una API cuando se quiere http://localhost:3000/api/users/1 (por ejemplo) para ir a la espacio de nombres api definido en routes.rb sin usar un programa de servidor proxy.
En producción sería algo así como http://api.sample.com/users/1.
lib/proxy.rb
require 'rack-proxy'
class Proxy < Rack::Proxy
def perform_request(env)
request = Rack::Request.new(env)
if request.path =~ %r{^/api}
#do nothing
else
@app.call(env)
end
end
end
config/application.rb
config.middleware.use "Proxy"
config/routes.rb
namespace :api, defaults: { format: :json },
constraints: { subdomain: 'api' }, path: '/' do
scope module: :v1, constraints: ApiConstraints.new(version: 1, default: true) do
resources :users, :only => [:show, :create, :update, :destroy]
end
lib/api_constraints.rb
class ApiConstraints
def initialize(options)
@version = options[:version]
@default = options[:default]
end
def matches?(req)
@default || req.headers['Accept'].include?("application/vnd.sample.v#{@version}")
end
end
- 1. PHP: Proxy otra url
- 2. Cómo puedo obtener Hudson para actualizar a través de Proxy
- 3. Acceso a beans proxy de ámbito dentro de Threads of
- 4. ¿Puedo usar http tunnel para hacer ping o traceroute a través de un proxy con firewall?
- 5. cómo agregar soporte proxy para impulsar :: asio?
- 6. ¿Cómo configuro Go para usar un proxy?
- 7. ¿Cómo puedo enviar claves a otra aplicación usando Delphi 7?
- 8. ¿Cómo usar CURL a través de un proxy?
- 9. FTP a proxy FTPS
- 10. rails paquete de instalación a través de proxy en Windows
- 11. C# Conectando a través de Proxy
- 12. Castle DynamicProxy: ¿Cómo se Equivale a Proxy cuando se utiliza una interfaz de proxy?
- 13. Javassist: ¿cómo crear proxy de proxy?
- 14. git: // a través del proxy
- 15. TortoiseSVN a través de un script proxy
- 16. Usando RestTemplate, ¿cómo enviar la solicitud a un proxy primero para que pueda usar mis junits con JMeter?
- 17. puedo usar adb shell para enviar comandos a mi aplicación
- 18. Conectar a través de proxy BitBucket
- 19. Cómo usar git detrás de un proxy
- 20. Aplicación Rails3 detrás de un Proxy
- 21. Cómo usar el proxy con la aplicación C#
- 22. ¿Algo parecido a MySQL Proxy para PostgreSQL?
- 23. ¿Redirigir localhost a través del proxy?
- 24. Socks Proxy para HttpWebRequest
- 25. https redirect for rails app behind proxy?
- 26. Servidor proxy HTTP
- 27. Error de proxy de Python con la biblioteca de solicitudes
- 28. CherryPy detrás de Nginx reverse-proxy POST solicitudes corrompidas/truncadas
- 29. Generación de proxy wcf frente a ChannelFactory
- 30. ¿Cómo se sirven los archivos estáticos a través de Rack?
habría sido agradable ver qué es exactamente la "magia" era que estabas hablando de – steve
puede poner Proxy.rb en app/middleware en los carriles 4 –