【问题标题】:Making HEAD request in Ruby在 Ruby 中发出 HEAD 请求
【发布时间】:2013-04-25 21:49:50
【问题描述】:

我是 ruby​​ 的新手,并且有 python 背景 我想向 URL 发出头部请求并检查一些信息,例如文件是否存在于服务器上以及时间戳、etag 等,我无法在 RUBY 中完成此操作。

在 Python 中:

import httplib2
print httplib2.Http().request('url.com/file.xml','HEAD')

在 Ruby 中:我尝试了这个并抛出了一些错误

require 'net/http'

Net::HTTP.start('url.com'){|http|
   response = http.head('/file.xml')
}
puts response


SocketError: getaddrinfo: nodename nor servname provided, or not known
    from /Users/comcast/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/net/http.rb:877:in `initialize'
    from /Users/comcast/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/net/http.rb:877:in `open'
    from /Users/comcast/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/net/http.rb:877:in `block in connect'
    from /Users/comcast/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/timeout.rb:51:in `timeout'
    from /Users/comcast/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/net/http.rb:876:in `connect'
    from /Users/comcast/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/net/http.rb:861:in `do_start'
    from /Users/comcast/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/net/http.rb:850:in `start'
    from /Users/comcast/.rvm/rubies/ruby-2.0.0-p0/lib/ruby/2.0.0/net/http.rb:582:in `start'
    from (irb):2
    from /Users/comcast/.rvm/rubies/ruby-2.0.0-p0/bin/irb:16:in `<main>'

【问题讨论】:

    标签: ruby net-http


    【解决方案1】:

    我认为将字符串传递给 :start 是不够的; in the docs 看起来它需要一个 URI 对象的主机和端口才能获得正确的地址:

    uri = URI('http://example.com/some_path?query=string')
    
    Net::HTTP.start(uri.host, uri.port) do |http|
      request = Net::HTTP::Get.new uri
    
      response = http.request request # Net::HTTPResponse object
    end
    

    你可以试试这个:

    require 'net/http'
    
    url = URI('yoururl.com')
    
    Net::HTTP.start(url.host, url.port){|http|
       response = http.head('/file.xml')
       puts response
    }
    

    我注意到一件事 - 你的 puts response 需要在区块内!否则,变量response 不在作用域内。

    编辑:您还可以将响应视为哈希以获取标头的值:

    response.each_value { |value| puts value }
    

    【讨论】:

    • 谢谢。 priti,我正在尝试的网址是内部的,您无法访问它。但一般来说,它是一个下载 xml 文件的 url。在我知道它之前我不想下载它,比如它是否陈旧、重复等,所以头部请求不会下载它而是获取属性
    • 我尝试了你的第二种方法,但我只得到了这个值“#<:httpok:0x13f4cf6f>”,我期待关于文件的大量标题信息和属性跨度>
    • 我期待这样的信息 ({'status': '200', 'content-length': '2983', 'accept-ranges': 'bytes', 'server': 'Apache /2.2.17 (Unix)', 'last-modified': '星期三, 2013 年 5 月 1 日 20:53:26 GMT', 'etag': '"5f56a-ba7-4dbae4f35555"', 'date': '星期三, 2013 年 5 月 1 日 21:11:30 GMT', 'content-type': 'application/xml'}, '')
    • 是的。如果您查看at the documentation,您会看到 :head 方法返回一个包含响应状态代码的 HTTPResponse 对象(此处为 200 OK)。您可以以哈希格式打印标题,例如puts response['content-type']
    • 但是当我做 response.body 它有文件的实际内容。我不想下载内容。因为我在服务器上有 100 多个文件,而且它们真的很大,比如 800 MB。所以它会占用我的系统内存并减慢调用速度。所以我只需要做 HEAD 请求并单独获取文件的属性
    【解决方案2】:

    我意识到这个问题已经得到解答,但我也不得不经历一些困难。下面是更具体的开始:

    #!/usr/bin/env ruby
    
    require 'net/http'
    require 'net/https' # for openssl
    
    uri = URI('http://stackoverflow.com')
    path = '/questions/16325918/making-head-request-in-ruby'
    
    response=nil
    http = Net::HTTP.new(uri.host, uri.port)
    # http.use_ssl = true                            # if using SSL
    # http.verify_mode = OpenSSL::SSL::VERIFY_NONE   # for example, when using self-signed certs
    
    response = http.head(path)
    response.each { |key, value| puts key.ljust(40) + " : " + value }
    

    【讨论】:

      【解决方案3】:
      headers = nil
      
      url = URI('http://my-bucket.amazonaws.com/filename.mp4')
      
      Net::HTTP.start(url.host, url.port) do |http|
        headers = http.head(url.path).to_hash
      end
      

      现在您在headers 中有一个标头哈希

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-10-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-24
        • 2018-05-20
        相关资源
        最近更新 更多