2013-11-01 5 views
2

Подобно «getting the status code of a HTTP redirected page», но с NET :: HTTP вместо бордюра творю запрос GET на страницу, которая будет перенаправлять:Как получить код перенаправленного статуса с помощью NET: HTTP?

response = Net::HTTP.get_response(URI.parse("http://www.wikipedia.org/wiki/URL_redirection")) 
puts response.code #{ 
puts response['location'] 

=> 301 
en.wikipedia.org/wiki/URL_redirection 

Проблема заключается в том, что я хочу знать код статуса перенаправленная страница. В этом случае это 200, но в моем приложении я хочу проверить, 200 или что-то еще. Решение, которое я видел, - это просто позвонить get_response(response['location']), но это не будет работать в моем приложении, потому что способ, которым перенаправляется, делает его так, что перенаправление может выполняться только один раз. Поскольку первый GET использует одно перенаправление, я не могу повторить его снова.

Есть ли способ получить последний код состояния, являющийся результатом GET?


EDIT: Дальнейшее уточнение ситуации:

Приложение, которое я посылаю GET, чтобы есть единый вход механизм аутентификации, где, если я хочу получить доступ к «MYAPP/MYPAGE», I должны сначала отправить сообщение:

postResponse = Net::HTTP.post_form(URI.parse("http://myapp.com/trusted"), {"username" => @username}) 

Затем сделать запрос GET для:

'http://myapp.com/trusted/#{postResponse.body}/mypage 

* postResponse.body - это билет, который можно выкупить один раз.

что GET проверяет, что билет действителен, а затем перенаправляет:

myapp.com/mypage 

Так ли, что билет действителен или нет, я получаю 301.

Я хочу, чтобы проверить код состояния окончательный переход на myapp.com/mypage.

Если я вручную попытаюсь выполнить перенаправление, будь то запрос HEAD или GET, первоначальный переадресация уже расходует билет, поэтому я получаю сообщение об ошибке, в которой истекает срок действия билета, даже если первоначальное перенаправление было 200.

+0

Можете ли вы просто сделать запрос «HTTP HEAD» перенаправленному местоположение, чтобы проверить его статус без «потребления» URL-адреса? Если это так, 'Net :: HTTP' поддерживает это, и я могу дать вам несколько указателей. – struthersneil

ответ

0

Если это достаточно просто сделать HTTP HEAD запрос без «потребляя» ваш URL (это будет обычное ожидание запроса на голове), вы можете сделать это следующим образом:

2.0.0-p195 :143 > result = Net::HTTP.start('www.google.com') { |http| http.head '/' } 
=> #<Net::HTTPFound 302 Found readbody=true> 

Таким образом, в в вашем примере вы сделаете так:

... 
result = Net::HTTP.start(response.uri.host) { |http| http.head response.uri.path } 

Если вы хотите сохранить историю кодов ответа, вы можете попробовать это. Это сохраняет последние 5 кодов ответа от вызовов до get_response и предоставляет их через метод Net::HTTP.history.

module Net 
    class << HTTP 
    alias_method :_get_response, :get_response 

    def get_response *args, &block 
     resp = _get_response *args, &block 
     @history = (@history || []).push(resp.code).last 5 
     resp 
    end 

    def history 
     @history || [] 
    end 
    end 
end 

(я не совсем получить сценарий использования, так адаптироваться к вашим потребностям)

+0

Это для первоначального получения, а затем я последую за результатом. ['Location'] или это второй get, после перенаправления? –

+0

Подход HEAD будет для второго запроса. Подход, в котором записывается история кодов ответа, будет записывать оба - 'Net :: HTTP.history.last' будет вашим последним кодом ответа. – struthersneil

+0

Я, вероятно, должен был немного уточнить прецедент. Комментируя мой оригинальный пост с большей детализацией. –

1

Net::HTTP documentation имеет пример кода, показывающий, как иметь дело с переадресаций. Ты это пробовал? Это должно облегчить доступ к механизму перенаправления и присвоению статуса позже.

Вот их пример:

После Перенаправление

Каждая Net :: HTTPResponse объект относится к классу для его кода ответа.

Например, все ответы 2XX являются экземплярами подкласса Net :: HTTPSuccess, ответ 3XX является экземпляром подкласса Net :: HTTPRedirection, а ответ 200 - это экземпляр класса Net :: HTTPOK. Подробнее о классах ответов см. В разделе «HTTP Response Classes» ниже.

Использование оператора выбора, вы можете обрабатывать различные типы реакций правильно:

def fetch(uri_str, limit = 10) 
    # You should choose a better exception. 
    raise ArgumentError, 'too many HTTP redirects' if limit == 0 

    response = Net::HTTP.get_response(URI(uri_str)) 

    case response 
    when Net::HTTPSuccess then 
    response 
    when Net::HTTPRedirection then 
    location = response['location'] 
    warn "redirected to #{location}" 
    fetch(location, limit - 1) 
    else 
    response.value 
    end 
end 

print fetch('http://www.ruby-lang.org') 

Небольшие изменения, как это должно помочь:

require 'net/http' 

RESPONSES = [] 
def fetch(uri_str, limit = 10) 
    # You should choose a better exception. 
    raise ArgumentError, 'too many HTTP redirects' if limit == 0 

    response = Net::HTTP.get_response(URI(uri_str)) 

    RESPONSES << response 

    case response 
    when Net::HTTPSuccess then 
    response 
    when Net::HTTPRedirection then 
    location = response['location'] 
    warn "redirected to #{location}" 
    fetch(location, limit - 1) 
    else 
    response.value 
    end 
end 

print fetch('http://jigsaw.w3.org/HTTP/300/302.html') 
puts RESPONSES.join("\n") # => 

Я вижу это, когда я запускаю его:

redirected to http://jigsaw.w3.org/HTTP/300/Overview.html 
#<Net::HTTPOK:0x007f9e82a1e050>#<Net::HTTPFound:0x007f9e82a2daa0> 
#<Net::HTTPOK:0x007f9e82a1e050> 
Смежные вопросы