-
Notifications
You must be signed in to change notification settings - Fork 601
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
browser monitoring injection logic hardening #2465
The head ref may contain hidden characters: "nettleseroverv\u00E5king"
Conversation
These changes introduce hardening to the logic that determines whether or not to inject the browser agent script tag. In particular, the following 2 issues have been addressed: 1. If either `#traced_call` or `#should_instrument?` encounter any exceptions, these exceptions should be handled and logged without impacting the observed web application. 2. Allow a response headers hash to use symbols for values. Closes #2462
NOTE to @kaylareopelle and @hannahramadan: I was worried about introducing performance overhead while supporting hash values as symbols. After some benchmarking, the solution I came up with is to use Here is the benchmarking code in question: require 'benchmark'
SYMBOLS = { :'an/example' => :'a/value',
:'another-example' => :'another-value',
:content_type => :'text/html',
:traceparent => :'00-da8bc8cc6d062849b0efcf3c169afb5a-7d3efb1b173fecfa-01',
:tracestate => :'33@nr=0-0-33-2827902-7d3efb1b173fecfa-e8b91a159289ff74-1-1.234567-1518469636035' }
STRINGS = SYMBOLS.each_with_object({}) { |(k,v), h| h[k.to_s] = v.to_s }
TEXT_HTML = 'text/html'
TEXT_HTML_PATTERN = %r{text/html}.freeze
TIMES = 1_000_000
puts 'Finding a speedy way to test symbol text inclusion...'
Benchmark.bm do |x|
x.report 'baseline' do
TIMES.times do
# use STRINGS twice, as SYMBOLS will error out
STRINGS.each { |k, v| STRINGS[k].include?(TEXT_HTML) }
STRINGS.each { |k, v| STRINGS[k].include?(TEXT_HTML) }
end
end
x.report '#to_s' do
TIMES.times do
SYMBOLS.each { |k, v| SYMBOLS[k].to_s.include?(TEXT_HTML) }
STRINGS.each { |k, v| STRINGS[k].to_s.include?(TEXT_HTML) }
end
end
x.report '#match? with pattern' do
TIMES.times do
SYMBOLS.each { |k, v| SYMBOLS[k].match?(TEXT_HTML_PATTERN) }
STRINGS.each { |k, v| STRINGS[k].match?(TEXT_HTML_PATTERN) }
end
end
x.report '#match? with string' do
TIMES.times do
SYMBOLS.each { |k, v| SYMBOLS[k].match?(TEXT_HTML) }
STRINGS.each { |k, v| STRINGS[k].match?(TEXT_HTML) }
end
end
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really like these updates, @fallwith. Especially with the performance boost!
I think we might want a changelog entry for this. What do you think?
Sounds good. Let me figure out what's going on with these unit tests that aren't happy with the new |
- we want to rescue all exceptions spawning from checks to determine whether the browser agent should be inserted, but we can't rescue `#traced_call` without breaking expected workflows - add a unit test for a hash with a symbol as the content type value - added a README.md entry
Ah ok. I was rescuing too far up the chain. We want legitimate issues to be surfaced and not rescued. With the latest commit we're still rescuing all headers parsing and other determinations of whether the browser agent should be inserted. The tests should pass now and a changelog entry has been added. |
use `#send` in the test
SimpleCov Report
|
ATTACHMENT = 'attachment'.freeze | ||
TEXT_HTML = 'text/html'.freeze | ||
ATTACHMENT = /attachment/.freeze | ||
TEXT_HTML = %r{text/html}.freeze |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TIL about %r{}
! Nice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's most useful for cases like this where there's a literal forward slash character involved in the pattern.
@@ -65,6 +65,10 @@ def should_instrument?(env, status, headers) | |||
html?(headers) && | |||
!attachment?(headers) && | |||
!streaming?(env, headers) | |||
rescue StandardError => e |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could do rescue => e
here but as I'm also cool with it as-is!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aha! You and I were talking about this one recently and I was trying to figure out where my knowledge of a related best practice was coming from.
It turns out that RuboCop prefers it this way, with a named class. See Style/RescueStandardError. For some reason this project has (temporarily?) disabled that cop, but I still heed its advice and would prefer to stick with a named class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ser bra ut!
These changes introduce hardening to the logic that determines whether or not to inject the browser agent script tag.
In particular, the following 2 issues have been addressed:
#traced_call
or#should_instrument?
encounter any exceptions, these exceptions should be handled and logged without impacting the observed web application.Closes #2462