Class: Rollbar::Middleware::Js
Overview
Middleware to inject the rollbar.js snippet into a 200 html response
Constant Summary
collapse
- JS_IS_INJECTED_KEY =
'rollbar.js_is_injected'
- SNIPPET =
File.read(File.expand_path('../../../../data/rollbar.snippet.js', __FILE__))
RequestDataExtractor::ALLOWED_BODY_PARSEABLE_METHODS, RequestDataExtractor::ALLOWED_HEADERS_REGEX
Instance Attribute Summary collapse
Instance Method Summary
collapse
-
#add_js(env, response) ⇒ Object
-
#add_js?(env, headers) ⇒ Boolean
-
#add_person_data(js_config, env) ⇒ Object
-
#append_nonce? ⇒ Boolean
-
#attachment?(headers) ⇒ Boolean
-
#build_body_with_js(env, body, head_open_end) ⇒ Object
-
#build_response(env, app_result, response_string) ⇒ Object
-
#call(env) ⇒ Object
-
#close_old_response(response) ⇒ Object
-
#config_js_tag(env) ⇒ Object
-
#enabled? ⇒ Boolean
-
#find_end_after_regex(body, regex) ⇒ Object
-
#find_insertion_point(body) ⇒ Object
-
#html?(headers) ⇒ Boolean
-
#html_safe_if_needed(string) ⇒ Object
-
#initialize(app, config) ⇒ Js
constructor
-
#join_body(response) ⇒ Object
-
#js_snippet ⇒ Object
-
#script_tag(content, env) ⇒ Object
-
#snippet_js_tag(env) ⇒ Object
-
#streaming?(env) ⇒ Boolean
#extract_person_data_from_controller, #extract_request_data_from_rack, #scrub_params, #scrub_url
Constructor Details
#initialize(app, config) ⇒ Js
Returns a new instance of Js.
19
20
21
22
|
# File 'lib/rollbar/middleware/js.rb', line 19
def initialize(app, config)
@app = app
@config = config
end
|
Instance Attribute Details
#app ⇒ Object
Returns the value of attribute app.
13
14
15
|
# File 'lib/rollbar/middleware/js.rb', line 13
def app
@app
end
|
#config ⇒ Object
Returns the value of attribute config.
14
15
16
|
# File 'lib/rollbar/middleware/js.rb', line 14
def config
@config
end
|
Instance Method Details
#add_js(env, response) ⇒ Object
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
# File 'lib/rollbar/middleware/js.rb', line 62
def add_js(env, response)
body = join_body(response)
close_old_response(response)
return nil unless body
insert_after_idx = find_insertion_point(body)
return nil unless insert_after_idx
build_body_with_js(env, body, insert_after_idx)
rescue => e
Rollbar.log_error("[Rollbar] Rollbar.js could not be added because #{e} exception")
nil
end
|
#add_js?(env, headers) ⇒ Boolean
43
44
45
46
|
# File 'lib/rollbar/middleware/js.rb', line 43
def add_js?(env, )
enabled? && !env[JS_IS_INJECTED_KEY] &&
html?() && !attachment?() && !streaming?(env)
end
|
#add_person_data(js_config, env) ⇒ Object
124
125
126
127
128
129
130
131
|
# File 'lib/rollbar/middleware/js.rb', line 124
def add_person_data(js_config, env)
person_data = (env)
return if person_data && person_data.empty?
js_config[:payload] ||= {}
js_config[:payload][:person] = person_data if person_data
end
|
#append_nonce? ⇒ Boolean
157
158
159
160
161
162
|
# File 'lib/rollbar/middleware/js.rb', line 157
def append_nonce?
defined?(::SecureHeaders) && ::SecureHeaders.respond_to?(:content_security_policy_script_nonce) &&
defined?(::SecureHeaders::Configuration) &&
!::SecureHeaders::Configuration.get.csp.opt_out? &&
!::SecureHeaders::Configuration.get.current_csp[:script_src].to_a.include?("'unsafe-inline'")
end
|
#attachment?(headers) ⇒ Boolean
52
53
54
|
# File 'lib/rollbar/middleware/js.rb', line 52
def attachment?()
['Content-Disposition'].to_s.include?('attachment')
end
|
#build_body_with_js(env, body, head_open_end) ⇒ Object
87
88
89
90
91
92
|
# File 'lib/rollbar/middleware/js.rb', line 87
def build_body_with_js(env, body, head_open_end)
return body unless head_open_end
body[0..head_open_end] << config_js_tag(env) << snippet_js_tag(env) <<
body[head_open_end + 1..-1]
end
|
#build_response(env, app_result, response_string) ⇒ Object
77
78
79
80
81
82
83
84
85
|
# File 'lib/rollbar/middleware/js.rb', line 77
def build_response(env, app_result, response_string)
return app_result unless response_string
env[JS_IS_INJECTED_KEY] = true
response = ::Rack::Response.new(response_string, app_result[0],
app_result[1])
response.finish
end
|
#call(env) ⇒ Object
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
# File 'lib/rollbar/middleware/js.rb', line 24
def call(env)
app_result = app.call(env)
begin
return app_result unless add_js?(env, app_result[1])
response_string = add_js(env, app_result[2])
build_response(env, app_result, response_string)
rescue => e
Rollbar.log_error("[Rollbar] Rollbar.js could not be added because #{e} exception")
app_result
end
end
|
#close_old_response(response) ⇒ Object
112
113
114
|
# File 'lib/rollbar/middleware/js.rb', line 112
def close_old_response(response)
response.close if response.respond_to?(:close)
end
|
#config_js_tag(env) ⇒ Object
116
117
118
119
120
121
122
|
# File 'lib/rollbar/middleware/js.rb', line 116
def config_js_tag(env)
js_config = Rollbar::Util.deep_copy(config[:options])
add_person_data(js_config, env)
script_tag("var _rollbarConfig = #{js_config.to_json};", env)
end
|
#enabled? ⇒ Boolean
39
40
41
|
# File 'lib/rollbar/middleware/js.rb', line 39
def enabled?
!!config[:enabled]
end
|
#find_end_after_regex(body, regex) ⇒ Object
100
101
102
103
|
# File 'lib/rollbar/middleware/js.rb', line 100
def find_end_after_regex(body, regex)
open_idx = body.index(regex)
body.index('>', open_idx) if open_idx
end
|
#find_insertion_point(body) ⇒ Object
94
95
96
97
98
|
# File 'lib/rollbar/middleware/js.rb', line 94
def find_insertion_point(body)
find_end_after_regex(body, /<meta\s*charset=/i) ||
find_end_after_regex(body, /<meta\s*http-equiv="Content-Type"/i) ||
find_end_after_regex(body, /<head\W/i)
end
|
#html?(headers) ⇒ Boolean
48
49
50
|
# File 'lib/rollbar/middleware/js.rb', line 48
def html?()
['Content-Type'] && ['Content-Type'].include?('text/html')
end
|
#html_safe_if_needed(string) ⇒ Object
152
153
154
155
|
# File 'lib/rollbar/middleware/js.rb', line 152
def html_safe_if_needed(string)
string = string.html_safe if string.respond_to?(:html_safe)
string
end
|
#join_body(response) ⇒ Object
105
106
107
108
109
110
|
# File 'lib/rollbar/middleware/js.rb', line 105
def join_body(response)
response.to_enum.reduce('') do |acc, fragment|
acc << fragment.to_s
acc
end
end
|
#js_snippet ⇒ Object
137
138
139
|
# File 'lib/rollbar/middleware/js.rb', line 137
def js_snippet
SNIPPET
end
|
#script_tag(content, env) ⇒ Object
141
142
143
144
145
146
147
148
149
150
|
# File 'lib/rollbar/middleware/js.rb', line 141
def script_tag(content, env)
if append_nonce?
nonce = ::SecureHeaders.content_security_policy_script_nonce(::Rack::Request.new(env))
script_tag_content = "\n<script type=\"text/javascript\" nonce=\"#{nonce}\">#{content}</script>"
else
script_tag_content = "\n<script type=\"text/javascript\">#{content}</script>"
end
html_safe_if_needed(script_tag_content)
end
|
#snippet_js_tag(env) ⇒ Object
133
134
135
|
# File 'lib/rollbar/middleware/js.rb', line 133
def snippet_js_tag(env)
script_tag(js_snippet, env)
end
|
#streaming?(env) ⇒ Boolean
56
57
58
59
60
|
# File 'lib/rollbar/middleware/js.rb', line 56
def streaming?(env)
return false unless defined?(ActionController::Live)
env['action_controller.instance'].class.included_modules.include?(ActionController::Live)
end
|