Creating a Single Page Proxy Using Ruby Sinatra

I am trying to use Ruby Sinatra to create a simple proxy for a specific web page. I can do this in C #, I just can't figure out Sinatra, the C # code is below:

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

The Ruby Sinatra code I tried looks like this:

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

I assume that Sinatra does not work (get 404), since there is only a request transfer to pages in the same domain. Any hep would be appreciated.

EDIT:

Using the Tin Man help, I came up with a beautiful, concise solution that works well for me:

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

Thanks for the help.

+7
source share
2 answers

If you want your Sinatra application to retrieve a URL, you need to run some kind of HTTP client:

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

I think this will work and is about as minimal as you can get.

You can use HTTPClient if you need more convenient setup.

Also, I think Rack can do this. Sinatra is built on top of the rack, but since then I have played at this level.

I still need to find a way to extract ContentType from the response

From the 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 } 

For your purposes, something like this should work:

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

I have not tested this, but I think the return value of the block will be assigned to body . If this does not work, try:

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

but I think the first will work.

+4
source

Using Tin Man and TK-421, I developed a solution, see the Sinatra route below:

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

Just replace <URI> with the desired page, and you will be fine.

After I played, this is what I came up with:

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

As already mentioned, where you need require 'open-uri' at the top of the code. The reason for gsub is that for some reason the parsing fails if it is left, and my browser does not automatically encode them.

+1
source

All Articles