使用Ruby Sinatra创建单页代理
我试图使用Ruby Sinatra为特定网页创建一个简单的代理。我可以用C#来做,但我似乎无法为Sinatra解决这个问题,C#代码如下:使用Ruby Sinatra创建单页代理,ruby,proxy,sinatra,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(Str
<%@ 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;
}
}
}
我假设Sinatra one不工作(获取404),因为它只是将请求传递给同一域中的页面。任何hep都将不胜感激
编辑:
在铁皮人的帮助下,我想出了一个简洁的解决方案,对我来说效果很好:
get '/proxy/path' do
URI.parse(<URI> + request.query_string.gsub("|", "%7C")).read
end
get'/proxy/path'do
parse(+request.query_string.gsub(“|“,“%7C”)).read
结束
谢谢您的帮助。如果您想让Sinatra应用程序检索URL,您需要启动某种HTTP客户端:
get '/mapsproxy/staticmap' do
require 'open-uri'
open('http://maps.google.com/maps/api/staticmap').read
end
我认为这会起作用,并且是尽可能少的
如果需要更多的可调整性,可以使用
而且,我认为这个架子可以做到。西纳特拉是建在架子上的,但我已经有一段时间没有达到那个水平了
我仍然需要找到一种从响应中提取contentType的方法
从文档中:
我还没有对此进行测试,但我认为块的返回值将分配给body
。如果不起作用,请尝试:
content_type = ''
body = ''
open("http://www.ruby-lang.org/en") {|f|
content_type = f.content_type # "text/html"
body = f.read
}
但我认为第一种方法会奏效。在锡人和TK-421的帮助下,我已经找到了一个解决方案,请参见下面的Sinatra路线:
get '/proxy/path' do
require 'open-uri'
uri = URI.parse(<URI>)
getresult = uri.read
halt 200, {'Content-Type' => getresult.content_type}, getresult
end
get'/proxy/path'do
需要“打开uri”
uri=uri.parse()
getresult=uri.read
halt 200,{'Content-Type'=>getresult.Content\u-Type},getresult
结束
只需将
替换为您需要的页面,就可以了
再玩一段时间后,我就想到了:
get '/proxy/path' do
URI.parse(<URI> + request.query_string.gsub("|", "%7C")).read
end
get'/proxy/path'do
parse(+request.query_string.gsub(“|“,“%7C”)).read
结束
正如前面提到的,您需要
在代码顶部要求“openuri”
。使用gsub
的原因是,由于某些原因,如果保留它们,解析将失败,并且我的浏览器不会自动对它们进行编码。您需要添加一些异常处理,并且可能希望使用超时
模块在请求花费太长时间时提供更好的控制。请参阅示例。它似乎可以处理基于文本的响应,尽管它确实重新格式化了响应,但不会重新格式化图像响应。我认为我需要以某种方式将响应流式传输到Sinatra响应…不应该有任何重新格式化,因为开放URI在不进行任何转换的情况下流式传输数据;它基本上是一个文件I/O,与文本/二进制无关。除了使用OpenURI检索大量文本外,我还将MP3、PDF和图像检索到磁盘。西纳特拉可能在做些什么。有关流媒体示例,请参阅我最后的评论。没问题。我还在编辑。对于你的问题+1,因为它提醒了我Sinatra有多酷。我已经有一段时间没玩了,我错过了它。也可以看看西纳特拉的老大哥,他坐在西纳特拉和Rails之间。干杯。它真的很酷,我才刚刚开始使用它,我对它的威力感到惊讶。我来看看帕德里诺。在将新请求响应导入Sinatra one时仍然存在问题。但我比一小时前进步了很多,谢谢你的帮助。铁皮人给出了正确的答案。很高兴看到它在工作。那么,你更喜欢Ruby而不是C吗实际上,您可以使用return getresult
来代替halt 200,{'Content-Type'=>getresult.Content\u-Type},getresult
,因为uri会返回完整的响应,据我所知。我从来都不喜欢C#,只在工作中使用它,我更喜欢用解释语言来编写自己的代码(lisp、Scheme、Clojure、JavaScript)。我对Ruby很陌生,但我很喜欢:)不要在块中要求。。。这简直是浪费。并不是说它每次都会加载lib,而是它会检查它是否已经加载了它。”实际上,您可以使用return getresult来代替halt 200,{'Content-Type'=>getresult.Content\u Type},getresult作为uri返回一个完整的响应“您不需要使用return
。这在Ruby中是隐含的,它返回退出块之前看到的最后一个值。您也不需要解析URIopen
对字符串URL很满意,因此您正在做一些不需要的工作,实际上会妨碍您提取所需的内容类型
信息。
content_type = ''
body = ''
open("http://www.ruby-lang.org/en") {|f|
content_type = f.content_type # "text/html"
body = f.read
}
get '/proxy/path' do
require 'open-uri'
uri = URI.parse(<URI>)
getresult = uri.read
halt 200, {'Content-Type' => getresult.content_type}, getresult
end
get '/proxy/path' do
URI.parse(<URI> + request.query_string.gsub("|", "%7C")).read
end