我可能会错过这里显而易见的,但是这段代码失败了,除非我在return
案例中递归调用它时使用Net::HTTPRedirection
子句。
def fetch_headers(limit = REDIRECT_LIMIT)
# You should choose a better exception.
raise ArgumentError, 'too many HTTP redirects' if limit == 0
http = Net::HTTP.new(@uri.host, @uri.port)
http.use_ssl = true if @uri.scheme == 'https'
request_uri = @uri.request_uri.nil? ? '/' : @uri.request_uri
http.request_head(request_uri) do |response|
case response
when Net::HTTPSuccess then
return response
when Net::HTTPRedirection then
location = response['location']
parsed_location = URI.parse location
@uri = parsed_location.absolute? ? parsed_location : @uri.merge(parsed_location)
fetch_headers(limit - 1)
else
return response.value
end
end
end
来电者方法:
def perform(link_id)
link = Link.find(link_id)
url = link.url =~ /^http/ ? link.url : "http://#{link.url}"
@uri = URI.parse url
headers = fetch_headers
case headers.content_type
when /application/
filename = File.basename(@uri.path)
link.update title: filename
when /html/
response = fetch_page
page = Nokogiri::HTML(response)
link.update title: page_title(page), description: page_description(page)
else
logger.warn "URL #{url} with unknow mime-type: #{headers.content_type}"
end
end
这是我正在运行的规范:
it 'follows the redirects using relative URL' do
link = create(:link, url: url)
path = '/welcome.html'
stub_request(:head, url).to_return(status: 302, body: '',
headers: { 'Location' => path })
redirect_url = "#{url}#{path}"
stub_request(:head, redirect_url).to_return(status: 200, body: '',
headers: html_header)
stub_request(:get, redirect_url).to_return(status: 200, body: title_html_raw,
headers: html_header)
UrlScrapperJob.perform_now link.id
link.reload
expect(link.title).to match(/page title/)
end
以下是fetch_headers
方法的结果:
使用return子句:#<Net::HTTPOK 200 readbody=true>
没有return子句:#<Net::HTTPFound 302 readbody=true>
我期望的结果是HTTPOK 200
,因为它应该遵循重定向,直到200 OK。
答案 0 :(得分:2)
差异是从return
函数返回的值。
return
作为函数调用的结果返回它的参数。
如果没有显式http.request_head(request_uri, &block)
,返回值就是http.request_head(request_uri) do |response|
case response
when Net::HTTPSuccess then
response
when Net::HTTPRedirection then
location = response['location']
parsed_location = URI.parse location
@uri = parsed_location.absolute? ? parsed_location : @uri.merge(parsed_location)
fetch_headers(limit - 1)
else
response.value
end
end.tap { |result| puts result } # ⇐ here
返回的值,这显然会导致无限递归。
您可能想尝试
return
在没有明确{{1}}的情况下检查实际结果是什么。