jsonrpc-rails 0.1.0 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7a329937c7fecde34677567a8df15dab630b5062b30c01f1fcb825b25789e590
4
- data.tar.gz: e7d7de880e9adc77839bb29feafdff54a35f56de555a68aa7e9d62413bf2d3fa
3
+ metadata.gz: 7c7eaabe38b79dd41bac2752a456d5278e6cc780c3d2ebbe0493c349ff24ee10
4
+ data.tar.gz: 51797ce9c50cd5e51b248f8a4376880f7ffcf19245daa8ae2ef1a4b9d5d17cdf
5
5
  SHA512:
6
- metadata.gz: e98d92b3ea32b21fc6b1fafa766a0a9b3a60f9cd0475424753c486e62c872945dd105c0e64f91c9d0eba291918ec5bab6f5d3310d4039ed2b807c9c53d3f6291
7
- data.tar.gz: b724be97e378604ede9244d90b76d93f07c0070a1e142ed0d3787c5d81e4df1dd8f1848a3d84fdd28096d6ae6cb7102e86780fe6c2b2fbabbf8a8e1fc8f0615b
6
+ metadata.gz: 3a55b1b369ff4d277b3351c6632a858bd00244cd0799108fbeaf4e64ba2e5b39c4687be0f1855e96df90343541e8ac0ab137684cad4f7af7394a75612b367395
7
+ data.tar.gz: 9883f5c131ab3437cde5410f82a21f072824a045e1680ad27d81ef1f4d10d471149a7db639c18d8e2d194586979919224c4e921bae263236023d71934d2a6cc5
data/README.md CHANGED
@@ -10,7 +10,7 @@ It integrates into Rails, allowing you to render JSON-RPC responses and validate
10
10
  - **Rails Integration:** Easily integrate JSON-RPC 2.0 support via a Rails Railtie.
11
11
  - **Custom Renderer:** Render responses with `render jsonrpc:`, automatically wrapping data in the JSON-RPC 2.0 envelope.
12
12
  - **Error Handling:** Built-in support for both success and error responses according to the JSON-RPC 2.0 specification.
13
- - **Request Validation:** Includes middleware (`JSON_RPC_Rails::Middleware::Validator`) to strictly validate incoming JSON-RPC 2.0 requests (single and batch) against the specification structure.
13
+ - **Request Validation:** Includes middleware (`JSONRPC_Rails::Middleware::Validator`) to strictly validate incoming JSON-RPC 2.0 requests (single and batch) against the specification structure.
14
14
  - **Rails 8+ Compatibility:** Designed specifically for Rails 8 and later versions.
15
15
 
16
16
  ## Installation
@@ -81,7 +81,7 @@ You can override the default `message` or add `data` for either method by provid
81
81
 
82
82
  ### Handling Requests
83
83
 
84
- The gem automatically inserts `JSON_RPC_Rails::Middleware::Validator` into your application's middleware stack. This middleware performs the following actions for incoming **POST** requests with `Content-Type: application/json`:
84
+ The gem automatically inserts `JSONRPC_Rails::Middleware::Validator` into your application's middleware stack. This middleware performs the following actions for incoming **POST** requests with `Content-Type: application/json`:
85
85
 
86
86
  1. **Parses** the JSON body. Returns a JSON-RPC `Parse error (-32700)` if parsing fails.
87
87
  2. **Validates** the structure against the JSON-RPC 2.0 specification (single or batch). It performs strict validation, ensuring `jsonrpc: "2.0"`, a string `method`, optional `params` (array/object), optional `id` (string/number/null), and **no extraneous keys**. Returns a JSON-RPC `Invalid Request (-32600)` error if validation fails. **Note:** For batch requests, if *any* individual request within the batch is structurally invalid, the entire batch is rejected with a single `Invalid Request (-32600)` error.
data/lib/jsonrpc-rails.rb CHANGED
@@ -7,7 +7,5 @@ require_relative "json_rpc/request"
7
7
  require_relative "json_rpc/response"
8
8
  require_relative "json_rpc/notification"
9
9
 
10
- # Define the top-level module for the gem (optional, but good practice)
11
- module JSON_RPC_Rails
12
- # You might add gem-level configuration or methods here if needed later.
10
+ module JSONRPC_Rails
13
11
  end
@@ -1,8 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "json"
4
+ require "active_support/json"
4
5
 
5
- module JSON_RPC_Rails
6
+ module JSONRPC_Rails
6
7
  module Middleware
7
8
  # Rack middleware to strictly validate incoming JSON-RPC 2.0 requests.
8
9
  # It checks for correct Content-Type, parses JSON, and validates the structure
@@ -17,40 +18,54 @@ module JSON_RPC_Rails
17
18
  # Other valid JSON payloads (e.g., strings, numbers, booleans, null) are passed through.
18
19
  class Validator
19
20
  CONTENT_TYPE = "application/json"
20
- ENV_PAYLOAD_KEY = "jsonrpc.payload"
21
+ ENV_PAYLOAD_KEY = :"jsonrpc.payload"
21
22
 
22
23
  def initialize(app)
23
24
  @app = app
24
25
  end
25
26
 
26
27
  def call(env)
27
- request = Rack::Request.new(env)
28
-
29
28
  # Only process POST requests with the correct Content-Type
30
- unless request.post? && request.content_type&.start_with?(CONTENT_TYPE)
31
- return @app.call(env)
32
- end
29
+ return @app.call(env) unless env["REQUEST_METHOD"] == "POST" &&
30
+ env["CONTENT_TYPE"]&.start_with?(CONTENT_TYPE)
33
31
 
34
32
  # Read and parse the request body
35
- body = request.body.read
36
- request.body.rewind # Rewind body for potential downstream middleware/apps
33
+ # Safely read and rewind
34
+ body = env["rack.input"].read
35
+ env["rack.input"].rewind
37
36
  payload = parse_json(body)
38
37
 
39
38
  # Handle JSON parsing errors
40
- return jsonrpc_error_response(:parse_error) unless payload
41
-
42
- # Only attempt JSON-RPC validation if payload is a Hash or Array
43
- unless payload.is_a?(Hash) || payload.is_a?(Array)
44
- # Pass through other valid JSON types (string, number, boolean, null)
45
- return @app.call(env)
39
+ # If parsing fails (returns nil), pass through
40
+ return @app.call(env) unless payload
41
+
42
+ # Determine if we should proceed with strict validation based on payload type and content
43
+ should_validate = false
44
+ is_batch = false
45
+
46
+ case payload
47
+ when Hash
48
+ # Validate single Hash only if 'jsonrpc' key is present
49
+ should_validate = payload.key?("jsonrpc")
50
+ is_batch = false
51
+ when Array
52
+ # Validate Array only if ALL elements are Hashes AND at least one has 'jsonrpc' key
53
+ all_hashes = payload.all? { |el| el.is_a?(Hash) }
54
+ any_jsonrpc = payload.any? { |el| el.is_a?(Hash) && el.key?("jsonrpc") }
55
+ if all_hashes && any_jsonrpc
56
+ should_validate = true
57
+ is_batch = true
58
+ end
59
+ # Note: Empty arrays or arrays not meeting the criteria will pass through
46
60
  end
47
61
 
48
- # Payload is Hash or Array, proceed with JSON-RPC validation
49
- is_batch = payload.is_a?(Array)
50
- # validate_batch handles the empty array case internally now
62
+ # If conditions for validation are not met, pass through
63
+ return @app.call(env) unless should_validate
64
+
65
+ # --- Proceed with strict validation ---
51
66
  validation_result, _ = is_batch ? validate_batch(payload) : validate_single(payload)
52
67
 
53
- # If validation failed, return the generated error response
68
+ # If strict validation failed (e.g., wrong version, missing method, invalid batch element), return the error
54
69
  return validation_result unless validation_result == :valid
55
70
 
56
71
  # Store the validated payload (original structure) in env for the controller
@@ -62,14 +77,13 @@ module JSON_RPC_Rails
62
77
 
63
78
  private
64
79
 
65
- # Removed jsonrpc_payload? method
66
-
67
- # Parses the JSON body string. Returns parsed data or nil on failure.
80
+ # Parses the JSON body string using ActiveSupport::JSON. Returns parsed data or nil on failure.
68
81
  def parse_json(body)
69
82
  return nil if body.nil? || body.strip.empty?
70
83
 
71
- JSON.parse(body)
72
- rescue JSON::ParserError
84
+ ActiveSupport::JSON.decode(body)
85
+ rescue ActiveSupport::JSON.parse_error
86
+ # Return nil if parsing fails, allowing the request to pass through
73
87
  nil
74
88
  end
75
89
 
@@ -92,8 +106,8 @@ module JSON_RPC_Rails
92
106
  return false
93
107
  end
94
108
 
95
- # Optional 'id' must be a String, Number (Integer/Float), or Null if present
96
- if obj.key?("id") && ![ String, Integer, Float, NilClass ].include?(obj["id"].class)
109
+ # Optional 'id' must be a String, Number (Integer), or Null if present
110
+ if obj.key?("id") && ![ String, Integer, NilClass ].include?(obj["id"].class)
97
111
  return false
98
112
  end
99
113
 
@@ -152,11 +166,10 @@ module JSON_RPC_Rails
152
166
  JSON_RPC::JsonRpcError.new(error_type)
153
167
  end
154
168
 
155
- response_body = {
156
- jsonrpc: "2.0",
169
+ response_body = JSON_RPC::Response.new(
170
+ id: nil, # Middleware errors have null id
157
171
  error: error_obj.to_h,
158
- id: nil # Middleware errors have null id
159
- }.to_json
172
+ ).to_json
160
173
 
161
174
  [
162
175
  status,
@@ -1,12 +1,12 @@
1
1
  require_relative "middleware/validator"
2
2
 
3
- module JSON_RPC_Rails
3
+ module JSONRPC_Rails
4
4
  # Use Rails::Railtie to integrate with the Rails application
5
5
  class Railtie < Rails::Railtie
6
6
  # Insert the JSON-RPC Validator middleware early in the stack.
7
7
  # Inserting before Rack::Sendfile, which is typically present early in the stack.
8
8
  initializer "jsonrpc-rails.add_validator_middleware" do |app|
9
- app.middleware.use JSON_RPC_Rails::Middleware::Validator
9
+ app.middleware.use JSONRPC_Rails::Middleware::Validator
10
10
  end
11
11
 
12
12
  initializer "jsonrpc-rails.add_renderers" do
@@ -1,3 +1,3 @@
1
- module JSON_RPC_Rails
2
- VERSION = "0.1.0"
1
+ module JSONRPC_Rails
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonrpc-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Abdelkader Boudih
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-03-27 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: railties
@@ -65,7 +65,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
65
  - !ruby/object:Gem::Version
66
66
  version: '0'
67
67
  requirements: []
68
- rubygems_version: 3.6.5
68
+ rubygems_version: 3.6.7
69
69
  specification_version: 4
70
70
  summary: A Railtie-based gem that brings JSON-RPC 2.0 support to your Rails application.
71
71
  test_files: []