Skip to content

Commit 5a06862

Browse files
authored
Merge pull request #70 from caifara/master
Make middleware thread safe
2 parents 6246be0 + afa7fc4 commit 5a06862

File tree

2 files changed

+83
-53
lines changed

2 files changed

+83
-53
lines changed

lib/inertia_rails/middleware.rb

Lines changed: 65 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -5,79 +5,91 @@ def initialize(app)
55
end
66

77
def call(env)
8-
@env = env
8+
InertiaRailsRequest.new(@app, env)
9+
.response
10+
end
911

10-
status, headers, body = @app.call(env)
11-
request = ActionDispatch::Request.new(env)
12+
class InertiaRailsRequest
13+
def initialize(app, env)
14+
@app = app
15+
@env = env
16+
end
1217

13-
::InertiaRails.reset!
18+
def response
19+
status, headers, body = @app.call(@env)
20+
request = ActionDispatch::Request.new(@env)
1421

15-
# Inertia errors are added to the session via redirect_to
16-
request.session.delete(:inertia_errors) unless keep_inertia_errors?(status)
22+
::InertiaRails.reset!
1723

18-
status = 303 if inertia_non_post_redirect?(status)
24+
# Inertia errors are added to the session via redirect_to
25+
request.session.delete(:inertia_errors) unless keep_inertia_errors?(status)
1926

20-
return stale_inertia_get? ? force_refresh(request) : [status, headers, body]
21-
end
27+
status = 303 if inertia_non_post_redirect?(status)
2228

23-
private
29+
stale_inertia_get? ? force_refresh(request) : [status, headers, body]
30+
end
2431

25-
def keep_inertia_errors?(status)
26-
redirect_status?(status) || stale_inertia_request?
27-
end
32+
private
2833

29-
def stale_inertia_request?
30-
inertia_request? && version_stale?
31-
end
34+
def keep_inertia_errors?(status)
35+
redirect_status?(status) || stale_inertia_request?
36+
end
3237

33-
def redirect_status?(status)
34-
[301, 302].include? status
35-
end
38+
def stale_inertia_request?
39+
inertia_request? && version_stale?
40+
end
3641

37-
def non_get_redirectable_method?
38-
['PUT', 'PATCH', 'DELETE'].include? request_method
39-
end
42+
def redirect_status?(status)
43+
[301, 302].include? status
44+
end
4045

41-
def inertia_non_post_redirect?(status)
42-
inertia_request? && redirect_status?(status) && non_get_redirectable_method?
43-
end
46+
def non_get_redirectable_method?
47+
['PUT', 'PATCH', 'DELETE'].include? request_method
48+
end
4449

45-
def stale_inertia_get?
46-
get? && stale_inertia_request?
47-
end
50+
def inertia_non_post_redirect?(status)
51+
inertia_request? && redirect_status?(status) && non_get_redirectable_method?
52+
end
4853

49-
def get?
50-
request_method == 'GET'
51-
end
54+
def stale_inertia_get?
55+
get? && stale_inertia_request?
56+
end
5257

53-
def request_method
54-
@env['REQUEST_METHOD']
55-
end
58+
def get?
59+
request_method == 'GET'
60+
end
5661

57-
def inertia_version
58-
@env['HTTP_X_INERTIA_VERSION']
59-
end
62+
def request_method
63+
@env['REQUEST_METHOD']
64+
end
6065

61-
def inertia_request?
62-
@env['HTTP_X_INERTIA'].present?
63-
end
66+
def inertia_version
67+
@env['HTTP_X_INERTIA_VERSION']
68+
end
6469

65-
def version_stale?
66-
sent_version != saved_version
67-
end
70+
def inertia_request?
71+
@env['HTTP_X_INERTIA'].present?
72+
end
6873

69-
def sent_version
70-
return nil if inertia_version.nil?
71-
InertiaRails.version.is_a?(Numeric) ? inertia_version.to_f : inertia_version
72-
end
74+
def version_stale?
75+
sent_version != saved_version
76+
end
7377

74-
def saved_version
75-
InertiaRails.version.is_a?(Numeric) ? InertiaRails.version.to_f : InertiaRails.version
76-
end
78+
def sent_version
79+
return nil if inertia_version.nil?
80+
81+
InertiaRails.version.is_a?(Numeric) ? inertia_version.to_f : inertia_version
82+
end
7783

78-
def force_refresh(request)
79-
request.flash.keep
80-
Rack::Response.new('', 409, {'X-Inertia-Location' => request.original_url}).finish
84+
def saved_version
85+
InertiaRails.version.is_a?(Numeric) ? InertiaRails.version.to_f : InertiaRails.version
86+
end
87+
88+
def force_refresh(request)
89+
request.flash.keep
90+
Rack::Response.new('', 409, {'X-Inertia-Location' => request.original_url}).finish
91+
end
8192
end
8293
end
8394
end
95+

spec/inertia/middleware_spec.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,24 @@
2828

2929
it { is_expected.to eq 303 }
3030
end
31+
32+
it 'is thread safe' do
33+
delete_request_proc = -> { delete redirect_test_path, headers: { 'X-Inertia' => true } }
34+
get_request_proc = -> { get empty_test_path }
35+
36+
statusses = []
37+
38+
threads = []
39+
40+
100.times do
41+
threads << Thread.new { statusses << delete_request_proc.call }
42+
threads << Thread.new { get_request_proc.call }
43+
end
44+
45+
threads.each(&:join)
46+
47+
expect(statusses.uniq).to eq([303])
48+
end
3149
end
3250

3351
context 'a request not originating from inertia' do

0 commit comments

Comments
 (0)