2011-02-11 55 views
7

我试图使用Ruby Sinatra和创建特定的网页一个简单的代理单页的代理。我能做到这一点在C#中,我似乎无法去解决它的末日,在C#代码如下:创建使用Ruby西纳特拉

<%@ 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; 
    } 
} 

} 

红宝石西纳特拉的代码,我已经试过如下:

require 'rubygems' 
require 'sinatra' 

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

我假设西纳特拉一个不工作(获得404)如只将请求传递给页面在同一个域中。任何hep将不胜感激。

编辑:

随着铁皮人的帮助下,我想出了一个很好的解决方案简洁,这对我来说工作得很好:

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

感谢所有帮助。

回答

4

如果你希望你的末日应用检索URL,你需要火了某种形式的HTTP客户端:

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

我认为这会工作,大约是最小的,你可以得到。

,如果你需要更多的tweakability你可以使用HTTPClient

而且,我认为,机架可以做到这一点。 Sinatra建立在Rack之上,但是我在这个级别上玩了一段时间。

我还需要找到一种方法,从响应中提取的contentType

Open-URI文档:

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 
} 

你的目的是这样应该工作:

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

我没有测试过,但我想换货政...块的值将被分配到body。如果不行,那就试试吧:

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

但是我觉得第一个会工作。

+0

干杯。这看起来很有希望......我现在只是在尝试一些东西...... – 2011-02-11 15:24:04

+0

您需要添加一些异常处理,并且可能希望使用`Timeout`模块来提供更好的控制,以便在请求也被采用时长。请参阅http://stackoverflow.com/questions/4964044/using-open-uri-to-fetch-xml-and-the-best-practice-in-case-of-problems-with-a-remo/4966240#4966240举些例子。 – 2011-02-11 15:30:07

1

随着帮助铁皮人TK-421我已经研究出了解决办法,请参见下面的西纳特拉路线:

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

只是你需要的页面替换<URI>,你很好走。

再过了些玩,这是我想出来的:

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

至于其他提到的,你需要require 'open-uri'在代码的顶部。 gsub的原因是由于某些原因,解析失败,如果他们留在,我的浏览器不会自动编码它们。