Создание одностраничного прокси с использованием Ruby Sinatra - PullRequest
7 голосов
/ 11 февраля 2011

Я пытаюсь использовать Ruby Sinatra для создания простого прокси для конкретной веб-страницы. Я могу сделать это в C #, я просто не могу решить это для Синатры, код 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;
    }
}

}

Код Ruby Sinatra, который я пробовал, выглядит следующим образом:

require 'rubygems'
require 'sinatra'

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

Я предполагаю, что Sinatra один не работает (получите 404), поскольку он только передает запрос на страницы в том же домене. Любая гепатита будет принята с благодарностью.

EDIT:

С помощью Жестяного человека я нашел хорошее, лаконичное решение, которое хорошо мне подходит:

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

Спасибо за помощь.

Ответы [ 2 ]

4 голосов
/ 11 февраля 2011

Если вы хотите, чтобы ваше приложение Sinatra получало URL-адрес, вам нужно запустить HTTP-клиент некоторого вида:

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

Я думаю, что это сработает и будет как можно меньше.get.

Вы можете использовать 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
}

Для ваших целей должно работать что-то подобное:

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
}

, но я думаю, что первое сработает.

1 голос
/ 11 февраля 2011

С помощью Дровосека и 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 заключается в том, что по какой-то причине анализ не выполняется, если они остаются, и мой браузер не кодирует их автоматически.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...