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.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +0 -5
  3. data/lib/sqreen/actions.rb +11 -337
  4. data/lib/sqreen/actions/base.rb +110 -0
  5. data/lib/sqreen/actions/block_ip.rb +32 -0
  6. data/lib/sqreen/actions/block_user.rb +44 -0
  7. data/lib/sqreen/actions/ip_range_indexed_action_class.rb +36 -0
  8. data/lib/sqreen/actions/ip_ranges_index.rb +36 -0
  9. data/lib/sqreen/actions/redirect_ip.rb +40 -0
  10. data/lib/sqreen/actions/redirect_user.rb +45 -0
  11. data/lib/sqreen/actions/repository.rb +24 -0
  12. data/lib/sqreen/actions/unknown_action_type.rb +16 -0
  13. data/lib/sqreen/actions/user_action_class.rb +41 -0
  14. data/lib/sqreen/agent.rb +4 -1
  15. data/lib/sqreen/attack_blocked.rb +17 -0
  16. data/lib/sqreen/binding_accessor.rb +9 -102
  17. data/lib/sqreen/binding_accessor/path_elem.rb +8 -0
  18. data/lib/sqreen/binding_accessor/transforms.rb +107 -0
  19. data/lib/sqreen/capped_queue.rb +2 -0
  20. data/lib/sqreen/{callbacks.rb → cb.rb} +1 -53
  21. data/lib/sqreen/{callback_tree.rb → cb_tree.rb} +2 -2
  22. data/lib/sqreen/condition_evaluator.rb +22 -5
  23. data/lib/sqreen/configuration.rb +3 -0
  24. data/lib/sqreen/default_cb.rb +20 -0
  25. data/lib/sqreen/deferred_logger.rb +63 -0
  26. data/lib/sqreen/deliveries.rb +10 -0
  27. data/lib/sqreen/deliveries/batch.rb +7 -1
  28. data/lib/sqreen/deliveries/simple.rb +5 -0
  29. data/lib/sqreen/dependency/rails.rb +4 -0
  30. data/lib/sqreen/dependency/sinatra.rb +4 -0
  31. data/lib/sqreen/error_handling_middleware.rb +30 -0
  32. data/lib/sqreen/event.rb +2 -0
  33. data/lib/sqreen/events/attack.rb +2 -0
  34. data/lib/sqreen/events/request_record.rb +11 -56
  35. data/lib/sqreen/exception.rb +9 -40
  36. data/lib/sqreen/formatter_with_tid.rb +45 -0
  37. data/lib/sqreen/framework_cb.rb +28 -0
  38. data/lib/sqreen/frameworks.rb +7 -0
  39. data/lib/sqreen/frameworks/generic.rb +5 -1
  40. data/lib/sqreen/frameworks/rails.rb +2 -0
  41. data/lib/sqreen/frameworks/request_recorder.rb +3 -0
  42. data/lib/sqreen/frameworks/sinatra.rb +2 -0
  43. data/lib/sqreen/frameworks/sqreen_test.rb +2 -0
  44. data/lib/sqreen/instrumentation.rb +5 -5
  45. data/lib/sqreen/invalid_signature_exception.rb +8 -0
  46. data/lib/{sqreen-alt.rb → sqreen/js.rb} +6 -1
  47. data/lib/sqreen/js/call_context.rb +10 -0
  48. data/lib/sqreen/js/context_pool.rb +60 -0
  49. data/lib/sqreen/js/exec_js_runnable.rb +20 -0
  50. data/lib/sqreen/js/execjs_adapter.rb +6 -47
  51. data/lib/sqreen/js/executable_js.rb +12 -0
  52. data/lib/sqreen/js/js_service.rb +2 -22
  53. data/lib/sqreen/js/js_service_adapter.rb +18 -0
  54. data/lib/sqreen/js/mini_racer_adapter.rb +6 -180
  55. data/lib/sqreen/js/mini_racer_executable_js.rb +142 -0
  56. data/lib/sqreen/js/thread_local_exec_js_runnable.rb +47 -0
  57. data/lib/sqreen/log.rb +8 -188
  58. data/lib/sqreen/logger.rb +83 -0
  59. data/lib/sqreen/metrics_store.rb +3 -11
  60. data/lib/sqreen/metrics_store/already_registered_metric.rb +11 -0
  61. data/lib/sqreen/metrics_store/unknown_metric.rb +11 -0
  62. data/lib/sqreen/metrics_store/unregistered_metric.rb +11 -0
  63. data/lib/sqreen/middleware.rb +0 -44
  64. data/lib/sqreen/mono_time.rb +2 -0
  65. data/lib/sqreen/node.rb +44 -0
  66. data/lib/sqreen/not_implemented_yet.rb +8 -0
  67. data/lib/sqreen/null_logger.rb +24 -0
  68. data/lib/sqreen/payload_creator.rb +2 -19
  69. data/lib/sqreen/payload_creator/header_section.rb +28 -0
  70. data/lib/sqreen/prefix.rb +33 -0
  71. data/lib/sqreen/rails_middleware.rb +14 -0
  72. data/lib/sqreen/remote_command.rb +1 -8
  73. data/lib/sqreen/remote_command/failure_output.rb +11 -0
  74. data/lib/sqreen/rules.rb +32 -2
  75. data/lib/sqreen/{rule_attributes.rb → rules/attrs.rb} +0 -0
  76. data/lib/sqreen/{rules_callbacks/sdk_auth_track.rb → rules/auth_track_cb.rb} +2 -2
  77. data/lib/sqreen/{rules_callbacks/binding_accessor_matcher.rb → rules/binding_accessor_matcher_cb.rb} +4 -8
  78. data/lib/sqreen/{rules_callbacks → rules}/binding_accessor_metrics.rb +1 -1
  79. data/lib/sqreen/{rules_callbacks/blacklist_ips.rb → rules/blacklist_ips_cb.rb} +3 -2
  80. data/lib/sqreen/{rules_callbacks → rules}/count_http_codes.rb +2 -2
  81. data/lib/sqreen/{rules_callbacks/crawler_user_agent_matches.rb → rules/crawler_user_agent_matches_cb.rb} +1 -1
  82. data/lib/sqreen/{rules_callbacks/crawler_user_agent_matches_metrics.rb → rules/crawler_user_agent_matches_metrics_cb.rb} +1 -1
  83. data/lib/sqreen/{rules_callbacks/custom_error.rb → rules/custom_error_cb.rb} +1 -1
  84. data/lib/sqreen/{rules_callbacks/devise_auth_track.rb → rules/devise_auth_track_cb.rb} +2 -2
  85. data/lib/sqreen/{rules_callbacks/devise_signup_track.rb → rules/devise_signup_track_cb.rb} +2 -2
  86. data/lib/sqreen/{rules_callbacks/execjs.rb → rules/execjs_cb.rb} +49 -50
  87. data/lib/sqreen/{rules_callbacks/headers_insert.rb → rules/headers_insert_cb.rb} +1 -1
  88. data/lib/sqreen/{rules_callbacks → rules}/matcher_rule.rb +2 -2
  89. data/lib/sqreen/{rules_callbacks/not_found.rb → rules/not_found_cb.rb} +2 -2
  90. data/lib/sqreen/{rules_callbacks/rails_parameters.rb → rules/rails_parameters_cb.rb} +1 -1
  91. data/lib/sqreen/{rules_callbacks → rules}/record_request_context.rb +1 -1
  92. data/lib/sqreen/{rules_callbacks/regexp_rule.rb → rules/regexp_rule_cb.rb} +1 -1
  93. data/lib/sqreen/{rule_callback.rb → rules/rule_cb.rb} +2 -2
  94. data/lib/sqreen/{rules_callbacks → rules}/run_req_start_actions.rb +4 -2
  95. data/lib/sqreen/{rules_callbacks → rules}/run_user_actions.rb +1 -1
  96. data/lib/sqreen/{rules_callbacks/shell_env.rb → rules/shell_env_cb.rb} +1 -1
  97. data/lib/sqreen/{rules_callbacks/sdk_signup_track.rb → rules/signup_track_cb.rb} +2 -2
  98. data/lib/sqreen/{rules_callbacks → rules}/update_request_context.rb +1 -1
  99. data/lib/sqreen/{rules_callbacks/url_matches.rb → rules/url_matches_cb.rb} +1 -1
  100. data/lib/sqreen/{rules_callbacks/user_agent_matches.rb → rules/user_agent_matches_cb.rb} +1 -1
  101. data/lib/sqreen/{rules_callbacks/waf.rb → rules/waf_cb.rb} +7 -3
  102. data/lib/sqreen/{rules_callbacks/reflected_xss.rb → rules/xss_cb.rb} +10 -7
  103. data/lib/sqreen/run_when_called_cb.rb +21 -0
  104. data/lib/sqreen/sensitive_data_redactor.rb +111 -0
  105. data/lib/sqreen/signature_verifier.rb +20 -0
  106. data/lib/sqreen/sinatra_middleware.rb +14 -0
  107. data/lib/sqreen/{rules_signature.rb → sqreen_signed_verifier.rb} +5 -17
  108. data/lib/sqreen/token_invalid_exception.rb +8 -0
  109. data/lib/sqreen/token_not_found_exception.rb +9 -0
  110. data/lib/sqreen/trie.rb +3 -64
  111. data/lib/sqreen/unauthorized.rb +8 -0
  112. data/lib/sqreen/util.rb +2 -0
  113. data/lib/sqreen/util/capped_array.rb +30 -0
  114. data/lib/sqreen/util/capped_hash.rb +36 -0
  115. data/lib/sqreen/util/capped_string.rb +22 -0
  116. data/lib/sqreen/util/capper.rb +57 -0
  117. data/lib/sqreen/version.rb +1 -1
  118. data/lib/sqreen/waf_error.rb +18 -0
  119. metadata +85 -36
  120. data/lib/sqreen/rules_callbacks.rb +0 -36
  121. 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
@@ -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: sqreen/events
5
+
4
6
  require 'sqreen/event'
5
7
 
6
8
  module Sqreen
@@ -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
@@ -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
@@ -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/callbacks'
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
@@ -5,6 +5,8 @@
5
5
 
6
6
  require 'sqreen/frameworks/generic'
7
7
  require 'sqreen/middleware'
8
+ require 'sqreen/error_handling_middleware'
9
+ require 'sqreen/rails_middleware'
8
10
 
9
11
  module Sqreen
10
12
  module Frameworks
@@ -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'
@@ -3,6 +3,8 @@
3
3
 
4
4
  require 'sqreen/frameworks/generic'
5
5
  require 'sqreen/middleware'
6
+ require 'sqreen/error_handling_middleware'
7
+ require 'sqreen/sinatra_middleware'
6
8
 
7
9
  module Sqreen
8
10
  module Frameworks
@@ -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: drop
5
+
4
6
  require 'sqreen/frameworks/generic'
5
7
 
6
8
  module Sqreen
@@ -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/callback_tree'
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/rules_signature'
10
+ require 'sqreen/sqreen_signed_verifier'
11
11
  require 'sqreen/shared_storage'
12
- require 'sqreen/rules_callbacks/record_request_context'
13
- require 'sqreen/rules_callbacks/run_req_start_actions'
14
- require 'sqreen/rules_callbacks/run_user_actions'
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,8 @@
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/exception'
5
+
6
+ module Sqreen
7
+ class InvalidSignatureException < Sqreen::Exception; end
8
+ end
@@ -1,4 +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
- require "sqreen"
4
+ # TODO: case JS/Js?
5
+
6
+ module Sqreen
7
+ module Js
8
+ end
9
+ end
@@ -0,0 +1,10 @@
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: useless?
5
+
6
+ module Sqreen
7
+ module Js
8
+ CallContext = Struct.new(:inst, :args, :rv)
9
+ end
10
+ end
@@ -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