【问题标题】:Get response headers from Curb从 Curb 获取响应标头
【发布时间】:2013-01-15 19:58:31
【问题描述】:

我打算从 Ruby on Rails 应用程序进行调用:

c = Curl::Easy.http_post("https://example.com", json_string_goes_here) do |curl|
  curl.headers['Accept'] = 'application/json'
  curl.headers['Content-Type'] = 'application/json'
  curl.headers['Api-Version'] = '2.2'
end

响应应该有自定义标题:

X-Custom1 : "some value"
X-Custom2 : "another value"

如何遍历响应标头以将值与我期望的值进行比较?

【问题讨论】:

    标签: ruby curb


    【解决方案1】:

    使用 Curl::Easy 的 header_str,您可以将返回的标头作为字符串访问。来自文档:

    返回上一个调用的响应头来执行。这由默认的 on_header 处理程序填充 - 如果您提供自己的标头处理程序,则此字符串将为空。

    为了测试这一点,我使用以下方法打开了内置 Gem 服务器:

    gem server
    

    这里有一些代码来测试这个:

    curl = Curl::Easy.http_get('http://0.0.0.0:8808')
    curl.header_str
    => "HTTP/1.1 200 OK \r\nDate: 2013-01-10 09:07:42 -0700\r\nContent-Type: text/html\r\nServer: WEBrick/1.3.1 (Ruby/1.9.3/2012-11-10)\r\nContent-Length: 62164\r\nConnection: Keep-Alive\r\n\r\n"
    

    捕获响应,并将剩余的字符串分解为哈希,使其更易于使用,很简单:

    http_response, *http_headers = curl.header_str.split(/[\r\n]+/).map(&:strip)
    http_headers = Hash[http_headers.flat_map{ |s| s.scan(/^(\S+): (.+)/) }]
    
    http_response # => "HTTP/1.1 200 OK"
    
    http_headers 
    => {
                      "Date" => "2013-01-10 09:07:42 -0700",
              "Content-Type" => "text/html",
                    "Server" => "WEBrick/1.3.1 (Ruby/1.9.3/2012-11-10)",
            "Content-Length" => "62164",
                "Connection" => "Keep-Alive"
        }
    

    再次测试,在 Pry 中:

    [27] (pry) main: 0> curl = Curl::Easy.http_get('http://www.example.com')
    #<Curl::Easy http://www.example.com>
    [28] (pry) main: 0> curl.header_str
    "HTTP/1.0 302 Found\r\nLocation: http://www.iana.org/domains/example/\r\nServer: BigIP\r\nConnection: Keep-Alive\r\nContent-Length: 0\r\n\r\n"
    [29] (pry) main: 0> http_response, *http_headers = curl.header_str.split(/[\r\n]+/).map(&:strip)
    [
        [0] "HTTP/1.0 302 Found",
        [1] "Location: http://www.iana.org/domains/example/",
        [2] "Server: BigIP",
        [3] "Connection: Keep-Alive",
        [4] "Content-Length: 0"
    ]
    [30] (pry) main: 0> http_headers = Hash[http_headers.flat_map{ |s| s.scan(/^(\S+): (.+)/) }]
    {
              "Location" => "http://www.iana.org/domains/example/",
                "Server" => "BigIP",
            "Connection" => "Keep-Alive",
        "Content-Length" => "0"
    }
    

    【讨论】:

    • 这是一个很好的答案,你值得被接受。顺便说一句,不为您解析标题,给您带来了多么糟糕的用户体验限制。
    • 我不明白你的评论。你同意他的观点,并认为我的回答应该被删除和替换?他说这是一个很好的答案。至于跟随重定向,多年来我们不得不在低得多的水平上做这件事,所以,在弄清楚如何解开返回的数据之后,这没什么大不了的。对于从未见过这种级别的 HTTP 通信的人来说,这可能会让人感到困惑或畏惧,但这只是编程的一部分。
    • @theTinMan - 我认为他是说如果这是路边的一部分会很好,这样到达这里的每个人都不会一遍又一遍地编写相同的代码......你的回答很好;)
    猜你喜欢
    • 2015-08-31
    • 2019-04-04
    • 2017-11-06
    • 2017-07-28
    • 2019-03-04
    • 2011-06-21
    • 1970-01-01
    • 2013-05-28
    • 2016-07-25
    相关资源
    最近更新 更多