api_hammer 0.10.2 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/bin/hc +9 -0
- data/lib/api_hammer/body.rb +103 -0
- data/lib/api_hammer/content_type_attrs.rb +15 -3
- data/lib/api_hammer/faraday/outputter.rb +21 -14
- data/lib/api_hammer/faraday/request_logger.rb +11 -79
- data/lib/api_hammer/request_logger.rb +20 -17
- data/lib/api_hammer/trailing_newline.rb +1 -1
- data/lib/api_hammer/version.rb +1 -1
- data/lib/api_hammer.rb +1 -1
- data/lib/logstash/filters/request_bodies_parsed.rb +1 -1
- metadata +3 -3
- data/lib/api_hammer/parsed_body.rb +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d475db83c102fc0746ea2da97c992a9ab1e6a1f
|
4
|
+
data.tar.gz: f82cbddaf738a334f7779bed1ce64005c6e46f93
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42161c34bc9260717cba35c2ce308636490e332722e43d1435fa2300b404f97156701d9bed860a727ed4dbf2fcab010968f6cb360d33dd10b63dfaf4f73b7d75
|
7
|
+
data.tar.gz: 59f6ccc971e7d4c925a7141c7fa91670bf36e83972598c0583015c0df5c48759195bf34fb6499887b3703fce63f9610a700f9d91b334720e9627bf93792ac0cf
|
data/CHANGELOG.md
CHANGED
data/bin/hc
CHANGED
@@ -44,6 +44,9 @@ opt_parser = OptionParser.new do |opts|
|
|
44
44
|
opts.on("-t", "--content-type CONTENT-TYPE", "Sets the Content-Type header of the request. This defaults to application/json if a body is included.") do |v|
|
45
45
|
$options[:headers]['Content-Type'.downcase] = v
|
46
46
|
end
|
47
|
+
opts.on("-o", "--output OUTPUT", "write response to file") do |v|
|
48
|
+
$options[:output] = v
|
49
|
+
end
|
47
50
|
opts.on("--oauth-token TOKEN", "OAuth 1.0 token") do |token|
|
48
51
|
$oauth[:token] = token
|
49
52
|
end
|
@@ -116,3 +119,9 @@ end
|
|
116
119
|
# OH LOOK IT'S FINALLY ACTUALLY CONNECTING TO SOMETHING
|
117
120
|
|
118
121
|
response = connection.run_request(httpmethod.downcase.to_sym, url, body, headers)
|
122
|
+
|
123
|
+
if $options[:output]
|
124
|
+
File.open($options[:output], 'wb') do |f|
|
125
|
+
f.write(response.body)
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'rack'
|
2
|
+
|
3
|
+
module ApiHammer
|
4
|
+
class Body
|
5
|
+
attr_reader :body, :content_type
|
6
|
+
|
7
|
+
def initialize(body, content_type)
|
8
|
+
@body = body
|
9
|
+
@content_type = content_type
|
10
|
+
end
|
11
|
+
|
12
|
+
# parses the body to an object
|
13
|
+
def object
|
14
|
+
instance_variable_defined?(:@object) ? @object : @object = begin
|
15
|
+
if media_type == 'application/json'
|
16
|
+
JSON.parse(body) rescue nil
|
17
|
+
elsif media_type == 'application/x-www-form-urlencoded'
|
18
|
+
CGI.parse(body).map { |k, vs| {k => vs.last} }.inject({}, &:update)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def filtered(options)
|
24
|
+
@filtered ||= Body.new(begin
|
25
|
+
if media_type == 'application/json'
|
26
|
+
begin
|
27
|
+
ApiHammer::Filtration::Json.new(body, options).filter
|
28
|
+
rescue JSON::ParserError
|
29
|
+
body
|
30
|
+
end
|
31
|
+
elsif media_type == 'application/x-www-form-urlencoded'
|
32
|
+
ApiHammer::Filtration::FormEncoded.new(body, options).filter
|
33
|
+
else
|
34
|
+
body
|
35
|
+
end
|
36
|
+
end, content_type)
|
37
|
+
end
|
38
|
+
|
39
|
+
def content_type_attrs
|
40
|
+
@content_type_attrs ||= ContentTypeAttrs.new(content_type)
|
41
|
+
end
|
42
|
+
|
43
|
+
def media_type
|
44
|
+
content_type_attrs.media_type
|
45
|
+
end
|
46
|
+
|
47
|
+
# deal with the vagaries of getting the response body in a form which JSON
|
48
|
+
# gem will not cry about generating
|
49
|
+
def jsonifiable
|
50
|
+
@jsonifiable ||= Body.new(catch(:jsonifiable) do
|
51
|
+
original_body = self.body
|
52
|
+
unless original_body.is_a?(String)
|
53
|
+
begin
|
54
|
+
# if the response body is not a string, but JSON doesn't complain
|
55
|
+
# about dumping whatever it is, go ahead and use it
|
56
|
+
JSON.generate([original_body])
|
57
|
+
throw :jsonifiable, original_body
|
58
|
+
rescue
|
59
|
+
# otherwise return nil - don't know what to do with whatever this object is
|
60
|
+
throw :jsonifiable, nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# first try to change the string's encoding per the Content-Type header
|
65
|
+
body = original_body.dup
|
66
|
+
unless body.valid_encoding?
|
67
|
+
# I think this always comes in as ASCII-8BIT anyway so may never get here. hopefully.
|
68
|
+
body.force_encoding('ASCII-8BIT')
|
69
|
+
end
|
70
|
+
|
71
|
+
content_type_attrs = ContentTypeAttrs.new(content_type)
|
72
|
+
if content_type_attrs.parsed?
|
73
|
+
charset = content_type_attrs['charset'].first
|
74
|
+
if charset && Encoding.list.any? { |enc| enc.to_s.downcase == charset.downcase }
|
75
|
+
if body.dup.force_encoding(charset).valid_encoding?
|
76
|
+
body.force_encoding(charset)
|
77
|
+
else
|
78
|
+
# I guess just ignore the specified encoding if the result is not valid. fall back to
|
79
|
+
# something else below.
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
begin
|
84
|
+
JSON.generate([body])
|
85
|
+
rescue Encoding::UndefinedConversionError
|
86
|
+
# if updating by content-type didn't do it, try UTF8 since JSON wants that - but only
|
87
|
+
# if it seems to be valid utf8.
|
88
|
+
# don't try utf8 if the response content-type indicated something else.
|
89
|
+
try_utf8 = !(content_type_attrs && content_type_attrs.parsed? && content_type_attrs['charset'].any?)
|
90
|
+
if try_utf8 && body.dup.force_encoding('UTF-8').valid_encoding?
|
91
|
+
body.force_encoding('UTF-8')
|
92
|
+
else
|
93
|
+
# I'm not sure if there is a way in this situation to get JSON gem to generate the
|
94
|
+
# string correctly. fall back to an array of codepoints I guess? this is a weird
|
95
|
+
# solution but the best I've got for now.
|
96
|
+
body = body.codepoints.to_a
|
97
|
+
end
|
98
|
+
end
|
99
|
+
body
|
100
|
+
end, content_type)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -27,7 +27,7 @@ module ApiHammer
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
attr_reader :media_type
|
30
|
+
attr_reader :content_type, :media_type
|
31
31
|
|
32
32
|
def parsed?
|
33
33
|
@parsed
|
@@ -47,12 +47,19 @@ module ApiHammer
|
|
47
47
|
%r(model/.*) => :binary,
|
48
48
|
%r(text/.*) => :text,
|
49
49
|
%r(message/.*) => :text,
|
50
|
+
%r(application/(.+\+)?json) => :text,
|
51
|
+
%r(application/(.+\+)?xml) => :text,
|
52
|
+
%r(model/(.+\+)?xml) => :text,
|
53
|
+
'application/x-www-form-urlencoded' => :text,
|
54
|
+
'application/javascript' => :text,
|
55
|
+
'application/ecmascript' => :text,
|
50
56
|
'application/octet-stream' => :binary,
|
51
57
|
'application/ogg' => :binary,
|
52
58
|
'application/pdf' => :binary,
|
53
59
|
'application/postscript' => :binary,
|
54
60
|
'application/zip' => :binary,
|
55
61
|
'application/gzip' => :binary,
|
62
|
+
'application/vnd.apple.pkpass' => :binary,
|
56
63
|
}
|
57
64
|
types.each do |match, type|
|
58
65
|
matched = match.is_a?(Regexp) ? media_type =~ %r(\A#{match.source}\z) : media_type == match
|
@@ -60,8 +67,13 @@ module ApiHammer
|
|
60
67
|
return type == :text
|
61
68
|
end
|
62
69
|
end
|
63
|
-
# fallback (unknown or not given) assume
|
64
|
-
|
70
|
+
# fallback (unknown or not given) assume that unknown content types are binary but omitted
|
71
|
+
# content-type means text
|
72
|
+
if content_type && content_type =~ /\S/
|
73
|
+
return false
|
74
|
+
else
|
75
|
+
return true
|
76
|
+
end
|
65
77
|
end
|
66
78
|
end
|
67
79
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'faraday'
|
2
2
|
require 'rack'
|
3
|
+
require 'api_hammer'
|
3
4
|
|
4
5
|
module ApiHammer
|
5
6
|
# outputs the response body to the given logger or output device (defaulting to STDOUT)
|
@@ -55,6 +56,8 @@ module ApiHammer
|
|
55
56
|
color :response_header
|
56
57
|
color :response_blankline, :intense_green, :bold
|
57
58
|
|
59
|
+
color :omitted_body, :intense_yellow
|
60
|
+
|
58
61
|
def call(request_env)
|
59
62
|
puts "#{info('*')} #{info_body("connect to #{request_env[:url].host} on port #{request_env[:url].port}")}"
|
60
63
|
puts "#{info('*')} #{info_body("getting our SSL on")}" if request_env[:url].scheme=='https'
|
@@ -125,23 +128,27 @@ module ApiHammer
|
|
125
128
|
# - formatted prettily if #pretty? is true
|
126
129
|
def alter_body_by_content_type(body, content_type)
|
127
130
|
return body unless body.is_a?(String)
|
128
|
-
|
129
|
-
if
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
131
|
+
content_type_attrs = ApiHammer::ContentTypeAttrs.new(content_type)
|
132
|
+
if content_type_attrs.text?
|
133
|
+
if pretty?
|
134
|
+
case content_type_attrs.media_type
|
135
|
+
when 'application/json'
|
136
|
+
require 'json'
|
137
|
+
begin
|
138
|
+
body = JSON.pretty_generate(JSON.parse(body))
|
139
|
+
rescue JSON::ParserError
|
140
|
+
end
|
136
141
|
end
|
137
142
|
end
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
143
|
+
if color?
|
144
|
+
coderay_scanner = CodeRayForMediaTypes.reject{|k,v| !v.any?{|type| type === content_type_attrs.media_type} }.keys.first
|
145
|
+
if coderay_scanner
|
146
|
+
require 'coderay'
|
147
|
+
body = CodeRay.scan(body, coderay_scanner).encode(:terminal)
|
148
|
+
end
|
144
149
|
end
|
150
|
+
else
|
151
|
+
body = omitted_body("[[omitted binary body (size = #{body.size})]]")
|
145
152
|
end
|
146
153
|
body
|
147
154
|
end
|
@@ -5,72 +5,6 @@ require 'strscan'
|
|
5
5
|
|
6
6
|
module ApiHammer
|
7
7
|
module Faraday
|
8
|
-
class Request
|
9
|
-
def initialize(request_env, response_env)
|
10
|
-
@request_env = request_env
|
11
|
-
@response_env = response_env
|
12
|
-
end
|
13
|
-
|
14
|
-
attr_reader :request_env
|
15
|
-
attr_reader :response_env
|
16
|
-
|
17
|
-
# deal with the vagaries of getting the response body in a form which JSON
|
18
|
-
# gem will not cry about generating
|
19
|
-
def response_body
|
20
|
-
instance_variable_defined?(:@response_body) ? @response_body : @response_body = catch(:response_body) do
|
21
|
-
unless response_env.body.is_a?(String)
|
22
|
-
begin
|
23
|
-
# if the response body is not a string, but JSON doesn't complain
|
24
|
-
# about dumping whatever it is, go ahead and use it
|
25
|
-
JSON.generate([response_env.body])
|
26
|
-
throw :response_body, response_env.body
|
27
|
-
rescue
|
28
|
-
# otherwise return nil - don't know what to do with whatever this object is
|
29
|
-
throw :response_body, nil
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
# first try to change the string's encoding per the Content-Type header
|
34
|
-
content_type = response_env.response_headers['Content-Type']
|
35
|
-
response_body = response_env.body.dup
|
36
|
-
unless response_body.valid_encoding?
|
37
|
-
# I think this always comes in as ASCII-8BIT anyway so may never get here. hopefully.
|
38
|
-
response_body.force_encoding('ASCII-8BIT')
|
39
|
-
end
|
40
|
-
|
41
|
-
content_type_attrs = ContentTypeAttrs.new(content_type)
|
42
|
-
if content_type_attrs.parsed?
|
43
|
-
charset = content_type_attrs['charset'].first
|
44
|
-
if charset && Encoding.list.any? { |enc| enc.to_s.downcase == charset.downcase }
|
45
|
-
if response_body.dup.force_encoding(charset).valid_encoding?
|
46
|
-
response_body.force_encoding(charset)
|
47
|
-
else
|
48
|
-
# I guess just ignore the specified encoding if the result is not valid. fall back to
|
49
|
-
# something else below.
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
begin
|
54
|
-
JSON.generate([response_body])
|
55
|
-
rescue Encoding::UndefinedConversionError
|
56
|
-
# if updating by content-type didn't do it, try UTF8 since JSON wants that - but only
|
57
|
-
# if it seems to be valid utf8.
|
58
|
-
# don't try utf8 if the response content-type indicated something else.
|
59
|
-
try_utf8 = !(content_type_attrs && content_type_attrs.parsed? && content_type_attrs['charset'].any?)
|
60
|
-
if try_utf8 && response_body.dup.force_encoding('UTF-8').valid_encoding?
|
61
|
-
response_body.force_encoding('UTF-8')
|
62
|
-
else
|
63
|
-
# I'm not sure if there is a way in this situation to get JSON gem to generate the
|
64
|
-
# string correctly. fall back to an array of codepoints I guess? this is a weird
|
65
|
-
# solution but the best I've got for now.
|
66
|
-
response_body = response_body.codepoints.to_a
|
67
|
-
end
|
68
|
-
end
|
69
|
-
response_body
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
8
|
# Faraday middleware for logging.
|
75
9
|
#
|
76
10
|
# logs two lines:
|
@@ -101,8 +35,6 @@ module ApiHammer
|
|
101
35
|
@app.call(request_env).on_complete do |response_env|
|
102
36
|
now = Time.now
|
103
37
|
|
104
|
-
request = ApiHammer::Faraday::Request.new(request_env, response_env)
|
105
|
-
|
106
38
|
status_color = case response_env.status.to_i
|
107
39
|
when 200..299
|
108
40
|
:intense_green
|
@@ -115,17 +47,17 @@ module ApiHammer
|
|
115
47
|
end
|
116
48
|
status_s = bold(send(status_color, response_env.status.to_s))
|
117
49
|
|
118
|
-
|
119
|
-
|
50
|
+
bodies = [
|
51
|
+
['request', request_body, request_env.request_headers],
|
52
|
+
['response', response_env.body, response_env.response_headers]
|
53
|
+
].map do |(role, body, headers)|
|
54
|
+
{role => Body.new(body, headers['Content-Type']).jsonifiable}
|
55
|
+
end.inject({}, &:update)
|
120
56
|
|
121
57
|
if @options[:filter_keys]
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
parsed_body = ApiHammer::ParsedBody.new(body, headers['Content-Type'])
|
126
|
-
body.replace(parsed_body.filtered_body(@options.slice(:filter_keys)))
|
127
|
-
end
|
128
|
-
end
|
58
|
+
bodies = bodies.map do |(role, body)|
|
59
|
+
{role => body.filtered(@options.slice(:filter_keys))}
|
60
|
+
end.inject({}, &:update)
|
129
61
|
end
|
130
62
|
|
131
63
|
data = {
|
@@ -134,12 +66,12 @@ module ApiHammer
|
|
134
66
|
'method' => request_env[:method],
|
135
67
|
'uri' => request_env[:url].normalize.to_s,
|
136
68
|
'headers' => request_env.request_headers,
|
137
|
-
'body' => (
|
69
|
+
'body' => (bodies['request'].body if bodies['request'].content_type_attrs.text?),
|
138
70
|
}.reject{|k,v| v.nil? },
|
139
71
|
'response' => {
|
140
72
|
'status' => response_env.status.to_s,
|
141
73
|
'headers' => response_env.response_headers,
|
142
|
-
'body' => (
|
74
|
+
'body' => (bodies['response'].body if bodies['response'].content_type_attrs.text?),
|
143
75
|
}.reject{|k,v| v.nil? },
|
144
76
|
'processing' => {
|
145
77
|
'began_at' => began_at.utc.to_f,
|
@@ -112,24 +112,27 @@ module ApiHammer
|
|
112
112
|
response_body_string = response_body.to_enum.to_a.join('')
|
113
113
|
body_info = [['request', request_body, request.content_type], ['response', response_body_string, response.content_type]]
|
114
114
|
body_info.map do |(role, body, content_type)|
|
115
|
-
parsed_body = ApiHammer::
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
115
|
+
parsed_body = ApiHammer::Body.new(body, content_type)
|
116
|
+
content_type_attrs = ApiHammer::ContentTypeAttrs.new(content_type)
|
117
|
+
if content_type_attrs.text?
|
118
|
+
if (400..599).include?(status.to_i) || body.size < LARGE_BODY_SIZE
|
119
|
+
# log bodies if they are not large, or if there was an error (either client or server)
|
120
|
+
data[role]['body'] = parsed_body.jsonifiable.filtered(@options.reject { |k,v| ![:filter_keys].include?(k) }).body
|
121
|
+
else
|
122
|
+
# otherwise, log id and uuid fields
|
123
|
+
body_object = parsed_body.object
|
124
|
+
sep = /(?:\b|\W|_)/
|
125
|
+
hash_ids = proc do |hash|
|
126
|
+
hash.reject { |key, value| !(key =~ /#{sep}([ug]u)?id#{sep}/ && value.is_a?(String)) }
|
127
|
+
end
|
128
|
+
if body_object.is_a?(Hash)
|
129
|
+
body_ids = hash_ids.call(body_object)
|
130
|
+
elsif body_object.is_a?(Array) && body_object.all? { |e| e.is_a?(Hash) }
|
131
|
+
body_ids = body_object.map(&hash_ids)
|
132
|
+
end
|
131
133
|
|
132
|
-
|
134
|
+
data[role]['body_ids'] = body_ids if body_ids && body_ids.any?
|
135
|
+
end
|
133
136
|
end
|
134
137
|
end
|
135
138
|
Thread.current['request_logger.info'] = nil
|
@@ -26,7 +26,7 @@ module ApiHammer
|
|
26
26
|
end
|
27
27
|
def call(env)
|
28
28
|
status, headers, body = *@app.call(env)
|
29
|
-
if env['REQUEST_METHOD'].downcase != 'head'
|
29
|
+
if env['REQUEST_METHOD'].downcase != 'head' && ApiHammer::ContentTypeAttrs.new(env['CONTENT_TYPE']).text?
|
30
30
|
body = TNLBodyProxy.new(body){}
|
31
31
|
if headers["Content-Length"]
|
32
32
|
headers["Content-Length"] = body.map(&Rack::Utils.method(:bytesize)).inject(0, &:+).to_s
|
data/lib/api_hammer/version.rb
CHANGED
data/lib/api_hammer.rb
CHANGED
@@ -12,7 +12,7 @@ module ApiHammer
|
|
12
12
|
autoload :RailsOrSidekiqLogger, 'api_hammer/rails_or_sidekiq_logger'
|
13
13
|
autoload :FaradayOutputter, 'api_hammer/faraday/outputter'
|
14
14
|
autoload :FaradayCurlVOutputter, 'api_hammer/faraday/outputter'
|
15
|
-
autoload :
|
15
|
+
autoload :Body, 'api_hammer/body'
|
16
16
|
autoload :ContentTypeAttrs, 'api_hammer/content_type_attrs'
|
17
17
|
autoload :JsonScriptEscapeHelper, 'api_hammer/json_script_escape_helper'
|
18
18
|
module Faraday
|
@@ -21,7 +21,7 @@ class LogStash::Filters::RequestBodiesParsed < LogStash::Filters::Base
|
|
21
21
|
if event[re]['headers'].is_a?(Hash) && !content_type
|
22
22
|
_, content_type = event[re]['headers'].detect { |(k,_)| k =~ /\Acontent.type\z/i }
|
23
23
|
end
|
24
|
-
parsed_body = ApiHammer::
|
24
|
+
parsed_body = ApiHammer::Body.new(event[re]['body'], content_type)
|
25
25
|
event[re]['body_parsed'] = parsed_body.object if parsed_body.object
|
26
26
|
end
|
27
27
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: api_hammer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ethan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -244,6 +244,7 @@ files:
|
|
244
244
|
- bin/hc
|
245
245
|
- lib/api_hammer.rb
|
246
246
|
- lib/api_hammer/active_record_cache_find_by.rb
|
247
|
+
- lib/api_hammer/body.rb
|
247
248
|
- lib/api_hammer/check_required_params.rb
|
248
249
|
- lib/api_hammer/content_type_attrs.rb
|
249
250
|
- lib/api_hammer/faraday/outputter.rb
|
@@ -252,7 +253,6 @@ files:
|
|
252
253
|
- lib/api_hammer/filtration/json.rb
|
253
254
|
- lib/api_hammer/halt.rb
|
254
255
|
- lib/api_hammer/json_script_escape_helper.rb
|
255
|
-
- lib/api_hammer/parsed_body.rb
|
256
256
|
- lib/api_hammer/public_instance_exec.rb
|
257
257
|
- lib/api_hammer/rails.rb
|
258
258
|
- lib/api_hammer/rails_or_sidekiq_logger.rb
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'rack'
|
2
|
-
|
3
|
-
module ApiHammer
|
4
|
-
class ParsedBody
|
5
|
-
attr_reader :body, :content_type, :media_type
|
6
|
-
|
7
|
-
def initialize(body, content_type)
|
8
|
-
@body = body
|
9
|
-
@content_type = content_type
|
10
|
-
@media_type = ::Rack::Request.new({'CONTENT_TYPE' => content_type}).media_type
|
11
|
-
end
|
12
|
-
|
13
|
-
def object
|
14
|
-
instance_variable_defined?(:@object) ? @object : @object = begin
|
15
|
-
if media_type == 'application/json'
|
16
|
-
JSON.parse(body) rescue nil
|
17
|
-
elsif media_type == 'application/x-www-form-urlencoded'
|
18
|
-
CGI.parse(body).map { |k, vs| {k => vs.last} }.inject({}, &:update)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def filtered_body(options)
|
24
|
-
@filtered_body ||= begin
|
25
|
-
if media_type == 'application/json'
|
26
|
-
begin
|
27
|
-
ApiHammer::Filtration::Json.new(body, options).filter
|
28
|
-
rescue JSON::ParserError
|
29
|
-
body
|
30
|
-
end
|
31
|
-
elsif media_type == 'application/x-www-form-urlencoded'
|
32
|
-
ApiHammer::Filtration::FormEncoded.new(body, options).filter
|
33
|
-
else
|
34
|
-
body
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|