当 curl 时,HTTParty 补丁请求不起作用



在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.1rnAuthorization: Bearer MY-SENDGRID-KEYrnConnection: closernHost: api.sendgrid.comrnContent-Length: 0rnContent-Type: application/x-www-form-urlencodedrnrn"
<- ""
-> "HTTP/1.1 200 OKrn"
-> "Server: nginxrn"
-> "Date: Fri, 25 Aug 2017 18:47:15 GMTrn"
-> "Content-Type: application/jsonrn"
-> "Content-Length: 48rn"
-> "Connection: closern"
-> "Access-Control-Allow-Methods: HEAD, PATCH, OPTIONS, GETrn"
-> "Access-Control-Max-Age: 21600rn"
-> "Access-Control-Expose-Headers: Linkrn"
-> "Access-Control-Allow-Origin: *rn"
-> "Access-Control-Allow-Headers: AUTHORIZATION, Content-Type, On-behalf-of, x-sg-elas-aclrn"
-> "Content-Security-Policy: default-src https://api.sendgrid.com; frame-src 'none'; object-src 'none'rn"
-> "X-Content-Type-Options: nosniffrn"
-> "Strict-Transport-Security: max-age=31536000rn"
-> "X-Ratelimit-Remaining: 599rn"
-> "X-Ratelimit-Limit: 600rn"
-> "X-Ratelimit-Reset: 1503686880rn"
-> "Powered-By: Makorn"
-> "rn"
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 -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是如何做到这一点的呢?

显式设置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,以指出在此用例中需要:body:query

我认为查询中的.to_json导致了问题,HTTParty 对query参数采用 rubyhash,它解析该参数以创建查询字符串。.to_json会导致query参数成为字符串,因此按原样传递查询以构造 URI。从那里删除.to_json应该可以解决问题。

最新更新