отредактировано, оригинальный ответ внизу
Я не думаю, что вы бездействуете в первом фрагменте кода от вашего pastie. Попробуйте следующее, чтобы понять, что я имею в виду:
h = Net::HTTP.new uri.host,uri.port
h.set_debug_output $stderr
h.start do |http|
http.request_get(uri.path) do |response|
end
end
То, что происходит, заключается в том, что при выдаче GET
ваш клиент обязан прочитать весь документ из сокета, независимо от того, действительно ли вы что-то делаете с ним. Это только часть спецификации HTTP.
Если вы не вызываете response.read_body, вы запрещаете вашему коду считывать ответ в память , но блок не вернется, пока все данные не будут считаны из сокета. Ваш блок с вызовом break
выходит из строя перед финальным read
, который призван сделать ваш код HTTP-совместимым, даже если вы решите не читать ответ в память. Я отредактировал вашу пасту , чтобы указать, где происходит окончательное чтение.
Вы просто читаете массивный файл ISO, так что похоже, что вы простаиваете.
Краткий ответ заключается в том, что вы должны выполнить запрос HEAD
, если вы не собираетесь читать весь документ, как указано в спецификации HTTP.
Сложный ответ заключается в том, что вы можете выдать частичный GET
, если вы введете диапазон байтов, как указано здесь , но я не уверен, что клиентская библиотека ruby http является поддерживает этот режим работы.
Вызывая http.finish
, вы рано закрываете сокет tcp, который выполняет работу настолько, насколько вырывает вас из блока кода, но вызывает исключение при вызове кода, потому что вы "не должны" делать это , Вы можете позвонить по номеру finish
, если хотите перехватить исключение, но не очень хорошо играете с HTTP.
оригинальный ответ
Вы не должны звонить finish
,
соединение будет закрыто, когда
блок выходов. Документация здесь .
Исключение выдается из
этот код
Если вы действительно хотите заставить сокет
чтобы закрыть рано, просто поймать
IOError.
Я только что заметил, что ты
инициализация response
для
результат звонка
head
, но тогда ты
используя его снова в качестве параметра блока.
Просто проверьте тип контента до
Вы звоните request_get
,
при условии
content_type
.