@@ -7,18 +7,18 @@ module Middleware
77 class Stack
88 extend Forwardable
99 class Middleware
10- extend Forwardable
11-
1210 attr_reader :args , :block , :klass
1311
14- def_delegators :klass , :name
15-
16- def initialize ( klass , *args , &block )
12+ def initialize ( klass , args , block )
1713 @klass = klass
1814 @args = args
1915 @block = block
2016 end
2117
18+ def name
19+ klass . name
20+ end
21+
2222 def ==( other )
2323 case other
2424 when Middleware
@@ -32,7 +32,11 @@ def inspect
3232 klass . to_s
3333 end
3434
35- def use_in ( builder )
35+ def build ( builder )
36+ # we need to force the ruby2_keywords_hash for middlewares that initialize contains keywords
37+ # like ActionDispatch::RequestId since middleware arguments are serialized
38+ # https://rubyapi.org/3.4/o/hash#method-c-ruby2_keywords_hash
39+ args [ -1 ] = Hash . ruby2_keywords_hash ( args [ -1 ] ) if args . last . is_a? ( Hash ) && Hash . respond_to? ( :ruby2_keywords_hash )
3640 builder . use ( klass , *args , &block )
3741 end
3842 end
@@ -48,51 +52,50 @@ def initialize
4852 @others = [ ]
4953 end
5054
51- def insert ( index , *args , &block )
55+ def insert ( index , klass , *args , &block )
5256 index = assert_index ( index , :before )
53- middleware = self . class ::Middleware . new ( *args , &block )
54- middlewares . insert ( index , middleware )
57+ middlewares . insert ( index , self . class ::Middleware . new ( klass , args , block ) )
5558 end
56- ruby2_keywords :insert if respond_to? ( :ruby2_keywords , true )
5759
5860 alias insert_before insert
5961
6062 def insert_after ( index , *args , &block )
6163 index = assert_index ( index , :after )
6264 insert ( index + 1 , *args , &block )
6365 end
64- ruby2_keywords :insert_after if respond_to? ( :ruby2_keywords , true )
6566
66- def use ( ... )
67- middleware = self . class ::Middleware . new ( ... )
67+ def use ( klass , * args , & block )
68+ middleware = self . class ::Middleware . new ( klass , args , block )
6869 middlewares . push ( middleware )
6970 end
7071
7172 def merge_with ( middleware_specs )
72- middleware_specs . each do |operation , *args |
73+ middleware_specs . each do |operation , klass , *args |
7374 if args . last . is_a? ( Proc )
7475 last_proc = args . pop
75- public_send ( operation , *args , &last_proc )
76+ public_send ( operation , klass , *args , &last_proc )
7677 else
77- public_send ( operation , *args )
78+ public_send ( operation , klass , *args )
7879 end
7980 end
8081 end
8182
8283 # @return [Rack::Builder] the builder object with our middlewares applied
83- def build ( builder = Rack ::Builder . new )
84- others . shift ( others . size ) . each { |m | merge_with ( m ) }
85- middlewares . each do |m |
86- m . use_in ( builder )
84+ def build
85+ Rack ::Builder . new . tap do |builder |
86+ others . shift ( others . size ) . each { |m | merge_with ( m ) }
87+ middlewares . each do |m |
88+ m . build ( builder )
89+ end
8790 end
88- builder
8991 end
9092
9193 # @description Add middlewares with :use operation to the stack. Store others with :insert_* operation for later
9294 # @param [Array] other_specs An array of middleware specifications (e.g. [[:use, klass], [:insert_before, *args]])
9395 def concat ( other_specs )
94- @others << Array ( other_specs ) . reject { |o | o . first == :use }
95- merge_with ( Array ( other_specs ) . select { |o | o . first == :use } )
96+ use , not_use = other_specs . partition { |o | o . first == :use }
97+ others << not_use
98+ merge_with ( use )
9699 end
97100
98101 protected
0 commit comments