2016-12-23 4 views
7

Я использую Net :: HTTP с Ruby для обхода URL.Ruby NET :: HTTP Прочитайте заголовок ПЕРЕД телом (без запроса HEAD)?

Я не хочу ползать потоковое аудио, такие как: http://listen2.openstream.co/334

на самом деле я только хочу, чтобы сканировать содержимое HTML, так что никаких PDF, видео, TXT ..

Прямо сейчас, у меня есть и open_timeout и read_timeout установлены на 10, поэтому, даже если я сканирую эти потоковые аудио-страницы, они будут таймаутом.

url = 'http://listen2.openstream.co/334' 
path = uri.path 

req= Net::HTTP::Get.new(path, {'Accept' => '*/*', 'Content-Type' => 'text/plain; charset=utf-8', 'Connection' => 'keep-alive','Accept-Encoding' => 'Identity'}) 

uri = Addressable::URI.parse(url) 

resp = Net::HTTP.start(uri.host, uri.inferred_port) do |httpRequest| 
    httpRequest.open_timeout = 10 
    httpRequest.read_timeout = 10 
    #how can I read the headers here before it's streaming the body and then exit b/c the content type is audio? 
    httpRequest.request(req) 
end 

Однако, есть способ, чтобы проверить заголовок, прежде чем я прочитал тело ответа HTTP, чтобы увидеть, если это аудио? Я хочу сделать это, не отправляя отдельный запрос HEAD.

+1

Могу ли я спросить, что не так с запросом 'HEAD', который был изобретен для решения этой точной проблемы? – mudasobwa

+0

Вы также можете попробовать настроить заголовок «Принять» на «текст/html». Хорошо организованные серверы должны быстро возвращать HTTP 406-ответ, если контент в URL-адресе не представлен в HTML. –

ответ

4

net/http поддерживает потоковое вещание, вы можете использовать его для чтения заголовка перед телом.

Пример кода,

url = URI('http://stackoverflow.com/questions/41306082/ruby-nethttp-read-the-header-before-the-body-without-head-request') 

Net::HTTP.start(url.host, url.port) do |http| 
    request = Net::HTTP::Get.new(url) 
    http.request(request) do |response| 

    # check headers here, body has not yet been read 
    # then call read_body or just body to read the body 

    if true 
     response.read_body do |chunk| 
     # process body chunks here 
     end 
    end 
    end 
end 
0

Поскольку я не нашел способ правильно сделать это в Net :: HTTP, и я увидел, что вы используете addressable драгоценный камень, как уже внешнюю зависимость, вот решение, используя замечательный http gem:

require 'http' 

response = HTTP.get('http://listen2.openstream.co/334') 
# Here are the headers 
puts response.headers 

# Everything ok? Start streaming the response 
body = response.body 
body.stream! 

# now just call `readpartial` on the body until it returns `nil` 
# or some other break condition is met 

Извините, если вам требуется использовать Net :: HTTP, надеюсь, кто-то найдет ответ. Отдельный запрос HEAD действительно может быть в этом случае.

0

Вы можете сделать целый ряд связанных чистых вещей без использования драгоценных камней. Просто используйте модуль net/http.

require 'net/http' 

url = URI 'http://listen2.openstream.co/334' 

Net::HTTP.start(url.host, url.port){|conn| 
    conn.request_get(url){|resp| 
    resp.each{|k_header, v_header| 
     # process headers 
     puts "#{k_header}: #{v_header}" 
    } 
    # 
    # resp.read_body{|body_chunk| 
    # # process body 
    # } 
    } 
} 

Примечание: при обработке заголовков, просто убедитесь, чтобы проверить заголовок content-type. Для аудиосодержимого контента он обычно будет содержать значение audio/mpeg.

Надеюсь, это помогло.

0

Я добавлю пример рубина позже сегодня вечером. Однако для быстрого ответа. Для этого есть простой трюк.

Вы можете использовать заголовок HTTP Range, чтобы указать, какой диапазон байтов вы хотите получать с сервера. Ниже приведен пример -

curl -XGET http://www.sample-videos.com/audio/mp3/crowd-cheering.mp3 -v -H "Range: bytes=0-1"

В приведенном выше примере. Сервер вернет данные из диапазона от 0 до 1 байта.

FYI: https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests

Надежда, которая работает для вас.

Thanks