2011-02-11 8 views
7

Estoy intentando usar Ruby Sinatra para crear un proxy simple para una página web específica. Puedo hacerlo en C#, sólo parece que no puede trabajar fuera de Sinatra, el código C# es el siguiente:Creación de un único proxy de página con Ruby Sinatra

<%@ WebHandler Language="C#" Class="Map" %> 

using System; 
using System.Web; 
using System.Net; 
using System.IO; 

public class Map : IHttpHandler { 

static void CopyStream(Stream input, Stream output) 
{ 
    byte[] buffer = new byte[0x1000]; 
    int read; 
    while ((read = input.Read(buffer, 0, buffer.Length)) > 0) 
     output.Write(buffer, 0, read); 
} 

public void ProcessRequest(HttpContext context) 
{ 
    string gmapUri = string.Format("http://maps.google.com/maps/api/staticmap{0}", context.Request.Url.Query); 
    WebRequest request = WebRequest.Create(gmapUri); 

    using (WebResponse response = request.GetResponse()) 
    { 
     context.Response.ContentType = response.ContentType; 
     Stream responseStream = response.GetResponseStream(); 

     CopyStream(responseStream, context.Response.OutputStream); 
    } 
} 

public bool IsReusable { 
    get { 
     return false; 
    } 
} 

} 

El código Ruby Sinatra He tratado es el siguiente:

require 'rubygems' 
require 'sinatra' 

get '/mapsproxy/staticmap' do 
    request.path_info = 'http://maps.google.com/maps/api/staticmap' 
    pass 
end 

Supongo que el Sinatra no funciona (obtenga un 404) ya que solo pasa la solicitud a páginas del mismo dominio. Cualquier hepatitis sería muy apreciada.

EDIT:

Con ayuda del hombre de la lata 's que he llegado a una solución sucinta agradable, que funciona bien para mí:

get '/proxy/path' do 
    URI.parse(<URI> + request.query_string.gsub("|", "%7C")).read 
end 

Gracias por toda la ayuda.

Respuesta

4

Si desea que su aplicación Sinatra para recuperar la URL, que necesita para arrancar un cliente HTTP de algún tipo:

get '/mapsproxy/staticmap' do 
    require 'open-uri' 
    open('http://maps.google.com/maps/api/staticmap').read 
end 

Creo que esto va a funcionar y se trata como mínimo, ya que se puede obtener .

Puede usar HTTPClient si necesita más tweakability.

Además, creo que Rack puede hacerlo. Sinatra está construido sobre Rack, pero ha pasado un tiempo desde que jugué en ese nivel.

todavía tengo que encontrar una manera de extraer el contentType de la respuesta

De los Open-URI docs:

The opened file has several methods for meta information as follows since 
it is extended by OpenURI::Meta. 

open("http://www.ruby-lang.org/en") {|f| 
    f.each_line {|line| p line} 
    p f.base_uri   # <URI::HTTP:0x40e6ef2 URL:http://www.ruby-lang.org/en/> 
    p f.content_type  # "text/html" 
    p f.charset   # "iso-8859-1" 
    p f.content_encoding # [] 
    p f.last_modified # Thu Dec 05 02:45:02 UTC 2002 
} 

para sus propósitos algo como esto debería funcionar:

content_type = '' 
body = open("http://www.ruby-lang.org/en") {|f| 
    content_type = f.content_type  # "text/html" 
    f.read 
} 

No lo he probado, pero creo que el retu El valor rn del bloque se asignará a body. Si eso no funciona, intente:

content_type = '' 
body = '' 
open("http://www.ruby-lang.org/en") {|f| 
    content_type = f.content_type  # "text/html" 
    body = f.read 
} 

pero creo que la primera funcionará.

+0

Saludos. Esto parece prometedor ... Solo estoy tratando de resolverlo ... –

+0

Debería agregar un poco de manejo de excepciones, y probablemente quiera utilizar el módulo 'Timeout' para proporcionar un mejor control en caso de que también se solicite una solicitud largo. Ver http://stackoverflow.com/questions/4964044/using-open-uri-to-fetch-xml-and-the-best-practice-in-case-of-problems-with-a-remo/4966240#4966240 por ejemplo. –

+0

Parece que funciona bien con respuestas basadas en texto, aunque las reformatea, pero no las de imagen. Creo que necesito transmitir de alguna manera la respuesta a la respuesta de Sinatra ... –

1

Con la ayuda de el hombre de hojalata yTK-421 he trabajado para encontrar una solución, ver la ruta Sinatra a continuación:

get '/proxy/path' do 
    require 'open-uri' 
    uri = URI.parse(<URI>) 
    getresult = uri.read 
    halt 200, {'Content-Type' => getresult.content_type}, getresult 
end 

Basta con sustituir el <URI> con la página que necesita, y estás listo para irte

Después de poco más jugando esto es lo que he llegado con:

get '/proxy/path' do 
    URI.parse(<URI> + request.query_string.gsub("|", "%7C")).read 
end 

Como se ha mencionado en otro lugar que necesita para require 'open-uri' en la parte superior del código. El motivo del gsub es que, por alguna razón, el análisis falla si se dejan y mi navegador no los codifica automáticamente.

+0

el Hombre de Hojalatero proporcionó la respuesta correcta. Es bueno ver que está funcionando. Entonces, ¿te gusta más Ruby que C#? ;) –

+0

Puedes simplemente usar 'return getresult' en lugar de' halt 200, {'Content-Type' => getresult.content_type}, getresult' ya que el uri devuelve una respuesta completa, hasta donde yo sé. –

+0

Nunca me ha gustado C#, solo lo uso para el trabajo, prefiero los idiomas interpretados para mi propia codificación (lisp, Scheme, Clojure, JavaScript). Soy bastante nuevo para Ruby, pero realmente lo disfruto :) –

Cuestiones relacionadas