【问题标题】:HTTParty patch request doesn't work when curl does当 curl 执行时,HTTParty 补丁请求不起作用
【发布时间】:2017-08-25 19:12:05
【问题描述】:

在 Rails 4.2 中,我使用HTTParty 为 SendGrid 的 API 版本 3 制作 API 包装器。这是它的样子:

class SendGridV3
  include HTTParty
  debug_output $stdout

  base_uri 'https://api.sendgrid.com/v3'
  format :json

  headers 'Authorization' => "Bearer #{ENV['SENDGRID_API_KEY']}"

  def self.enforce_tls
    response = patch '/user/settings/enforced_tls', query: {require_tls: true}.to_json
    puts response
    response['require_tls']
  end
end

当我运行SendGridV3.enforce_tls 时,预期的响应是{"require_tls": true, "require_valid_cert": false},但实际的响应是{"require_tls": false, "require_valid_cert": false}

这是debug_output的输出

opening connection to api.sendgrid.com:443...
opened
starting SSL for api.sendgrid.com:443...
SSL established
<- "PATCH /v3/user/settings/enforced_tls?{%22require_tls%22:true} HTTP/1.1\r\nAuthorization: Bearer MY-SENDGRID-KEY\r\nConnection: close\r\nHost: api.sendgrid.com\r\nContent-Length: 0\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\n"
<- ""
-> "HTTP/1.1 200 OK\r\n"
-> "Server: nginx\r\n"
-> "Date: Fri, 25 Aug 2017 18:47:15 GMT\r\n"
-> "Content-Type: application/json\r\n"
-> "Content-Length: 48\r\n"
-> "Connection: close\r\n"
-> "Access-Control-Allow-Methods: HEAD, PATCH, OPTIONS, GET\r\n"
-> "Access-Control-Max-Age: 21600\r\n"
-> "Access-Control-Expose-Headers: Link\r\n"
-> "Access-Control-Allow-Origin: *\r\n"
-> "Access-Control-Allow-Headers: AUTHORIZATION, Content-Type, On-behalf-of, x-sg-elas-acl\r\n"
-> "Content-Security-Policy: default-src https://api.sendgrid.com; frame-src 'none'; object-src 'none'\r\n"
-> "X-Content-Type-Options: nosniff\r\n"
-> "Strict-Transport-Security: max-age=31536000\r\n"
-> "X-Ratelimit-Remaining: 599\r\n"
-> "X-Ratelimit-Limit: 600\r\n"
-> "X-Ratelimit-Reset: 1503686880\r\n"
-> "Powered-By: Mako\r\n"
-> "\r\n"
reading 48 bytes...
-> "{\"require_tls\":false,\"require_valid_cert\":false}"
read 48 bytes
Conn close
{"require_tls"=>false, "require_valid_cert"=>false}
=> false

我也尝试使用 body: 而不是 query: 来传递 JSON

当我使用这个 curl 时,我得到了预期的响应:

curl -X "PATCH" "https://api.sendgrid.com/v3/user/settings/enforced_tls" -H "Authorization: Bearer MY-SENDGRID-KEY" -H "Content-Type: application/json" -d '{"require_tls":true}'

那么当 HTTParty 失败时 curl 是如何使这项工作发挥作用的呢?

【问题讨论】:

  • 会是内容类型吗?在您的调试中它说:"PATCH /v3/user/settings/enforced_tls?{%22require_tls%22:true} HTTP/1.1\r\nAuthorization: Bearer MY-SENDGRID-KEY\r\nConnection: close\r\nHost: api.sendgrid.com\r\nContent-Length: 0\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\n" 这可能是您需要将其显式设置为“application/json”,因为它现在看起来像是x-www-form-urlencoded
  • 很好地发现了@JamesMilani,你是对的。我设置了内容类型并将query:更改为body:,它可以工作。
  • 嘿托比。我要把它变成一个答案。我在我自己的应用程序中完全以这种方式实现HTTParty。干杯!

标签: ruby-on-rails rest httparty


【解决方案1】:

显式设置Content-Type 以及使用:body 将使其工作。

class SendGridV3
  ...
  headers 'Content-Type' => 'application/json'
  def self.enforce_tls
    response = patch '/user/settings/enforced_tls', body: {require_tls: true}.to_json
    puts response
    response['require_tls']
  end
end

感谢 OP 注意到在此用例中 :query 需要为 :body

【讨论】:

    【解决方案2】:

    我认为查询中的 .to_json 导致了问题,HTTParty 将 ruby​​ hashquery 参数相结合,它解析该参数以创建查询字符串。 .to_json 导致query 参数变为字符串,因此查询按原样传递以构造URI。从那里删除 .to_json 应该可以解决问题。

    【讨论】:

      猜你喜欢
      • 2013-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-20
      • 2013-11-16
      • 1970-01-01
      相关资源
      最近更新 更多