wm.*_*agg 7 ruby proxy sinatra
我正在尝试使用Ruby Sinatra为特定网页创建一个简单的代理.我可以用C#来做,我似乎无法为Sinatra工作,C#代码如下:
<%@ 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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我尝试过的Ruby Sinatra代码如下:
require 'rubygems'
require 'sinatra'
get '/mapsproxy/staticmap' do
request.path_info = 'http://maps.google.com/maps/api/staticmap'
pass
end
Run Code Online (Sandbox Code Playgroud)
我假设Sinatra一个不起作用(获得404),因为只是将请求传递给同一域中的页面.任何肝脏将非常感激.
编辑:
随着铁皮人的帮助下,我想出了一个很好的解决方案简洁,这对我来说工作得很好:
get '/proxy/path' do
URI.parse(<URI> + request.query_string.gsub("|", "%7C")).read
end
Run Code Online (Sandbox Code Playgroud)
谢谢你的帮助.
如果您希望 Sinatra 应用程序检索 URL,则需要启动某种 HTTP 客户端:
get '/mapsproxy/staticmap' do
require 'open-uri'
open('http://maps.google.com/maps/api/staticmap').read
end
Run Code Online (Sandbox Code Playgroud)
我认为这会起作用,并且是尽可能少的。
如果您需要更多可调整性,您可以使用HTTPClient 。
另外,我认为 Rack 可以做到。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
}
Run Code Online (Sandbox Code Playgroud)
出于您的目的,这样的事情应该有效:
content_type = ''
body = open("http://www.ruby-lang.org/en") {|f|
content_type = f.content_type # "text/html"
f.read
}
Run Code Online (Sandbox Code Playgroud)
我还没有测试过,但我认为该块的返回值将被分配给body. 如果这不起作用,请尝试:
content_type = ''
body = ''
open("http://www.ruby-lang.org/en") {|f|
content_type = f.content_type # "text/html"
body = f.read
}
Run Code Online (Sandbox Code Playgroud)
但我认为第一个会起作用。