class FaradayJSON::EncodeJson
Request middleware that encodes the body as JSON.
Processes only requests with matching Content-type or those without a type. If a request doesn't have a type but has a body, it sets the Content-type to JSON MIME-type.
Doesn't try to encode bodies that already are in string form.
Constants
- CONTENT_LENGTH
- CONTENT_TYPE
- MIME_TYPE
- MIME_TYPE_UTF8
Public Instance Methods
call(env)
click to toggle source
# File lib/faraday_json/encode_json.rb, line 32 def call(env) if process_request?(env) body = env[:body] # Detect and honour input charset. Basically, all requests without a # charset should be considered malformed, but we can make a best guess. # Whether the body is a string or another data structure does not # matter: all strings *contained* within it must be encoded properly. charset = request_charset(env) # Strip BOM, if any body = strip_bom(body, charset, { 'default_encoding' => 'us-ascii' }) # Transcode to UTF-8 body = to_utf8(body, charset, { 'force_input_charset' => true }) # If the body is a stirng, we assume it's already JSON. No further # processing is necessary. # XXX Is :to_str really a good indicator for Strings? Taken from old # code. if not body.respond_to?(:to_str) # If body isn't a string yet, we need to encode it. We also know it's # then going to be UTF-8, because JSON defaults to that. # Thanks to to_utf8 above, JSON.dump should not have any issues here. body = ::JSON.dump(body) end env[:body] = body # We'll add a content length, because otherwise we're relying on every # component down the line properly interpreting UTF-8 - that can fail. env[:request_headers][CONTENT_LENGTH] ||= env[:body].bytesize.to_s # Always base the encoding we're sending in the content type header on # the string encoding. env[:request_headers][CONTENT_TYPE] = MIME_TYPE_UTF8 end @app.call env end
has_body?(env)
click to toggle source
# File lib/faraday_json/encode_json.rb, line 84 def has_body?(env) body = env[:body] and !(body.respond_to?(:to_str) and body.empty?) end
process_request?(env)
click to toggle source
# File lib/faraday_json/encode_json.rb, line 72 def process_request?(env) type = request_type(env) has_body?(env) and (type.empty? or type == MIME_TYPE) end
request_charset(env)
click to toggle source
# File lib/faraday_json/encode_json.rb, line 77 def request_charset(env) enc = env[:request_headers][CONTENT_TYPE].to_s enc = enc.split(';', 2).last if enc.index(';') enc = enc.split('=', 2).last if enc.index('=') return enc end
request_type(env)
click to toggle source
# File lib/faraday_json/encode_json.rb, line 88 def request_type(env) type = env[:request_headers][CONTENT_TYPE].to_s type = type.split(';', 2).first if type.index(';') type end