sqreen 1.14.1-java → 1.14.2-java
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/lib/sqreen.rb +4 -0
- data/lib/sqreen/frameworks/generic.rb +26 -0
- data/lib/sqreen/js/execjs_adapter.rb +50 -2
- data/lib/sqreen/js/js_service.rb +2 -2
- data/lib/sqreen/js/mini_racer_adapter.rb +20 -1
- data/lib/sqreen/performance_notifications/binned_metrics.rb +2 -0
- data/lib/sqreen/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d64ca79b53ae2456a2c51b3939ff14c2d41b8dd82a7ce89860d82005cc75e1e5
|
4
|
+
data.tar.gz: fdee9e1364ff14e4167ae07bc9c1d878a073904a32d79acccbc1a041d96555c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a4b42b30b81fa25b154ccb5dea089dcd46ddb54c08fcb7e55946c8b45a03c74e4420bba338590b48582b3fea2084111c76b7ddffc4ff7fe862a0670e94ff5aa
|
7
|
+
data.tar.gz: 78e5b14939b1c743335b17fdaf9bc3d2d954c1806326edf4c88a2a58e5a170f87cf642bd8750caed162ec0090220b0d733f02cb38d3714403c46d8654cc249be
|
data/lib/sqreen.rb
CHANGED
@@ -17,6 +17,10 @@ require 'thread'
|
|
17
17
|
# Auto start the instrumentation.
|
18
18
|
|
19
19
|
Sqreen.framework.on_start do |framework|
|
20
|
+
if RUBY_VERSION =~ /\A2\.5\.[01]\z/ && Sqreen.framework.on_pre_fork_preload?
|
21
|
+
STDERR.puts("Avoiding launching sqreen thread pre-fork") # sqreen log unavailable
|
22
|
+
next
|
23
|
+
end
|
20
24
|
Thread.new do
|
21
25
|
begin
|
22
26
|
runner = nil
|
@@ -422,6 +422,15 @@ module Sqreen
|
|
422
422
|
end
|
423
423
|
end
|
424
424
|
|
425
|
+
def on_pre_fork_preload?
|
426
|
+
# unlike with worker_fork_detection, we can't be instrument Puma::Cluster
|
427
|
+
# in time for intercepting run
|
428
|
+
stack = Kernel.caller_locations
|
429
|
+
|
430
|
+
puma_preload?(stack) || unicorn_preload?(stack)
|
431
|
+
end
|
432
|
+
|
433
|
+
|
425
434
|
protected
|
426
435
|
|
427
436
|
# Is this a whitelisted path?
|
@@ -519,6 +528,7 @@ module Sqreen
|
|
519
528
|
Sqreen.log.warn "Failed ignoring AttackBlocked on NewRelic: #{e.inspect}"
|
520
529
|
end
|
521
530
|
|
531
|
+
# if it doesn't detect the fork it's not a problem
|
522
532
|
def worker_fork_detection
|
523
533
|
# only Puma currently supported
|
524
534
|
return unless defined?(Puma::Cluster) && Puma::Cluster.instance_methods.include?(:worker)
|
@@ -533,6 +543,22 @@ module Sqreen
|
|
533
543
|
|
534
544
|
private
|
535
545
|
|
546
|
+
def puma_preload?(stack)
|
547
|
+
cluster_run = stack.each_with_index.find { |b, _i| b.path =~ /puma\/cluster\.rb\z/ && b.label == 'run' }
|
548
|
+
return false unless cluster_run
|
549
|
+
frame_atop = stack[cluster_run[1] - 1]
|
550
|
+
frame_atop.label == 'load_and_bind'
|
551
|
+
end
|
552
|
+
|
553
|
+
def unicorn_preload?(stack)
|
554
|
+
build_app = stack.each_with_index.find do |b, _i|
|
555
|
+
b.path =~ /unicorn\/http_server\.rb\z/ && b.label == 'build_app!'
|
556
|
+
end
|
557
|
+
return false unless build_app
|
558
|
+
frame_below = stack[build_app[1] + 1]
|
559
|
+
frame_below.label == 'start'
|
560
|
+
end
|
561
|
+
|
536
562
|
def split_ip_addresses(ip_addresses)
|
537
563
|
ip_addresses ? ip_addresses.strip.split(/[,\s]+/) : []
|
538
564
|
end
|
@@ -1,15 +1,26 @@
|
|
1
1
|
require 'execjs'
|
2
|
+
require 'weakref'
|
2
3
|
|
3
4
|
module Sqreen
|
4
5
|
module Js
|
5
6
|
class ExecjsAdapter < JsServiceAdapter
|
6
|
-
def preprocess(
|
7
|
-
|
7
|
+
def preprocess(rule_name, code)
|
8
|
+
if thread_safe?
|
9
|
+
ExecJsRunnable.new(ExecJS.compile(code))
|
10
|
+
else
|
11
|
+
ThreadLocalExecJsRunnable.new(code)
|
12
|
+
end
|
8
13
|
end
|
9
14
|
|
10
15
|
def variant_name
|
11
16
|
ExecJS.runtime.name + ' (ExecJS)'
|
12
17
|
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def thread_safe?
|
22
|
+
ExecJS.runtime.name != 'therubyrhino (Rhino)'
|
23
|
+
end
|
13
24
|
end
|
14
25
|
|
15
26
|
class ExecJsRunnable < ExecutableJs
|
@@ -21,5 +32,42 @@ module Sqreen
|
|
21
32
|
@compiled.call(cbname, *arguments)
|
22
33
|
end
|
23
34
|
end
|
35
|
+
|
36
|
+
class ThreadLocalExecJsRunnable < ExecutableJs
|
37
|
+
def initialize(code)
|
38
|
+
@code = code
|
39
|
+
@tl_key = "SQREEN_EXECJS_CONTEXT_#{object_id}".freeze
|
40
|
+
@runtimes = [] # place where to keep strong references
|
41
|
+
@runtimes_mutex = Mutex.new
|
42
|
+
end
|
43
|
+
|
44
|
+
def run_js_cb(cbname, _budget, arguments)
|
45
|
+
tl_exec_js_runnable.call(cbname, *arguments)
|
46
|
+
end
|
47
|
+
|
48
|
+
def with_runtimes_mutex
|
49
|
+
@runtimes_mutex.synchronize { yield }
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def dispose_from_dead_threads
|
55
|
+
with_runtimes_mutex do
|
56
|
+
@runtimes.delete_if { |th, _runtime| !th.alive? }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def tl_exec_js_runnable
|
61
|
+
runnable = Thread.current[@tl_key]
|
62
|
+
return runnable if runnable && runnable.weakref_alive?
|
63
|
+
|
64
|
+
dispose_from_dead_threads
|
65
|
+
runtime = ExecJS.compile(@code)
|
66
|
+
with_runtimes_mutex do
|
67
|
+
@runtimes << [Thread.current, runtime]
|
68
|
+
end
|
69
|
+
Thread.current[@tl_key] = WeakRef.new(runtime)
|
70
|
+
end
|
71
|
+
end
|
24
72
|
end
|
25
73
|
end
|
data/lib/sqreen/js/js_service.rb
CHANGED
@@ -5,7 +5,7 @@ module Sqreen
|
|
5
5
|
# start public interface
|
6
6
|
|
7
7
|
class JsService
|
8
|
-
include Singleton
|
8
|
+
include ::Singleton
|
9
9
|
|
10
10
|
def initialize
|
11
11
|
detect_adapter
|
@@ -75,7 +75,7 @@ module Sqreen
|
|
75
75
|
# end public interface
|
76
76
|
|
77
77
|
class JsServiceAdapter
|
78
|
-
def preprocess(code)
|
78
|
+
def preprocess(rule_name, code)
|
79
79
|
raise Sqreen::NotImplementedYet
|
80
80
|
end
|
81
81
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'weakref'
|
2
|
+
require 'sqreen/runner' # for Sqreen.on_forked_worker?
|
2
3
|
|
3
4
|
module Sqreen
|
4
5
|
module Js
|
@@ -63,8 +64,9 @@ module Sqreen
|
|
63
64
|
|
64
65
|
mini_racer_context[:c] += 1
|
65
66
|
begin
|
67
|
+
json_args = "[#{arguments.map(&method(:fixup_bad_encoding)).map(&:to_json).join(',')}]"
|
66
68
|
mini_racer_context[:r].eval_unsafe(
|
67
|
-
"#{cb_name}.apply(this, #{
|
69
|
+
"#{cb_name}.apply(this, #{json_args})", nil, budget)
|
68
70
|
rescue @module::ScriptTerminatedError
|
69
71
|
nil
|
70
72
|
end
|
@@ -72,6 +74,23 @@ module Sqreen
|
|
72
74
|
|
73
75
|
private
|
74
76
|
|
77
|
+
def fixup_bad_encoding(arg)
|
78
|
+
# NOTE: we don't fix encoding problems in deeper structures
|
79
|
+
return arg unless arg.is_a?(String)
|
80
|
+
unless arg.valid_encoding?
|
81
|
+
return arg.dup.force_encoding(Encoding::ISO_8859_1)
|
82
|
+
end
|
83
|
+
|
84
|
+
# encoding is valid if it reaches this point
|
85
|
+
return arg if arg.encoding == Encoding::UTF_8
|
86
|
+
|
87
|
+
begin
|
88
|
+
arg.encode(Encoding::UTF_8)
|
89
|
+
rescue Encoding::UndefinedConversionError
|
90
|
+
arg.dup.force_encoding(Encoding::ISO_8859_1)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
75
94
|
def snapshot
|
76
95
|
@snapshot ||= @module::Snapshot.new(@source)
|
77
96
|
end
|
@@ -58,6 +58,8 @@ module Sqreen
|
|
58
58
|
|
59
59
|
finish_time = SQREEN_MONO_TIME ? Time.now.utc : finish
|
60
60
|
time_millis = (finish - start) * 1000
|
61
|
+
# Ensure we always have a timings if we somehow missed the request start
|
62
|
+
SharedStorage[:sqreen_request_time] ||= 0
|
61
63
|
SharedStorage[:sqreen_request_time] += time_millis
|
62
64
|
metrics_store.update(metric_name, finish_time, nil, time_millis)
|
63
65
|
end
|
data/lib/sqreen/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sqreen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.14.
|
4
|
+
version: 1.14.2
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Sqreen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-10-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|