1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
require "active_support/inflector/methods"
module ActionDispatch
class MiddlewareStack < Array
class Middleware
def self.new(klass, *args, &block)
if klass.is_a?(self)
klass
else
super
end
end
attr_reader :args, :block
def initialize(klass, *args, &block)
@klass = klass
options = args.extract_options!
if options.has_key?(:if)
@conditional = options.delete(:if)
else
@conditional = true
end
args << options unless options.empty?
@args = args
@block = block
end
def klass
if @klass.respond_to?(:new)
@klass
elsif @klass.respond_to?(:call)
@klass.call
else
ActiveSupport::Inflector.constantize(@klass.to_s)
end
end
def active?
return false unless klass
if @conditional.respond_to?(:call)
@conditional.call
else
@conditional
end
end
def ==(middleware)
case middleware
when Middleware
klass == middleware.klass
when Class
klass == middleware
else
if lazy_compare?(@klass) && lazy_compare?(middleware)
normalize(@klass) == normalize(middleware)
else
klass.name == middleware.to_s
end
end
end
def inspect
klass.to_s
end
def build(app)
if block
klass.new(app, *build_args, &block)
else
klass.new(app, *build_args)
end
end
private
def lazy_compare?(object)
object.is_a?(String) || object.is_a?(Symbol)
end
def normalize(object)
object.to_s.strip.sub(/^::/, '')
end
def build_args
Array(args).map { |arg| arg.respond_to?(:call) ? arg.call : arg }
end
end
def initialize(*args, &block)
super(*args)
block.call(self) if block_given?
end
def insert(index, *args, &block)
index = self.index(index) unless index.is_a?(Integer)
middleware = Middleware.new(*args, &block)
super(index, middleware)
end
alias_method :insert_before, :insert
def insert_after(index, *args, &block)
i = index.is_a?(Integer) ? index : self.index(index)
raise "No such middleware to insert after: #{index.inspect}" unless i
insert(i + 1, *args, &block)
end
def swap(target, *args, &block)
insert_before(target, *args, &block)
delete(target)
end
def use(*args, &block)
middleware = Middleware.new(*args, &block)
push(middleware)
end
def active
find_all { |middleware| middleware.active? }
end
def build(app = nil, &blk)
app ||= blk
raise "MiddlewareStack#build requires an app" unless app
active.reverse.inject(app) { |a, e| e.build(a) }
end
end
end
|