rack-jsonparser 0.1.4 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -4
  3. data/lib/rack/json_parser.rb +35 -9
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d34d28f12f5fbada826a128a5d6d7003e19886a2
4
- data.tar.gz: 847559f7291cbabcb224056d9f0c1bb59b877266
3
+ metadata.gz: eac921ff3af56183ab2ba111c35a5c82fc33ea28
4
+ data.tar.gz: e4f9a9e559aaa76d37f104f427acd18a5da57f3f
5
5
  SHA512:
6
- metadata.gz: 7e71bb61d3ed06f5ca9449b1140938fa3578a1661023d3fea4fdb10a08a8f2bfaa0fb10898c7a17ae01b9d63ca1e264edff3adfa645d380f79877fbc9ab11f18
7
- data.tar.gz: d9742358907b79ca3c8f735ffaf772d300762dd288d89424036425c2442aa41c3b748ca1f9a290b5092e6f29bba5e1787a22118c9d89594ba7116b242d760611
6
+ metadata.gz: 70389f5d95ac35207a28afd28aa8ec4e24d3c441a026958546da59e5ad104f3311f74382367ef352434c9414a90f67f06ee1be48f9308158a5ec35ef90933495
7
+ data.tar.gz: 3275436b113a6640515274ebd3ec6aa0a473e6cb894d062b2cca4de7531b52acae0261f051856b7a9c4f323f0e4285f38254e7e59e8df22dd779bc6234c386f9
data/README.md CHANGED
@@ -39,15 +39,15 @@ Below is a sample rack app which uses the middleware to send and receive JSON:
39
39
  ```ruby
40
40
  require 'rack/json_parser'
41
41
 
42
- # Notice how the `payload` is a Hash, not a JSON string
42
+ # Notice how the `request.payload` is a Hash, not a JSON string
43
43
  # We return a Hash instance (or any Ruby object) for the response body
44
44
  # We can turn off the request/response parsing via the `use` method (defaults to true)
45
- # Parsing will only occur if enabled AND the Content-Type is `application/json`
45
+ # Parsing will only occur if enabled AND the `Content-Type` is `application/json`
46
46
  handler = proc do |env|
47
- payload = env['payload']
47
+ payload = env['request.payload']
48
48
  full_name = payload['forenames'].push(payload['surname']).join(' ')
49
49
  res_hash = { 'full_name' => full_name }
50
- [200, { 'CONTENT_TYPE' => 'application/json' }, res_hash]
50
+ [200, { 'Content-Type' => 'application/json' }, res_hash]
51
51
  end
52
52
 
53
53
  app = Rack::Builder.new do
@@ -1,4 +1,5 @@
1
1
  require 'oj'
2
+ require 'rack'
2
3
 
3
4
  module Rack
4
5
  # Rack middleware which transforms JSON during the request and response.
@@ -8,7 +9,14 @@ module Rack
8
9
  # served by the application without interference by this middleware. This
9
10
  # however requires the client and app to set the 'Content-Type' correctly.
10
11
  class JSONParser
11
- ENV_PAYLOAD_KEY = 'payload'.freeze
12
+ CONTENT_TYPE_KEY = 'Content-Type'.freeze
13
+ CONTENT_TYPE_ALT_KEY = 'CONTENT_TYPE'.freeze
14
+ CONTENT_LENGTH_KEY = 'Content-Length'.freeze
15
+
16
+ CONTENT_TYPE_JSON = 'application/json'.freeze
17
+
18
+ ENV_PAYLOAD_KEY = 'request.payload'.freeze
19
+ ENV_RACK_INPUT_KEY = 'rack.input'.freeze
12
20
 
13
21
  # Called via the rack `use` method. Used to register the middleware and
14
22
  # optionally toggle request and response processing of JSON to Object.
@@ -22,19 +30,22 @@ module Rack
22
30
  # Loads the request JSON string into a Hash instance.
23
31
  # Expects the app response body to be an object instance e.g. Hash,
24
32
  # putting the object in an array will likely cause unexpected JSON.
25
- # If the response body is processed then the `CONTENT_LENGTH` header will
26
- # be set to the body.length.
33
+ # If the response body is processed then the `Content-Length` header will
34
+ # be set to the body#length.
27
35
  def call(env)
36
+ env = Rack::Utils::HeaderHash.new(env)
37
+
28
38
  if transform_request?(env)
29
- env[ENV_PAYLOAD_KEY] = Oj.load(env['rack.input'])
39
+ env[ENV_PAYLOAD_KEY] = Oj.load(env[ENV_RACK_INPUT_KEY])
30
40
  end
31
41
 
32
42
  status, headers, body = @app.call(env)
43
+ headers = Rack::Utils::HeaderHash.new(headers)
33
44
 
34
45
  if transform_response?(headers, body)
35
46
  body = Oj.dump(body)
36
- headers['CONTENT_LENGTH'] = body.length.to_s
37
- body = [body] unless body.is_a?(Array)
47
+ headers[CONTENT_LENGTH_KEY] = body.length.to_s
48
+ body = [body] unless body.respond_to?(:each)
38
49
  end
39
50
 
40
51
  [status, headers, body]
@@ -47,8 +58,8 @@ module Rack
47
58
  # request parameters such as headers and request body.
48
59
  def transform_request?(env)
49
60
  @transform_request &&
50
- env['CONTENT_TYPE'] == 'application/json' &&
51
- env['rack.input'] &&
61
+ json_content_type?(env) &&
62
+ env[ENV_RACK_INPUT_KEY] &&
52
63
  true # so the return value is true if all prior conditions are true
53
64
  end
54
65
 
@@ -57,9 +68,24 @@ module Rack
57
68
  # and response parameters such as headers and response body.
58
69
  def transform_response?(headers, body)
59
70
  @transform_response &&
60
- headers['CONTENT_TYPE'] == 'application/json' &&
71
+ json_content_type?(headers) &&
61
72
  body &&
62
73
  true # so the return value is true if all prior conditions are true
63
74
  end
75
+
76
+ # Determine whether or not the 'Content-Type' is 'application/json'.
77
+ # The content type value assertion is always case insensitive and supports
78
+ # both a dash/hyphen and an underscore. The content type key assertion
79
+ # depends on the env parameter. A Hash is case sensitive by default whereas
80
+ # a Rack::Utils::HeaderHash is case insensitive.
81
+ def json_content_type?(env)
82
+ if env.include?(CONTENT_TYPE_KEY)
83
+ env[CONTENT_TYPE_KEY].downcase == CONTENT_TYPE_JSON.downcase
84
+ elsif env.include?(CONTENT_TYPE_ALT_KEY)
85
+ env[CONTENT_TYPE_ALT_KEY].downcase == CONTENT_TYPE_JSON.downcase
86
+ else
87
+ false
88
+ end
89
+ end
64
90
  end
65
91
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-jsonparser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Telford
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-02 00:00:00.000000000 Z
11
+ date: 2017-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oj