ddtrace 1.6.0 → 1.7.0

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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +50 -1
  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/redis/integration.rb +2 -1
  64. data/lib/datadog/tracing/contrib/redis/patcher.rb +2 -3
  65. data/lib/datadog/tracing/contrib/resque/resque_job.rb +2 -0
  66. data/lib/datadog/tracing/contrib/shoryuken/tracer.rb +2 -0
  67. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +5 -0
  68. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +5 -0
  69. data/lib/datadog/tracing/contrib/sneakers/tracer.rb +2 -0
  70. data/lib/datadog/tracing/distributed/b3.rb +66 -0
  71. data/lib/datadog/tracing/distributed/b3_single.rb +66 -0
  72. data/lib/datadog/tracing/distributed/datadog.rb +153 -0
  73. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +1 -0
  74. data/lib/datadog/tracing/distributed/fetcher.rb +30 -0
  75. data/lib/datadog/tracing/distributed/headers/ext.rb +18 -16
  76. data/lib/datadog/tracing/distributed/helpers.rb +7 -6
  77. data/lib/datadog/tracing/distributed/propagation.rb +127 -0
  78. data/lib/datadog/tracing/propagation/http.rb +3 -106
  79. data/lib/datadog/tracing/trace_segment.rb +1 -1
  80. data/lib/ddtrace/transport/trace_formatter.rb +2 -5
  81. data/lib/ddtrace/version.rb +1 -1
  82. metadata +19 -14
  83. data/lib/datadog/tracing/distributed/headers/b3.rb +0 -55
  84. data/lib/datadog/tracing/distributed/headers/b3_single.rb +0 -67
  85. data/lib/datadog/tracing/distributed/headers/datadog.rb +0 -144
  86. data/lib/datadog/tracing/distributed/headers/parser.rb +0 -37
  87. data/lib/datadog/tracing/distributed/metadata/b3.rb +0 -55
  88. data/lib/datadog/tracing/distributed/metadata/b3_single.rb +0 -66
  89. data/lib/datadog/tracing/distributed/metadata/datadog.rb +0 -73
  90. data/lib/datadog/tracing/distributed/metadata/parser.rb +0 -34
  91. 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