【问题标题】:How do you set a Content-Type Header for the Ruby AWS SDK?如何为 Ruby AWS 开发工具包设置 Content-Type 标头?
【发布时间】:2019-07-01 21:28:45
【问题描述】:

我正在使用 Webmock 测试由 ruby​​ aws-sdk(在本例中为 aws-sdk-batch)发出的 http 请求。

Webmock 在请求失败时使用更方便的 hash diff 和 partial matching 处理 json 请求,但只有当存根请求的 Content-Typeapplication/json 时才会这样做。

但是,aws-sdk-batch gem 创建了一个带有空 Content-type (despite having documented the content type as application/json) 的请求,并且似乎依赖端点的默认行为将其解释为 application/json

我想手动添加标头Content-type: application/json,以便我可以从Webmock 更好地处理json 请求正文中受益。这可能吗?


未指定 Content-Type:application/json 的示例 Webmock 响应:

     WebMock::NetConnectNotAllowedError:
       Real HTTP connections are disabled. Unregistered request: POST https://batch.us-east-1.amazonaws.com/v1/submitjob with body '{"jobName":"Fakie","jobQueue":"queue","jobDefinition":"def","parameters":{"task":"{\"fake\":\"town\"}"}}' with headers {'Accept'=>'*/*', 'Accept-Encoding'=>'', 'Authorization'=>'AWS4-HMAC-SHA256 Credential=ACCESS_KEY_ID/20190701/us-east-1/batch/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=5f4bf85ba48333e6cda6ff613b4ea2faacd0417b4136621c58b87a488c3019ee', 'Content-Length'=>'106', 'Content-Type'=>'', 'Host'=>'batch.us-east-1.amazonaws.com', 'User-Agent'=>'aws-sdk-ruby3/3.54.2 ruby/2.5.5 x86_64-darwin18 aws-sdk-batch/1.20.0', 'X-Amz-Content-Sha256'=>'cf52595364d1a588b4ca4fdeaddb8170e4ad944fa28ac6df647484bb596de9c4', 'X-Amz-Date'=>'20190701T215756Z'}

       You can stub this request with the following snippet:

       stub_request(:post, "https://batch.us-east-1.amazonaws.com/v1/submitjob").
         with(
           body: "{\"jobName\":\"Fakie\",\"jobQueue\":\"quue\",\"jobDefinition\":\"def\",\"parameters\":{\"task\":\"{\\\"fake\\\":\\\"town\\\"}\"}}",
           headers: {
          'Accept'=>'*/*',
          'Accept-Encoding'=>'',
          'Authorization'=>'AWS4-HMAC-SHA256 Credential=ACCESS_KEY_ID/20190701/us-east-1/batch/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=5f4bf85ba48333e6cda6ff613b4ea2faacd0417b4136621c58b87a488c3019ee',
          'Content-Length'=>'106',
          'Content-Type'=>'',
          'Host'=>'batch.us-east-1.amazonaws.com',
          'User-Agent'=>'aws-sdk-ruby3/3.54.2 ruby/2.5.5 x86_64-darwin18 aws-sdk-batch/1.20.0',
          'X-Amz-Content-Sha256'=>'cf52595364d1a588b4ca4fdeaddb8170e4ad944fa28ac6df647484bb596de9c4',
          'X-Amz-Date'=>'20190701T215756Z'
           }).
         to_return(status: 200, body: "", headers: {})

       registered request stubs:

       stub_request(:post, "https://batch.us-east-1.amazonaws.com/v1/submitjob").
         with(
           body: {"jobDefinition"=>"def", "jobName"=>"Wrong", "jobQueue"=>"queue", "parameters"=>{"task"=>"{\"fake\":\"town\"}"}})

正如您所看到的,当这些字符串测试失败时,您将面临逐个字符挑选正文的痛苦任务,这是一种非常可怕的开发人员体验。 Hashdiff 的体验非常出色。

【问题讨论】:

  • 作为备注,您可以尝试vcr gem,它为您提供了在测试中模拟 http 请求的更便捷方式
  • @MartinZinovsky 我不是 VCR 的粉丝。我在一个大型 Rails 项目中工作,该项目使用 VCR 模拟了数百个请求,我发现它们非常脆弱。我更喜欢设置一个在测试中定义的显式模拟。使用 VCR 记录请求时,您还会选择与您正在测试的内容无关的内容(考虑缓存标头或过期的令牌)(也会增加脆弱性)。同样在这种情况下,VCR 对我没有帮助——AWS SDK(特别是 Seahorse)没有设置Content-Type,所以即使我记录了请求,我仍然会在失败时遇到难看的差异。

标签: ruby amazon-web-services webmock aws-batch aws-sdk-ruby


【解决方案1】:

AWS SDK 的基本 http 客户端称为 Seahorse,允许您添加更改请求链行为的处理程序。

可以添加标头Content-Type:application/json 的处理程序如下所示:

  class ContentType < Seahorse::Client::Plugin
    class Handler < Seahorse::Client::Handler
      def call(context)
        context.http_request.headers['Content-Type'] = 'application/json'
        @handler.call(context)
      end
    end
    handler(Handler, step: :sign, priority: 0)
  end

然后可以将其添加到继承自 Seahorse 的 AWS 开发工具包服务:

Aws::Batch::Client.add_plugin(ContentType)

现在 Webmock 会像这样响应失败:

...
       registered request stubs:

       stub_request(:post, "https://batch.us-east-1.amazonaws.com/v1/submitjob").
         with(
           body: {"jobDefinition"=>"def", "jobName"=>"Wrong", "jobQueue"=>"queueName", "parameters"=>{"task"=>"{\"fake\":\"town\"}"}})

       Body diff:
        [["~", "jobName", "Fakie", "Wrong"]]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-27
    • 2015-07-13
    • 2013-12-10
    相关资源
    最近更新 更多