Ruby. Должен ли я всегда добавлять косую черту?

Ниже приведен код Ruby, который я использую для получения HTML-контента веб-страниц. Мне не разрешено изменять этот код.

def getHtmlFromUrl(url)
    uri = URI.parse(url)
    http = Net::HTTP.new(uri.host, uri.port)
    http.read_timeout = 2
    html = http.get(uri.to_s)
    # ...
    # Handle any error that may have occurred (return nil)
    # ...
    return html.body
end

Этот код, похоже, имеет проблемы с чтением определенных URL-адресов, которые не имеют косой черты в конце. Например, ошибка возникает, когда я пытаюсь прочитать http://drive.google.com, но не http://drive.google.com/. Почему это так? Я решил реализовать исправление, добавляя косую черту в конце домена, если путь не указан. Это безопасное решение? Возможно ли, что в случае http://somedomain.com/ возникает ошибка, а в случае http://somedomain.com работает корректно?


person Kvass    schedule 08.12.2013    source источник
comment
Если вам не разрешено изменять этот код, вы можете сказать тому, кто МОЖЕТ изменить его, что нам не нужен return html.body в Ruby. Идиоматично просто говорить html.body в конце метода и использовать в именах методов змеиный регистр, а не camelCase.   -  person the Tin Man    schedule 08.12.2013
comment
Программист изначально написал его на Perl, а затем несколько поспешно перевел на Ruby, так что это может объяснить некоторые идиоматические несоответствия.   -  person Kvass    schedule 08.12.2013


Ответы (2)


У вас не должно возникнуть проблем с использованием косой черты в конце, но другой вариант — следовать перенаправлениям (вероятно, drive.google.com перенаправляет вас на drive.google.com/ ).

См. этот ответ (и комментарии) для получения дополнительной информации о том, как работать с перенаправлениями с использованием Net:HTTP: https://stackoverflow.com/a/6934503/1691

person olore    schedule 08.12.2013

Похоже, проблема в том, что вы не обрабатываете перенаправления. Документация Net::HTTP содержит информацию по их обработке. Это довольно простой процесс:

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

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

Например, все ответы 2XX являются экземплярами подкласса Net::HTTPSuccess, ответ 3XX — экземпляром подкласса Net::HTTPRedirection, а ответ 200 — экземпляром класса Net::HTTPOK. Дополнительные сведения о классах ответов см. в разделе «Классы ответов HTTP» ниже.

Используя оператор case, вы можете правильно обрабатывать различные типы ответов:

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')

Тем не менее, существует ряд HTTP-клиентов для Ruby, которые помогают вам справиться с этой ситуацией, потому что она настолько распространена, что вы можете сосредоточиться на более важных вещах, таких как обработка отсутствующих страниц, тайм-ауты, параллельная обработка нескольких потоков/обработка нескольких запросов, декодирование JSON. /XML/YAML. Я бы порекомендовал изучить их (в произвольном порядке) и посмотреть, что они могут предложить:

  • Тифей: Typhoeus.get("www.example.com", followlocation: true)
  • HTTPClient: puts clnt.get('http://dev.ctor.org/', :follow_redirect => true)
  • #P7#
    follow_location = boolean → boolean
    
    <цитата> #P8#
  • #P9# <блочная цитата> #P10# #P11#
    class Foo
      include HTTParty
      base_uri 'http://google.com'
      follow_redirects true
    end
    
person the Tin Man    schedule 08.12.2013