ddtrace 1.6.1 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +40 -2
  3. data/ext/ddtrace_profiling_loader/extconf.rb +1 -1
  4. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.c +66 -6
  5. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +51 -54
  6. data/ext/ddtrace_profiling_native_extension/collectors_stack.c +11 -13
  7. data/ext/ddtrace_profiling_native_extension/extconf.rb +1 -1
  8. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +3 -2
  9. data/ext/ddtrace_profiling_native_extension/setup_signal_handler.c +96 -0
  10. data/ext/ddtrace_profiling_native_extension/setup_signal_handler.h +7 -0
  11. data/ext/ddtrace_profiling_native_extension/stack_recorder.c +70 -18
  12. data/ext/ddtrace_profiling_native_extension/stack_recorder.h +1 -0
  13. data/lib/datadog/appsec/assets/blocked.html +98 -3
  14. data/lib/datadog/appsec/assets/blocked.json +1 -0
  15. data/lib/datadog/appsec/assets/blocked.text +5 -0
  16. data/lib/datadog/appsec/assets/waf_rules/recommended.json +35 -46
  17. data/lib/datadog/appsec/assets/waf_rules/risky.json +1 -1
  18. data/lib/datadog/appsec/assets/waf_rules/strict.json +46 -1
  19. data/lib/datadog/appsec/assets.rb +2 -2
  20. data/lib/datadog/appsec/configuration/settings.rb +6 -0
  21. data/lib/datadog/appsec/configuration.rb +4 -0
  22. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +4 -8
  23. data/lib/datadog/appsec/contrib/rack/request.rb +17 -0
  24. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +2 -2
  25. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +2 -2
  26. data/lib/datadog/appsec/contrib/rails/patcher.rb +3 -6
  27. data/lib/datadog/appsec/contrib/sinatra/ext.rb +1 -0
  28. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +1 -1
  29. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +11 -8
  30. data/lib/datadog/appsec/extensions.rb +10 -0
  31. data/lib/datadog/appsec/processor.rb +18 -0
  32. data/lib/datadog/appsec/response.rb +54 -0
  33. data/lib/datadog/core/runtime/ext.rb +1 -1
  34. data/lib/datadog/opentracer/distributed_headers.rb +5 -7
  35. data/lib/datadog/opentracer/rack_propagator.rb +0 -3
  36. data/lib/datadog/opentracer/text_map_propagator.rb +5 -7
  37. data/lib/datadog/profiling/collectors/cpu_and_wall_time.rb +10 -4
  38. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +4 -0
  39. data/lib/datadog/profiling/collectors/old_stack.rb +7 -0
  40. data/lib/datadog/profiling/exporter.rb +5 -0
  41. data/lib/datadog/profiling/old_recorder.rb +8 -0
  42. data/lib/datadog/profiling/profiler.rb +7 -0
  43. data/lib/datadog/profiling/scheduler.rb +4 -7
  44. data/lib/datadog/profiling/stack_recorder.rb +22 -0
  45. data/lib/datadog/profiling/tasks/setup.rb +0 -7
  46. data/lib/datadog/tracing/contrib/delayed_job/plugin.rb +4 -0
  47. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +2 -1
  48. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +6 -12
  49. data/lib/datadog/tracing/contrib/grpc/distributed/fetcher.rb +27 -0
  50. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +38 -0
  51. data/lib/datadog/tracing/contrib/grpc/patcher.rb +0 -2
  52. data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +32 -0
  53. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +33 -0
  54. data/lib/datadog/tracing/contrib/kafka/consumer_event.rb +1 -0
  55. data/lib/datadog/tracing/contrib/kafka/events/produce_operation/send_messages.rb +1 -0
  56. data/lib/datadog/tracing/contrib/kafka/events/producer/deliver_messages.rb +1 -0
  57. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +2 -0
  58. data/lib/datadog/tracing/contrib/que/tracer.rb +2 -0
  59. data/lib/datadog/tracing/contrib/racecar/events/batch.rb +4 -1
  60. data/lib/datadog/tracing/contrib/racecar/events/message.rb +4 -1
  61. data/lib/datadog/tracing/contrib/rack/middlewares.rb +2 -0
  62. data/lib/datadog/tracing/contrib/redis/instrumentation.rb +2 -0
  63. data/lib/datadog/tracing/contrib/resque/resque_job.rb +2 -0
  64. data/lib/datadog/tracing/contrib/shoryuken/tracer.rb +2 -0
  65. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +5 -0
  66. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +5 -0
  67. data/lib/datadog/tracing/contrib/sneakers/tracer.rb +2 -0
  68. data/lib/datadog/tracing/distributed/b3.rb +66 -0
  69. data/lib/datadog/tracing/distributed/b3_single.rb +66 -0
  70. data/lib/datadog/tracing/distributed/datadog.rb +153 -0
  71. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +1 -0
  72. data/lib/datadog/tracing/distributed/fetcher.rb +30 -0
  73. data/lib/datadog/tracing/distributed/headers/ext.rb +18 -16
  74. data/lib/datadog/tracing/distributed/helpers.rb +7 -6
  75. data/lib/datadog/tracing/distributed/propagation.rb +127 -0
  76. data/lib/datadog/tracing/propagation/http.rb +3 -106
  77. data/lib/datadog/tracing/trace_segment.rb +1 -1
  78. data/lib/ddtrace/transport/trace_formatter.rb +2 -5
  79. data/lib/ddtrace/version.rb +2 -2
  80. metadata +19 -14
  81. data/lib/datadog/tracing/distributed/headers/b3.rb +0 -55
  82. data/lib/datadog/tracing/distributed/headers/b3_single.rb +0 -67
  83. data/lib/datadog/tracing/distributed/headers/datadog.rb +0 -144
  84. data/lib/datadog/tracing/distributed/headers/parser.rb +0 -37
  85. data/lib/datadog/tracing/distributed/metadata/b3.rb +0 -55
  86. data/lib/datadog/tracing/distributed/metadata/b3_single.rb +0 -66
  87. data/lib/datadog/tracing/distributed/metadata/datadog.rb +0 -73
  88. data/lib/datadog/tracing/distributed/metadata/parser.rb +0 -34
  89. data/lib/datadog/tracing/propagation/grpc.rb +0 -98
@@ -0,0 +1 @@
1
+ {"errors": [{"title": "You've been blocked", "detail": "Sorry, you cannot access this page. Please contact the customer service team. Security provided by Datadog."}]}
@@ -0,0 +1,5 @@
1
+ You've been blocked
2
+
3
+ Sorry, you cannot access this page. Please contact the customer service team.
4
+
5
+ Security provided by Datadog.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": "2.2",
3
3
  "metadata": {
4
- "rules_version": "1.4.1"
4
+ "rules_version": "1.4.2"
5
5
  },
6
6
  "rules": [
7
7
  {
@@ -2853,51 +2853,6 @@
2853
2853
  ],
2854
2854
  "transformers": []
2855
2855
  },
2856
- {
2857
- "id": "crs-941-100",
2858
- "name": "XSS Attack Detected via libinjection",
2859
- "tags": {
2860
- "type": "xss",
2861
- "crs_id": "941100",
2862
- "category": "attack_attempt"
2863
- },
2864
- "conditions": [
2865
- {
2866
- "parameters": {
2867
- "inputs": [
2868
- {
2869
- "address": "server.request.headers.no_cookies",
2870
- "key_path": [
2871
- "user-agent"
2872
- ]
2873
- },
2874
- {
2875
- "address": "server.request.headers.no_cookies",
2876
- "key_path": [
2877
- "referer"
2878
- ]
2879
- },
2880
- {
2881
- "address": "server.request.query"
2882
- },
2883
- {
2884
- "address": "server.request.body"
2885
- },
2886
- {
2887
- "address": "server.request.path_params"
2888
- },
2889
- {
2890
- "address": "grpc.server.request.message"
2891
- }
2892
- ]
2893
- },
2894
- "operator": "is_xss"
2895
- }
2896
- ],
2897
- "transformers": [
2898
- "removeNulls"
2899
- ]
2900
- },
2901
2856
  {
2902
2857
  "id": "crs-941-110",
2903
2858
  "name": "XSS Filter - Category 1: Script Tag Vector",
@@ -4363,6 +4318,40 @@
4363
4318
  "keys_only"
4364
4319
  ]
4365
4320
  },
4321
+ {
4322
+ "id": "dog-000-007",
4323
+ "name": "Server side template injection: Velocity & Freemarker",
4324
+ "tags": {
4325
+ "type": "java_code_injection",
4326
+ "category": "attack_attempt"
4327
+ },
4328
+ "conditions": [
4329
+ {
4330
+ "parameters": {
4331
+ "inputs": [
4332
+ {
4333
+ "address": "server.request.query"
4334
+ },
4335
+ {
4336
+ "address": "server.request.body"
4337
+ },
4338
+ {
4339
+ "address": "server.request.path_params"
4340
+ },
4341
+ {
4342
+ "address": "server.request.headers.no_cookies"
4343
+ },
4344
+ {
4345
+ "address": "grpc.server.request.message"
4346
+ }
4347
+ ],
4348
+ "regex": "#(?:set|foreach|macro|parse|if)\\(.*\\)|<#assign.*>"
4349
+ },
4350
+ "operator": "match_regex"
4351
+ }
4352
+ ],
4353
+ "transformers": []
4354
+ },
4366
4355
  {
4367
4356
  "id": "nfd-000-001",
4368
4357
  "name": "Detect common directory discovery scans",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": "2.2",
3
3
  "metadata": {
4
- "rules_version": "1.4.1"
4
+ "rules_version": "1.4.2"
5
5
  },
6
6
  "rules": [
7
7
  {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": "2.2",
3
3
  "metadata": {
4
- "rules_version": "1.4.1"
4
+ "rules_version": "1.4.2"
5
5
  },
6
6
  "rules": [
7
7
  {
@@ -855,6 +855,51 @@
855
855
  ],
856
856
  "transformers": []
857
857
  },
858
+ {
859
+ "id": "crs-941-100",
860
+ "name": "XSS Attack Detected via libinjection",
861
+ "tags": {
862
+ "type": "xss",
863
+ "crs_id": "941100",
864
+ "category": "attack_attempt"
865
+ },
866
+ "conditions": [
867
+ {
868
+ "parameters": {
869
+ "inputs": [
870
+ {
871
+ "address": "server.request.headers.no_cookies",
872
+ "key_path": [
873
+ "user-agent"
874
+ ]
875
+ },
876
+ {
877
+ "address": "server.request.headers.no_cookies",
878
+ "key_path": [
879
+ "referer"
880
+ ]
881
+ },
882
+ {
883
+ "address": "server.request.query"
884
+ },
885
+ {
886
+ "address": "server.request.body"
887
+ },
888
+ {
889
+ "address": "server.request.path_params"
890
+ },
891
+ {
892
+ "address": "grpc.server.request.message"
893
+ }
894
+ ]
895
+ },
896
+ "operator": "is_xss"
897
+ }
898
+ ],
899
+ "transformers": [
900
+ "removeNulls"
901
+ ]
902
+ },
858
903
  {
859
904
  "id": "crs-941-130",
860
905
  "name": "XSS Filter - Category 3: Attribute Vector",
@@ -12,8 +12,8 @@ module Datadog
12
12
  read("waf_rules/#{kind}.json")
13
13
  end
14
14
 
15
- def blocked
16
- @blocked ||= read('blocked.html')
15
+ def blocked(format: :html)
16
+ (@blocked ||= {})[format] ||= read("blocked.#{format}")
17
17
  end
18
18
 
19
19
  def path
@@ -128,6 +128,12 @@ module Datadog
128
128
  @options[:ruleset]
129
129
  end
130
130
 
131
+ # EXPERIMENTAL: This configurable is not meant to be publicly used, but
132
+ # is very useful for testing. It may change at any point in time.
133
+ def ip_denylist
134
+ @options[:ip_denylist]
135
+ end
136
+
131
137
  def waf_timeout
132
138
  @options[:waf_timeout]
133
139
  end
@@ -34,6 +34,10 @@ module Datadog
34
34
  options[:ruleset] = value
35
35
  end
36
36
 
37
+ def ip_denylist=(value)
38
+ options[:ip_denylist] = value
39
+ end
40
+
37
41
  # in microseconds
38
42
  def waf_timeout=(value)
39
43
  options[:waf_timeout] = value
@@ -15,9 +15,7 @@ module Datadog
15
15
  op.publish('request.headers', Rack::Request.headers(request))
16
16
  op.publish('request.uri.raw', Rack::Request.url(request))
17
17
  op.publish('request.cookies', Rack::Request.cookies(request))
18
- # op.publish('request.body.raw', Rack::Request.body(request))
19
- # TODO: op.publish('request.path_params', { k: v }) # route params only?
20
- # TODO: op.publish('request.path', request.script_name + request.path) # unused for now
18
+ op.publish('request.client_ip', Rack::Request.client_ip(request))
21
19
 
22
20
  nil
23
21
  end
@@ -30,8 +28,7 @@ module Datadog
30
28
  'request.uri.raw',
31
29
  'request.query',
32
30
  'request.cookies',
33
- # 'request.body.raw',
34
- # TODO: 'request.path_params',
31
+ 'request.client_ip',
35
32
  ]
36
33
 
37
34
  op.subscribe(*addresses) do |*values|
@@ -41,16 +38,15 @@ module Datadog
41
38
  uri_raw = values[1]
42
39
  query = values[2]
43
40
  cookies = values[3]
44
- # body = values[4]
41
+ client_ip = values[4]
45
42
 
46
43
  waf_args = {
47
44
  'server.request.cookies' => cookies,
48
- # 'server.request.body.raw' => body,
49
45
  'server.request.query' => query,
50
46
  'server.request.uri.raw' => uri_raw,
51
47
  'server.request.headers' => headers,
52
48
  'server.request.headers.no_cookies' => headers_no_cookies,
53
- # TODO: 'server.request.path_params' => path_params,
49
+ 'http.client_ip' => client_ip,
54
50
  }
55
51
 
56
52
  waf_timeout = Datadog::AppSec.settings.waf_timeout
@@ -1,5 +1,8 @@
1
1
  # typed: true
2
2
 
3
+ require_relative '../../../tracing/client_ip'
4
+ require_relative '../../../tracing/contrib/rack/header_collection'
5
+
3
6
  module Datadog
4
7
  module AppSec
5
8
  module Contrib
@@ -54,6 +57,20 @@ module Datadog
54
57
  # Hash<String,String||Array||Hash> when e.g coming from JSON
55
58
  request.env['rack.request.form_hash']
56
59
  end
60
+
61
+ def self.client_ip(request)
62
+ remote_ip = request.env['REMOTE_ADDR']
63
+ headers = Datadog::Tracing::Contrib::Rack::Header::RequestHeaderCollection.new(request.env)
64
+
65
+ result = Datadog::Tracing::ClientIp.raw_ip_from_request(headers, remote_ip)
66
+
67
+ if result.raw_ip
68
+ ip = Datadog::Tracing::ClientIp.strip_decorations(result.raw_ip)
69
+ return unless Datadog::Tracing::ClientIp.valid_ip?(ip)
70
+
71
+ ip
72
+ end
73
+ end
57
74
  end
58
75
  end
59
76
  end
@@ -1,7 +1,7 @@
1
1
  # typed: ignore
2
2
 
3
3
  require_relative '../../instrumentation/gateway'
4
- require_relative '../../assets'
4
+ require_relative '../../response'
5
5
 
6
6
  module Datadog
7
7
  module AppSec
@@ -29,7 +29,7 @@ module Datadog
29
29
  end
30
30
 
31
31
  if request_response && request_response.any? { |action, _event| action == :block }
32
- request_return = [403, { 'Content-Type' => 'text/html' }, [Datadog::AppSec::Assets.blocked]]
32
+ request_return = AppSec::Response.negotiate(env).to_rack
33
33
  end
34
34
 
35
35
  request_return
@@ -4,7 +4,7 @@ require 'json'
4
4
 
5
5
  require_relative '../../instrumentation/gateway'
6
6
  require_relative '../../processor'
7
- require_relative '../../assets'
7
+ require_relative '../../response'
8
8
 
9
9
  require_relative '../../../tracing/client_ip'
10
10
  require_relative '../../../tracing/contrib/rack/header_collection'
@@ -40,7 +40,7 @@ module Datadog
40
40
  end
41
41
 
42
42
  if request_response && request_response.any? { |action, _event| action == :block }
43
- request_return = [403, { 'Content-Type' => 'text/html' }, [Datadog::AppSec::Assets.blocked]]
43
+ request_return = AppSec::Response.negotiate(env).to_rack
44
44
  end
45
45
 
46
46
  response = ::Rack::Response.new(request_return[2], request_return[0], request_return[1])
@@ -4,6 +4,7 @@ require_relative '../../../core/utils/only_once'
4
4
 
5
5
  require_relative '../patcher'
6
6
  require_relative 'framework'
7
+ require_relative '../../response'
7
8
  require_relative '../rack/request_middleware'
8
9
  require_relative '../rack/request_body_middleware'
9
10
  require_relative 'gateway/watcher'
@@ -83,11 +84,7 @@ module Datadog
83
84
  end
84
85
 
85
86
  if request_response && request_response.any? { |action, _event| action == :block }
86
- @_response = ::ActionDispatch::Response.new(
87
- 403,
88
- { 'Content-Type' => 'text/html' },
89
- [Datadog::AppSec::Assets.blocked]
90
- )
87
+ @_response = AppSec::Response.negotiate(env).to_action_dispatch_response
91
88
  request_return = @_response.body
92
89
  end
93
90
 
@@ -96,7 +93,7 @@ module Datadog
96
93
  end
97
94
 
98
95
  def patch_process_action
99
- ActionController::Instrumentation.prepend(ProcessActionPatch)
96
+ ::ActionController::Metal.prepend(ProcessActionPatch)
100
97
  end
101
98
 
102
99
  def include_middleware?(middleware, app)
@@ -8,6 +8,7 @@ module Datadog
8
8
  module Ext
9
9
  APP = 'sinatra'.freeze
10
10
  ENV_ENABLED = 'DD_TRACE_SINATRA_ENABLED'.freeze
11
+ ROUTE_INTERRUPT = :datadog_appsec_contrib_sinatra_route_interrupt
11
12
  end
12
13
  end
13
14
  end
@@ -11,7 +11,7 @@ module Datadog
11
11
  module Contrib
12
12
  module Sinatra
13
13
  module Gateway
14
- # Watcher for Rails gateway events
14
+ # Watcher for Sinatra gateway events
15
15
  module Watcher
16
16
  # rubocop:disable Metrics/MethodLength
17
17
  def self.watch
@@ -3,6 +3,7 @@
3
3
  require_relative '../../../tracing/contrib/rack/middlewares'
4
4
 
5
5
  require_relative '../patcher'
6
+ require_relative '../../response'
6
7
  require_relative '../rack/request_middleware'
7
8
  require_relative 'framework'
8
9
  require_relative 'gateway/watcher'
@@ -57,15 +58,12 @@ module Datadog
57
58
  # TODO: handle exceptions, except for super
58
59
 
59
60
  request_return, request_response = Instrumentation.gateway.push('sinatra.request.dispatch', request) do
60
- super
61
+ # handle process_route interruption
62
+ catch(Ext::ROUTE_INTERRUPT) { super }
61
63
  end
62
64
 
63
65
  if request_response && request_response.any? { |action, _event| action == :block }
64
- self.response = ::Sinatra::Response.new(
65
- [Datadog::AppSec::Assets.blocked],
66
- 403,
67
- { 'Content-Type' => 'text/html' }
68
- )
66
+ self.response = AppSec::Response.negotiate(env).to_sinatra_response
69
67
  request_return = nil
70
68
  end
71
69
 
@@ -94,9 +92,14 @@ module Datadog
94
92
  # At this point params has both route params and normal params.
95
93
  route_params = params.each.with_object({}) { |(k, v), h| h[k] = v unless base_params.key?(k) }
96
94
 
97
- Instrumentation.gateway.push('sinatra.request.routed', [request, route_params])
95
+ _, request_response = Instrumentation.gateway.push('sinatra.request.routed', [request, route_params])
98
96
 
99
- # TODO: handle block
97
+ if request_response && request_response.any? { |action, _event| action == :block }
98
+ self.response = AppSec::Response.negotiate(env).to_sinatra_response
99
+
100
+ # interrupt request and return response to dispatch! for consistency
101
+ throw(Ext::ROUTE_INTERRUPT, response)
102
+ end
100
103
 
101
104
  yield(*args)
102
105
  end
@@ -53,6 +53,12 @@ module Datadog
53
53
  @settings.merge(dsl)
54
54
  end
55
55
 
56
+ def ip_denylist=(arg)
57
+ dsl = AppSec::Configuration::DSL.new
58
+ dsl.ip_denylist = arg
59
+ @settings.merge(dsl)
60
+ end
61
+
56
62
  def instrument(*args)
57
63
  dsl = AppSec::Configuration::DSL.new
58
64
  dsl.instrument(*args)
@@ -86,6 +92,10 @@ module Datadog
86
92
  @settings.ruleset
87
93
  end
88
94
 
95
+ def ruledata
96
+ @settings.ruledata
97
+ end
98
+
89
99
  def waf_timeout
90
100
  @settings.waf_timeout
91
101
  end
@@ -57,7 +57,11 @@ module Datadog
57
57
 
58
58
  unless load_libddwaf && load_ruleset && create_waf_handle
59
59
  Datadog.logger.warn { 'AppSec is disabled, see logged errors above' }
60
+
61
+ return
60
62
  end
63
+
64
+ update_ip_denylist
61
65
  end
62
66
 
63
67
  def ready?
@@ -76,6 +80,20 @@ module Datadog
76
80
  @handle.toggle_rules(map)
77
81
  end
78
82
 
83
+ def update_ip_denylist(denylist = Datadog::AppSec.settings.ip_denylist, id: 'blocked_ips')
84
+ denylist ||= []
85
+
86
+ ruledata_setting = [
87
+ {
88
+ 'id' => id,
89
+ 'type' => 'data_with_expiration',
90
+ 'data' => denylist.map { |ip| { 'value' => ip.to_s, 'expiration' => 2**63 } }
91
+ }
92
+ ]
93
+
94
+ update_rule_data(ruledata_setting)
95
+ end
96
+
79
97
  def finalize
80
98
  @handle.finalize
81
99
  end
@@ -0,0 +1,54 @@
1
+ # typed: false
2
+
3
+ require_relative 'assets'
4
+
5
+ module Datadog
6
+ module AppSec
7
+ # AppSec response
8
+ class Response
9
+ attr_reader :status, :headers, :body
10
+
11
+ def initialize(status:, headers: {}, body: [])
12
+ @status = status
13
+ @headers = headers
14
+ @body = body
15
+ end
16
+
17
+ def to_rack
18
+ [status, headers, body]
19
+ end
20
+
21
+ def to_sinatra_response
22
+ ::Sinatra::Response.new(body, status, headers)
23
+ end
24
+
25
+ def to_action_dispatch_response
26
+ ::ActionDispatch::Response.new(status, headers, body)
27
+ end
28
+
29
+ class << self
30
+ def negotiate(env)
31
+ Response.new(
32
+ status: 403,
33
+ headers: { 'Content-Type' => 'text/html' },
34
+ body: [Datadog::AppSec::Assets.blocked(format: format(env))]
35
+ )
36
+ end
37
+
38
+ private
39
+
40
+ def format(env)
41
+ format = env['HTTP_ACCEPT'] && env['HTTP_ACCEPT'].split(',').any? do |accept|
42
+ if accept.start_with?('text/html')
43
+ break :html
44
+ elsif accept.start_with?('application/json')
45
+ break :json
46
+ end
47
+ end
48
+
49
+ format || :text
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -7,7 +7,7 @@ module Datadog
7
7
  module Ext
8
8
  TAG_ID = 'runtime-id'.freeze
9
9
  TAG_LANG = 'language'.freeze
10
- TAG_PID = 'system.pid'.freeze
10
+ TAG_PROCESS_ID = 'process_id'.freeze
11
11
 
12
12
  # Metrics
13
13
  # @public_api
@@ -1,15 +1,13 @@
1
1
  # typed: true
2
2
 
3
3
  require_relative '../tracing/span'
4
- require_relative '../tracing/distributed/headers/ext'
4
+ require_relative '../tracing/distributed/datadog'
5
5
 
6
6
  module Datadog
7
7
  module OpenTracer
8
8
  # DistributedHeaders provides easy access and validation to headers
9
9
  # @public_api
10
10
  class DistributedHeaders
11
- include Tracing::Distributed::Headers::Ext
12
-
13
11
  def initialize(carrier)
14
12
  @carrier = carrier
15
13
  end
@@ -20,15 +18,15 @@ module Datadog
20
18
  end
21
19
 
22
20
  def trace_id
23
- id HTTP_HEADER_TRACE_ID
21
+ id Tracing::Distributed::Datadog::TRACE_ID_KEY
24
22
  end
25
23
 
26
24
  def parent_id
27
- id HTTP_HEADER_PARENT_ID
25
+ id Tracing::Distributed::Datadog::PARENT_ID_KEY
28
26
  end
29
27
 
30
28
  def sampling_priority
31
- hdr = @carrier[HTTP_HEADER_SAMPLING_PRIORITY]
29
+ hdr = @carrier[Tracing::Distributed::Datadog::SAMPLING_PRIORITY_KEY]
32
30
  # It's important to make a difference between no header,
33
31
  # and a header defined to zero.
34
32
  return unless hdr
@@ -40,7 +38,7 @@ module Datadog
40
38
  end
41
39
 
42
40
  def origin
43
- hdr = @carrier[HTTP_HEADER_ORIGIN]
41
+ hdr = @carrier[Tracing::Distributed::Datadog::ORIGIN_KEY]
44
42
  # Only return the value if it is not an empty string
45
43
  hdr if hdr != ''
46
44
  end
@@ -1,7 +1,6 @@
1
1
  # typed: true
2
2
 
3
3
  require_relative '../tracing/context'
4
- require_relative '../tracing/distributed/headers/ext'
5
4
  require_relative '../tracing/propagation/http'
6
5
  require_relative '../tracing/trace_operation'
7
6
  require_relative 'propagator'
@@ -11,8 +10,6 @@ module Datadog
11
10
  # OpenTracing propagator for Datadog::OpenTracer::Tracer
12
11
  module RackPropagator
13
12
  extend Propagator
14
- extend Tracing::Distributed::Headers::Ext
15
- include Tracing::Distributed::Headers::Ext
16
13
 
17
14
  BAGGAGE_PREFIX = 'ot-baggage-'.freeze
18
15
  BAGGAGE_PREFIX_FORMATTED = 'HTTP_OT_BAGGAGE_'.freeze
@@ -1,7 +1,7 @@
1
1
  # typed: true
2
2
 
3
3
  require_relative '../tracing/context'
4
- require_relative '../tracing/distributed/headers/ext'
4
+ require_relative '../tracing/distributed/datadog'
5
5
  require_relative '../tracing/trace_operation'
6
6
  require_relative 'propagator'
7
7
 
@@ -10,8 +10,6 @@ module Datadog
10
10
  # OpenTracing propagator for Datadog::OpenTracer::Tracer
11
11
  module TextMapPropagator
12
12
  extend Propagator
13
- extend Tracing::Distributed::Headers::Ext
14
- include Tracing::Distributed::Headers::Ext
15
13
 
16
14
  BAGGAGE_PREFIX = 'ot-baggage-'.freeze
17
15
 
@@ -34,10 +32,10 @@ module Datadog
34
32
  end
35
33
  return unless digest
36
34
 
37
- carrier[HTTP_HEADER_ORIGIN] = digest.trace_origin
38
- carrier[HTTP_HEADER_PARENT_ID] = digest.span_id
39
- carrier[HTTP_HEADER_SAMPLING_PRIORITY] = digest.trace_sampling_priority
40
- carrier[HTTP_HEADER_TRACE_ID] = digest.trace_id
35
+ carrier[Tracing::Distributed::Datadog::ORIGIN_KEY] = digest.trace_origin
36
+ carrier[Tracing::Distributed::Datadog::PARENT_ID_KEY] = digest.span_id
37
+ carrier[Tracing::Distributed::Datadog::SAMPLING_PRIORITY_KEY] = digest.trace_sampling_priority
38
+ carrier[Tracing::Distributed::Datadog::TRACE_ID_KEY] = digest.trace_id
41
39
 
42
40
  nil
43
41
  end
@@ -23,13 +23,19 @@ module Datadog
23
23
  result
24
24
  end
25
25
 
26
+ def reset_after_fork
27
+ self.class._native_reset_after_fork(self)
28
+ end
29
+
26
30
  private
27
31
 
28
32
  def safely_extract_context_key_from(tracer)
29
- tracer &&
30
- tracer.respond_to?(:provider) &&
31
- # NOTE: instance_variable_get always works, even on nil -- it just returns nil if the variable doesn't exist
32
- tracer.provider.instance_variable_get(:@context).instance_variable_get(:@key)
33
+ provider = tracer && tracer.respond_to?(:provider) && tracer.provider
34
+
35
+ return unless provider
36
+
37
+ context = provider.instance_variable_get(:@context)
38
+ context && context.instance_variable_get(:@key)
33
39
  end
34
40
  end
35
41
  end
@@ -70,6 +70,10 @@ module Datadog
70
70
  @failure_exception = nil
71
71
  end
72
72
  end
73
+
74
+ def reset_after_fork
75
+ self.class._native_reset_after_fork(self)
76
+ end
73
77
  end
74
78
  end
75
79
  end