sqreen 1.18.3.beta1 → 1.18.3.beta2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +0 -5
- data/lib/sqreen/actions.rb +11 -337
- data/lib/sqreen/actions/base.rb +110 -0
- data/lib/sqreen/actions/block_ip.rb +32 -0
- data/lib/sqreen/actions/block_user.rb +44 -0
- data/lib/sqreen/actions/ip_range_indexed_action_class.rb +36 -0
- data/lib/sqreen/actions/ip_ranges_index.rb +36 -0
- data/lib/sqreen/actions/redirect_ip.rb +40 -0
- data/lib/sqreen/actions/redirect_user.rb +45 -0
- data/lib/sqreen/actions/repository.rb +24 -0
- data/lib/sqreen/actions/unknown_action_type.rb +16 -0
- data/lib/sqreen/actions/user_action_class.rb +41 -0
- data/lib/sqreen/agent.rb +4 -1
- data/lib/sqreen/attack_blocked.rb +17 -0
- data/lib/sqreen/binding_accessor.rb +9 -102
- data/lib/sqreen/binding_accessor/path_elem.rb +8 -0
- data/lib/sqreen/binding_accessor/transforms.rb +107 -0
- data/lib/sqreen/capped_queue.rb +2 -0
- data/lib/sqreen/{callbacks.rb → cb.rb} +1 -53
- data/lib/sqreen/{callback_tree.rb → cb_tree.rb} +2 -2
- data/lib/sqreen/condition_evaluator.rb +22 -5
- data/lib/sqreen/configuration.rb +3 -0
- data/lib/sqreen/default_cb.rb +20 -0
- data/lib/sqreen/deferred_logger.rb +63 -0
- data/lib/sqreen/deliveries.rb +10 -0
- data/lib/sqreen/deliveries/batch.rb +7 -1
- data/lib/sqreen/deliveries/simple.rb +5 -0
- data/lib/sqreen/dependency/rails.rb +4 -0
- data/lib/sqreen/dependency/sinatra.rb +4 -0
- data/lib/sqreen/error_handling_middleware.rb +30 -0
- data/lib/sqreen/event.rb +2 -0
- data/lib/sqreen/events/attack.rb +2 -0
- data/lib/sqreen/events/request_record.rb +11 -56
- data/lib/sqreen/exception.rb +9 -40
- data/lib/sqreen/formatter_with_tid.rb +45 -0
- data/lib/sqreen/framework_cb.rb +28 -0
- data/lib/sqreen/frameworks.rb +7 -0
- data/lib/sqreen/frameworks/generic.rb +5 -1
- data/lib/sqreen/frameworks/rails.rb +2 -0
- data/lib/sqreen/frameworks/request_recorder.rb +3 -0
- data/lib/sqreen/frameworks/sinatra.rb +2 -0
- data/lib/sqreen/frameworks/sqreen_test.rb +2 -0
- data/lib/sqreen/instrumentation.rb +5 -5
- data/lib/sqreen/invalid_signature_exception.rb +8 -0
- data/lib/{sqreen-alt.rb → sqreen/js.rb} +6 -1
- data/lib/sqreen/js/call_context.rb +10 -0
- data/lib/sqreen/js/context_pool.rb +60 -0
- data/lib/sqreen/js/exec_js_runnable.rb +20 -0
- data/lib/sqreen/js/execjs_adapter.rb +6 -47
- data/lib/sqreen/js/executable_js.rb +12 -0
- data/lib/sqreen/js/js_service.rb +2 -22
- data/lib/sqreen/js/js_service_adapter.rb +18 -0
- data/lib/sqreen/js/mini_racer_adapter.rb +6 -180
- data/lib/sqreen/js/mini_racer_executable_js.rb +142 -0
- data/lib/sqreen/js/thread_local_exec_js_runnable.rb +47 -0
- data/lib/sqreen/log.rb +8 -188
- data/lib/sqreen/logger.rb +83 -0
- data/lib/sqreen/metrics_store.rb +3 -11
- data/lib/sqreen/metrics_store/already_registered_metric.rb +11 -0
- data/lib/sqreen/metrics_store/unknown_metric.rb +11 -0
- data/lib/sqreen/metrics_store/unregistered_metric.rb +11 -0
- data/lib/sqreen/middleware.rb +0 -44
- data/lib/sqreen/mono_time.rb +2 -0
- data/lib/sqreen/node.rb +44 -0
- data/lib/sqreen/not_implemented_yet.rb +8 -0
- data/lib/sqreen/null_logger.rb +24 -0
- data/lib/sqreen/payload_creator.rb +2 -19
- data/lib/sqreen/payload_creator/header_section.rb +28 -0
- data/lib/sqreen/prefix.rb +33 -0
- data/lib/sqreen/rails_middleware.rb +14 -0
- data/lib/sqreen/remote_command.rb +1 -8
- data/lib/sqreen/remote_command/failure_output.rb +11 -0
- data/lib/sqreen/rules.rb +32 -2
- data/lib/sqreen/{rule_attributes.rb → rules/attrs.rb} +0 -0
- data/lib/sqreen/{rules_callbacks/sdk_auth_track.rb → rules/auth_track_cb.rb} +2 -2
- data/lib/sqreen/{rules_callbacks/binding_accessor_matcher.rb → rules/binding_accessor_matcher_cb.rb} +4 -8
- data/lib/sqreen/{rules_callbacks → rules}/binding_accessor_metrics.rb +1 -1
- data/lib/sqreen/{rules_callbacks/blacklist_ips.rb → rules/blacklist_ips_cb.rb} +3 -2
- data/lib/sqreen/{rules_callbacks → rules}/count_http_codes.rb +2 -2
- data/lib/sqreen/{rules_callbacks/crawler_user_agent_matches.rb → rules/crawler_user_agent_matches_cb.rb} +1 -1
- data/lib/sqreen/{rules_callbacks/crawler_user_agent_matches_metrics.rb → rules/crawler_user_agent_matches_metrics_cb.rb} +1 -1
- data/lib/sqreen/{rules_callbacks/custom_error.rb → rules/custom_error_cb.rb} +1 -1
- data/lib/sqreen/{rules_callbacks/devise_auth_track.rb → rules/devise_auth_track_cb.rb} +2 -2
- data/lib/sqreen/{rules_callbacks/devise_signup_track.rb → rules/devise_signup_track_cb.rb} +2 -2
- data/lib/sqreen/{rules_callbacks/execjs.rb → rules/execjs_cb.rb} +49 -50
- data/lib/sqreen/{rules_callbacks/headers_insert.rb → rules/headers_insert_cb.rb} +1 -1
- data/lib/sqreen/{rules_callbacks → rules}/matcher_rule.rb +2 -2
- data/lib/sqreen/{rules_callbacks/not_found.rb → rules/not_found_cb.rb} +2 -2
- data/lib/sqreen/{rules_callbacks/rails_parameters.rb → rules/rails_parameters_cb.rb} +1 -1
- data/lib/sqreen/{rules_callbacks → rules}/record_request_context.rb +1 -1
- data/lib/sqreen/{rules_callbacks/regexp_rule.rb → rules/regexp_rule_cb.rb} +1 -1
- data/lib/sqreen/{rule_callback.rb → rules/rule_cb.rb} +2 -2
- data/lib/sqreen/{rules_callbacks → rules}/run_req_start_actions.rb +4 -2
- data/lib/sqreen/{rules_callbacks → rules}/run_user_actions.rb +1 -1
- data/lib/sqreen/{rules_callbacks/shell_env.rb → rules/shell_env_cb.rb} +1 -1
- data/lib/sqreen/{rules_callbacks/sdk_signup_track.rb → rules/signup_track_cb.rb} +2 -2
- data/lib/sqreen/{rules_callbacks → rules}/update_request_context.rb +1 -1
- data/lib/sqreen/{rules_callbacks/url_matches.rb → rules/url_matches_cb.rb} +1 -1
- data/lib/sqreen/{rules_callbacks/user_agent_matches.rb → rules/user_agent_matches_cb.rb} +1 -1
- data/lib/sqreen/{rules_callbacks/waf.rb → rules/waf_cb.rb} +7 -3
- data/lib/sqreen/{rules_callbacks/reflected_xss.rb → rules/xss_cb.rb} +10 -7
- data/lib/sqreen/run_when_called_cb.rb +21 -0
- data/lib/sqreen/sensitive_data_redactor.rb +111 -0
- data/lib/sqreen/signature_verifier.rb +20 -0
- data/lib/sqreen/sinatra_middleware.rb +14 -0
- data/lib/sqreen/{rules_signature.rb → sqreen_signed_verifier.rb} +5 -17
- data/lib/sqreen/token_invalid_exception.rb +8 -0
- data/lib/sqreen/token_not_found_exception.rb +9 -0
- data/lib/sqreen/trie.rb +3 -64
- data/lib/sqreen/unauthorized.rb +8 -0
- data/lib/sqreen/util.rb +2 -0
- data/lib/sqreen/util/capped_array.rb +30 -0
- data/lib/sqreen/util/capped_hash.rb +36 -0
- data/lib/sqreen/util/capped_string.rb +22 -0
- data/lib/sqreen/util/capper.rb +57 -0
- data/lib/sqreen/version.rb +1 -1
- data/lib/sqreen/waf_error.rb +18 -0
- metadata +85 -36
- data/lib/sqreen/rules_callbacks.rb +0 -36
- data/lib/sqreen/rules_callbacks/inspect_rule.rb +0 -25
@@ -0,0 +1,30 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/attack_blocked'
|
5
|
+
|
6
|
+
module Sqreen
|
7
|
+
class ErrorHandlingMiddleware
|
8
|
+
def initialize(app)
|
9
|
+
@app = app
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
@app.call(env)
|
14
|
+
rescue StandardError => e
|
15
|
+
sqreen_attack = nil
|
16
|
+
if e.is_a?(Sqreen::AttackBlocked)
|
17
|
+
sqreen_attack = e
|
18
|
+
elsif e.respond_to?(:original_exception) &&
|
19
|
+
e.original_exception.is_a?(Sqreen::AttackBlocked)
|
20
|
+
sqreen_attack = e.original_exception
|
21
|
+
end
|
22
|
+
|
23
|
+
if sqreen_attack && sqreen_attack.redirect_url
|
24
|
+
return [303, { 'Location' => sqreen_attack.redirect_url }, ['']]
|
25
|
+
end
|
26
|
+
|
27
|
+
raise
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/sqreen/event.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
2
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
3
3
|
|
4
|
+
# TODO: see sqreen/events
|
5
|
+
|
4
6
|
module Sqreen
|
5
7
|
# Master interface for point in time events (e.g. Attack, RemoteException)
|
6
8
|
class Event
|
data/lib/sqreen/events/attack.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
2
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
3
3
|
|
4
|
+
# TODO: sqreen/events
|
5
|
+
|
4
6
|
require 'json'
|
7
|
+
require 'sqreen/log'
|
5
8
|
require 'sqreen/event'
|
6
9
|
require 'sqreen/encoding_sanitizer'
|
10
|
+
require 'sqreen/sensitive_data_redactor'
|
7
11
|
|
8
12
|
module Sqreen
|
9
13
|
# When a request is deeemed worthy of being sent to the backend
|
@@ -70,7 +74,13 @@ module Sqreen
|
|
70
74
|
res = Sqreen::EncodingSanitizer.sanitize(res)
|
71
75
|
|
72
76
|
if @redactor
|
73
|
-
res[:request] = @redactor.redact(res[:request])
|
77
|
+
res[:request], redacted = @redactor.redact(res[:request])
|
78
|
+
if redacted.any? && res[:observed] && res[:observed][:attacks]
|
79
|
+
res[:observed][:attacks] = @redactor.redact_attacks!(res[:observed][:attacks], redacted)
|
80
|
+
end
|
81
|
+
if redacted.any? && res[:observed] && res[:observed][:sqreen_exceptions]
|
82
|
+
res[:observed][:sqreen_exceptions] = @redactor.redact_exceptions!(res[:observed][:sqreen_exceptions], redacted)
|
83
|
+
end
|
74
84
|
end
|
75
85
|
|
76
86
|
res
|
@@ -115,59 +125,4 @@ module Sqreen
|
|
115
125
|
nil
|
116
126
|
end
|
117
127
|
end
|
118
|
-
|
119
|
-
# For redacting sensitive data and avoid having it sent to our servers
|
120
|
-
class SensitiveDataRedactor
|
121
|
-
DEFAULT_SENSITIVE_KEYS = Set.new(%w[password secret passwd authorization api_key apikey access_token]).freeze
|
122
|
-
DEFAULT_REGEX = /\A(?:\d[ -]*?){13,16}\z/
|
123
|
-
MASK = '<Redacted by Sqreen>'.freeze
|
124
|
-
|
125
|
-
def self.from_config
|
126
|
-
keys = Sqreen.config_get(:strip_sensitive_keys)
|
127
|
-
if keys && keys.is_a?(String)
|
128
|
-
keys = keys.split(',')
|
129
|
-
else
|
130
|
-
keys = nil
|
131
|
-
end
|
132
|
-
|
133
|
-
regex = Sqreen.config_get(:strip_sensitive_regex)
|
134
|
-
if regex && regex.is_a?(String)
|
135
|
-
begin
|
136
|
-
regex = Regexp.compile(regex)
|
137
|
-
rescue RegexpError
|
138
|
-
Sqreen.log.warn("Invalid regular expression given in strip_sensitive_regex: #{regex}")
|
139
|
-
regex = nil
|
140
|
-
end
|
141
|
-
else
|
142
|
-
regex = nil
|
143
|
-
end
|
144
|
-
|
145
|
-
new(keys: keys, regex: regex)
|
146
|
-
end
|
147
|
-
|
148
|
-
def initialize(params = {})
|
149
|
-
@regex = params[:regex] || DEFAULT_REGEX
|
150
|
-
@keys = (params[:keys] || DEFAULT_SENSITIVE_KEYS).map(&:downcase)
|
151
|
-
end
|
152
|
-
|
153
|
-
def redact(obj)
|
154
|
-
case obj
|
155
|
-
when String
|
156
|
-
return MASK if obj =~ @regex
|
157
|
-
|
158
|
-
when Array
|
159
|
-
return obj.map(&method(:redact))
|
160
|
-
|
161
|
-
when Hash
|
162
|
-
return Hash[
|
163
|
-
obj.map do |k, v|
|
164
|
-
ck = k.is_a?(String) ? k.downcase : k
|
165
|
-
[k, @keys.include?(ck) ? MASK : redact(v)]
|
166
|
-
end
|
167
|
-
]
|
168
|
-
end
|
169
|
-
|
170
|
-
obj
|
171
|
-
end
|
172
|
-
end
|
173
128
|
end
|
data/lib/sqreen/exception.rb
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
require 'sqreen/log'
|
5
5
|
|
6
6
|
module Sqreen
|
7
|
+
# TODO: do we really want this to be StandardError?
|
7
8
|
# Base exeception class for sqreen
|
8
9
|
class Exception < ::StandardError
|
9
10
|
def initialize(msg = nil, *args)
|
@@ -15,44 +16,12 @@ module Sqreen
|
|
15
16
|
Sqreen.log.error(msg)
|
16
17
|
end
|
17
18
|
end
|
18
|
-
|
19
|
-
# When the token is not found
|
20
|
-
class TokenNotFoundException < Exception
|
21
|
-
end
|
22
|
-
|
23
|
-
# When the token is invalid
|
24
|
-
class TokenInvalidException < Exception
|
25
|
-
end
|
26
|
-
|
27
|
-
# This exception name is particularly important since it is often seen by
|
28
|
-
# Sqreen users when watching their logs. It should not raise any concern to
|
29
|
-
# them.
|
30
|
-
class AttackBlocked < Exception
|
31
|
-
attr_accessor :redirect_url
|
32
|
-
|
33
|
-
def log_message(msg)
|
34
|
-
Sqreen.log.warn(msg)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
class NotImplementedYet < Exception
|
39
|
-
end
|
40
|
-
|
41
|
-
class InvalidSignatureException < Exception
|
42
|
-
end
|
43
|
-
|
44
|
-
class Unauthorized < Exception
|
45
|
-
end
|
46
|
-
|
47
|
-
class WAFError < Exception
|
48
|
-
attr_reader :rule_name, :error, :data, :args
|
49
|
-
|
50
|
-
def initialize(rule_name, error, data = nil, args = nil)
|
51
|
-
super(error.to_s)
|
52
|
-
@rule_name = rule_name
|
53
|
-
@error = error
|
54
|
-
@data = data
|
55
|
-
@args = args
|
56
|
-
end
|
57
|
-
end
|
58
19
|
end
|
20
|
+
|
21
|
+
require 'sqreen/token_not_found_exception'
|
22
|
+
require 'sqreen/token_invalid_exception'
|
23
|
+
require 'sqreen/attack_blocked'
|
24
|
+
require 'sqreen/not_implemented_yet'
|
25
|
+
require 'sqreen/invalid_signature_exception'
|
26
|
+
require 'sqreen/unauthorized'
|
27
|
+
require 'sqreen/waf_error'
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/log'
|
5
|
+
|
6
|
+
module Sqreen
|
7
|
+
# Ruby default formatter modified to display current thread_id
|
8
|
+
class FormatterWithTid
|
9
|
+
# TODO: constant name
|
10
|
+
Format = "%s, [%s#%d.%s] %5s -- %s: %s\n".freeze
|
11
|
+
DatetimeFormat = '%Y-%m-%dT%H:%M:%S.%6N '.freeze
|
12
|
+
|
13
|
+
attr_accessor :datetime_format
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@datetime_format = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def call(severity, time, progname, msg)
|
20
|
+
format(
|
21
|
+
Format,
|
22
|
+
severity[0..0], format_datetime(time), $$,
|
23
|
+
Thread.current.object_id.to_s(36),
|
24
|
+
severity, progname, msg2str(msg),
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def format_datetime(time)
|
31
|
+
time.strftime(DatetimeFormat)
|
32
|
+
end
|
33
|
+
|
34
|
+
def msg2str(msg)
|
35
|
+
case msg
|
36
|
+
when ::String
|
37
|
+
msg
|
38
|
+
when ::Exception
|
39
|
+
"#{msg.message} (#{msg.class})\n" << (msg.backtrace || []).join("\n")
|
40
|
+
else
|
41
|
+
msg.inspect
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
3
|
+
|
4
|
+
require 'sqreen/cb'
|
5
|
+
require 'sqreen/shared_storage'
|
6
|
+
|
7
|
+
module Sqreen
|
8
|
+
# Framework-aware callback
|
9
|
+
class FrameworkCB < CB
|
10
|
+
attr_accessor :framework
|
11
|
+
|
12
|
+
def whitelisted?
|
13
|
+
whitelisted = SharedStorage.get(:whitelisted)
|
14
|
+
return whitelisted unless whitelisted.nil?
|
15
|
+
framework && !framework.whitelisted_match.nil?
|
16
|
+
end
|
17
|
+
|
18
|
+
# Record a metric observation
|
19
|
+
# @param category [String] Name of the metric observed
|
20
|
+
# @param key [String] aggregation key
|
21
|
+
# @param observation [Object] data observed
|
22
|
+
# @param at [Time] time when observation was made
|
23
|
+
def record_observation(category, key, observation, at = Time.now.utc)
|
24
|
+
return unless framework
|
25
|
+
framework.observe(:observations, [category, key, observation, at], [], false)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/sqreen/frameworks.rb
CHANGED
@@ -1,7 +1,14 @@
|
|
1
1
|
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
2
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
3
3
|
|
4
|
+
# TODO: @@framework global of hell, misscoped (move to Sqreen::Framework?)
|
5
|
+
# TODO: Sqreen::Frameworks => Sqreen::Framework
|
6
|
+
|
7
|
+
require 'sqreen/log'
|
8
|
+
|
4
9
|
module Sqreen
|
10
|
+
module Frameworks; end
|
11
|
+
|
5
12
|
@@framework = nil
|
6
13
|
|
7
14
|
def self::set_framework(fwk)
|
@@ -1,13 +1,16 @@
|
|
1
1
|
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
2
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
3
3
|
|
4
|
+
# TODO: Sqreen::NotImplementedYet => sqreen/exceptions
|
5
|
+
|
4
6
|
require 'ipaddr'
|
5
7
|
require 'set'
|
6
8
|
|
7
9
|
require 'sqreen/events/remote_exception'
|
8
|
-
require 'sqreen/
|
10
|
+
require 'sqreen/shared_storage'
|
9
11
|
require 'sqreen/exception'
|
10
12
|
require 'sqreen/log'
|
13
|
+
|
11
14
|
require 'sqreen/frameworks/request_recorder'
|
12
15
|
|
13
16
|
module Sqreen
|
@@ -49,6 +52,7 @@ module Sqreen
|
|
49
52
|
HTTP_X_CLUSTER_CLIENT_IP HTTP_FORWARDED_FOR
|
50
53
|
HTTP_FORWARDED HTTP_VIA].freeze
|
51
54
|
|
55
|
+
# TODO: remove global config_get
|
52
56
|
def preferred_ip_headers
|
53
57
|
@preferred_ip_headers ||=
|
54
58
|
begin
|
@@ -1,6 +1,9 @@
|
|
1
1
|
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
2
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
3
3
|
|
4
|
+
# TODO: Sqreen::Framework::RequestRecorder misnamed/misplaced?
|
5
|
+
# TODO: deps?
|
6
|
+
|
4
7
|
require 'set'
|
5
8
|
require 'sqreen/shared_storage'
|
6
9
|
require 'sqreen/events/request_record'
|
@@ -1,17 +1,17 @@
|
|
1
1
|
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
2
|
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
3
3
|
|
4
|
-
require 'sqreen/
|
4
|
+
require 'sqreen/cb_tree'
|
5
5
|
require 'sqreen/log'
|
6
6
|
require 'sqreen/exception'
|
7
7
|
require 'sqreen/performance_notifications'
|
8
8
|
require 'sqreen/call_countable'
|
9
9
|
require 'sqreen/events/remote_exception'
|
10
|
-
require 'sqreen/
|
10
|
+
require 'sqreen/sqreen_signed_verifier'
|
11
11
|
require 'sqreen/shared_storage'
|
12
|
-
require 'sqreen/
|
13
|
-
require 'sqreen/
|
14
|
-
require 'sqreen/
|
12
|
+
require 'sqreen/rules/record_request_context'
|
13
|
+
require 'sqreen/rules/run_req_start_actions'
|
14
|
+
require 'sqreen/rules/run_user_actions'
|
15
15
|
require 'sqreen/mono_time'
|
16
16
|
require 'set'
|
17
17
|
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# Copyright (c) 2015 Sqreen. All Rights Reserved.
|
2
|
+
# Please refer to our terms for more information: https://www.sqreen.com/terms.html
|
3
|
+
|
4
|
+
# TODO: => Sqreen::JS:MiniRacer ?
|
5
|
+
|
6
|
+
module Sqreen
|
7
|
+
module Js
|
8
|
+
class ContextPool
|
9
|
+
def initialize
|
10
|
+
@mutex = Mutex.new
|
11
|
+
@total_ctxs = 0
|
12
|
+
@contexts = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def with_context(&block)
|
16
|
+
isolate = context
|
17
|
+
begin
|
18
|
+
block[isolate]
|
19
|
+
ensure
|
20
|
+
give_back_context isolate
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def context
|
27
|
+
@mutex.synchronize do
|
28
|
+
if @contexts.empty?
|
29
|
+
@total_ctxs += 1
|
30
|
+
Sqreen.log.debug "Creating new V8 context (#{@total_ctxs})"
|
31
|
+
SqreenContext.new
|
32
|
+
else
|
33
|
+
@contexts.pop
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def give_back_context(context)
|
39
|
+
context.possibly_gc
|
40
|
+
|
41
|
+
if context.gc_load > 30
|
42
|
+
if context.gc_threshold_in_bytes == DEFAULT_GC_THRESHOLD
|
43
|
+
context.gc_threshold_in_bytes *= 2
|
44
|
+
Sqreen.log.warn("Context #{context} had too many close garbage " \
|
45
|
+
'collections; doubling the threshold to ' \
|
46
|
+
"#{context.gc_threshold_in_bytes} bytes")
|
47
|
+
context.gc_load = 0
|
48
|
+
else
|
49
|
+
Sqreen.log.warn("Context #{context} had too many close garbage " \
|
50
|
+
'collections; discarding it')
|
51
|
+
context.dispose
|
52
|
+
return
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
@mutex.synchronize { @contexts.push(context); }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|