sqreen 1.18.3.beta1 → 1.18.3.beta2

Sign up to get free protection for your applications and to get access to all the features.
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