influx_reporter 1.0.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.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/.rspec +2 -0
- data/.rubocop.yml +51 -0
- data/.travis.yml +42 -0
- data/.yardopts +3 -0
- data/Dockerfile +9 -0
- data/Gemfile +7 -0
- data/HISTORY.md +1 -0
- data/LICENSE +14 -0
- data/README.md +189 -0
- data/Rakefile +27 -0
- data/gemfiles/Gemfile.base +29 -0
- data/gemfiles/Gemfile.rails-3.2.x +4 -0
- data/gemfiles/Gemfile.rails-4.0.x +4 -0
- data/gemfiles/Gemfile.rails-4.1.x +4 -0
- data/gemfiles/Gemfile.rails-4.2.x +5 -0
- data/gemfiles/Gemfile.rails-5.0.x +5 -0
- data/gemfiles/Gemfile.rails-HEAD +7 -0
- data/influx_reporter.gemspec +26 -0
- data/lib/influx_reporter.rb +142 -0
- data/lib/influx_reporter/client.rb +306 -0
- data/lib/influx_reporter/configuration.rb +88 -0
- data/lib/influx_reporter/data_builders.rb +18 -0
- data/lib/influx_reporter/data_builders/error.rb +52 -0
- data/lib/influx_reporter/data_builders/transactions.rb +120 -0
- data/lib/influx_reporter/error.rb +7 -0
- data/lib/influx_reporter/error_message.rb +85 -0
- data/lib/influx_reporter/error_message/exception.rb +14 -0
- data/lib/influx_reporter/error_message/http.rb +73 -0
- data/lib/influx_reporter/error_message/stacktrace.rb +76 -0
- data/lib/influx_reporter/error_message/user.rb +25 -0
- data/lib/influx_reporter/filter.rb +66 -0
- data/lib/influx_reporter/http_client.rb +140 -0
- data/lib/influx_reporter/influx_db_client.rb +74 -0
- data/lib/influx_reporter/injections.rb +89 -0
- data/lib/influx_reporter/injections/json.rb +21 -0
- data/lib/influx_reporter/injections/net_http.rb +50 -0
- data/lib/influx_reporter/injections/redis.rb +25 -0
- data/lib/influx_reporter/injections/sequel.rb +37 -0
- data/lib/influx_reporter/injections/sinatra.rb +59 -0
- data/lib/influx_reporter/integration/delayed_job.rb +30 -0
- data/lib/influx_reporter/integration/rails/inject_exceptions_catcher.rb +25 -0
- data/lib/influx_reporter/integration/railtie.rb +56 -0
- data/lib/influx_reporter/integration/resque.rb +18 -0
- data/lib/influx_reporter/integration/sidekiq.rb +130 -0
- data/lib/influx_reporter/line_cache.rb +21 -0
- data/lib/influx_reporter/logging.rb +39 -0
- data/lib/influx_reporter/middleware.rb +63 -0
- data/lib/influx_reporter/normalizers.rb +65 -0
- data/lib/influx_reporter/normalizers/action_controller.rb +34 -0
- data/lib/influx_reporter/normalizers/action_view.rb +72 -0
- data/lib/influx_reporter/normalizers/active_record.rb +45 -0
- data/lib/influx_reporter/sql_summarizer.rb +31 -0
- data/lib/influx_reporter/subscriber.rb +80 -0
- data/lib/influx_reporter/tasks.rb +28 -0
- data/lib/influx_reporter/trace.rb +48 -0
- data/lib/influx_reporter/trace_helpers.rb +31 -0
- data/lib/influx_reporter/transaction.rb +114 -0
- data/lib/influx_reporter/util.rb +18 -0
- data/lib/influx_reporter/util/constantize.rb +56 -0
- data/lib/influx_reporter/util/inspector.rb +72 -0
- data/lib/influx_reporter/util/timestamp.rb +11 -0
- data/lib/influx_reporter/version.rb +5 -0
- data/lib/influx_reporter/worker.rb +56 -0
- data/spec/influx_reporter/client_spec.rb +264 -0
- data/spec/influx_reporter/configuration_spec.rb +42 -0
- data/spec/influx_reporter/data_builders/error_spec.rb +40 -0
- data/spec/influx_reporter/data_builders/transactions_spec.rb +48 -0
- data/spec/influx_reporter/error_message/exception_spec.rb +22 -0
- data/spec/influx_reporter/error_message/http_spec.rb +55 -0
- data/spec/influx_reporter/error_message/stacktrace_spec.rb +56 -0
- data/spec/influx_reporter/error_message/user_spec.rb +26 -0
- data/spec/influx_reporter/error_message_spec.rb +102 -0
- data/spec/influx_reporter/filter_spec.rb +33 -0
- data/spec/influx_reporter/injections/net_http_spec.rb +35 -0
- data/spec/influx_reporter/injections/sequel_spec.rb +33 -0
- data/spec/influx_reporter/injections/sinatra_spec.rb +13 -0
- data/spec/influx_reporter/injections_spec.rb +50 -0
- data/spec/influx_reporter/integration/delayed_job_spec.rb +37 -0
- data/spec/influx_reporter/integration/json_spec.rb +41 -0
- data/spec/influx_reporter/integration/rails_spec.rb +92 -0
- data/spec/influx_reporter/integration/redis_spec.rb +20 -0
- data/spec/influx_reporter/integration/resque_spec.rb +42 -0
- data/spec/influx_reporter/integration/sidekiq_spec.rb +40 -0
- data/spec/influx_reporter/integration/sinatra_spec.rb +99 -0
- data/spec/influx_reporter/line_cache_spec.rb +38 -0
- data/spec/influx_reporter/logging_spec.rb +49 -0
- data/spec/influx_reporter/middleware_spec.rb +32 -0
- data/spec/influx_reporter/normalizers/action_controller_spec.rb +37 -0
- data/spec/influx_reporter/normalizers/action_view_spec.rb +78 -0
- data/spec/influx_reporter/normalizers/active_record_spec.rb +70 -0
- data/spec/influx_reporter/normalizers_spec.rb +16 -0
- data/spec/influx_reporter/sql_summarizer_spec.rb +35 -0
- data/spec/influx_reporter/subscriber_spec.rb +83 -0
- data/spec/influx_reporter/trace_spec.rb +43 -0
- data/spec/influx_reporter/transaction_spec.rb +98 -0
- data/spec/influx_reporter/util/inspector_spec.rb +41 -0
- data/spec/influx_reporter/util_spec.rb +20 -0
- data/spec/influx_reporter/worker_spec.rb +54 -0
- data/spec/influx_reporter_spec.rb +50 -0
- data/spec/spec_helper.rb +86 -0
- metadata +188 -0
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
module InfluxReporter
|
6
|
+
class Configuration
|
7
|
+
DEFAULTS = {
|
8
|
+
influx_db: {},
|
9
|
+
database: 'endpoints',
|
10
|
+
logger: Logger.new(nil),
|
11
|
+
context_lines: 3,
|
12
|
+
enabled_environments: %w[production],
|
13
|
+
excluded_exceptions: [],
|
14
|
+
filter_parameters: [/(authorization|password|passwd|secret)/i],
|
15
|
+
timeout: 100,
|
16
|
+
open_timeout: 100,
|
17
|
+
backoff_multiplier: 2,
|
18
|
+
current_user_method: :current_user,
|
19
|
+
environment: ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'default',
|
20
|
+
transaction_post_interval: 60,
|
21
|
+
worker_quit_timeout: 5,
|
22
|
+
|
23
|
+
payload_tags: [],
|
24
|
+
payload_values: [],
|
25
|
+
|
26
|
+
disable_performance: false,
|
27
|
+
disable_errors: false,
|
28
|
+
|
29
|
+
debug_traces: false,
|
30
|
+
|
31
|
+
view_paths: [],
|
32
|
+
|
33
|
+
tags: {},
|
34
|
+
|
35
|
+
# for tests
|
36
|
+
disable_worker: false
|
37
|
+
}.freeze
|
38
|
+
|
39
|
+
attr_accessor :influx_db
|
40
|
+
attr_accessor :database
|
41
|
+
attr_accessor :logger
|
42
|
+
attr_accessor :context_lines
|
43
|
+
attr_accessor :enabled_environments
|
44
|
+
attr_accessor :excluded_exceptions
|
45
|
+
attr_accessor :filter_parameters
|
46
|
+
attr_accessor :timeout
|
47
|
+
attr_accessor :open_timeout
|
48
|
+
attr_accessor :backoff_multiplier
|
49
|
+
attr_accessor :use_ssl
|
50
|
+
attr_accessor :current_user_method
|
51
|
+
attr_accessor :environment
|
52
|
+
attr_accessor :transaction_post_interval
|
53
|
+
attr_accessor :worker_quit_timeout
|
54
|
+
|
55
|
+
attr_accessor :payload_tags
|
56
|
+
attr_accessor :payload_values
|
57
|
+
|
58
|
+
attr_accessor :disable_performance
|
59
|
+
attr_accessor :disable_errors
|
60
|
+
|
61
|
+
attr_accessor :debug_traces
|
62
|
+
|
63
|
+
attr_accessor :disable_worker
|
64
|
+
|
65
|
+
attr_accessor :view_paths
|
66
|
+
|
67
|
+
attr_accessor :tags
|
68
|
+
|
69
|
+
def initialize(opts = {})
|
70
|
+
DEFAULTS.merge(opts).each do |k, v|
|
71
|
+
send("#{k}=", v)
|
72
|
+
end
|
73
|
+
|
74
|
+
yield self if block_given?
|
75
|
+
end
|
76
|
+
|
77
|
+
def validate!
|
78
|
+
%w[database influx_db tags].each do |key|
|
79
|
+
raise Error, "InfluxReporter Configuration missing `#{key}'" unless send(key)
|
80
|
+
end
|
81
|
+
|
82
|
+
true
|
83
|
+
rescue Error => e
|
84
|
+
logger.error e.message
|
85
|
+
false
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module InfluxReporter
|
4
|
+
# @api private
|
5
|
+
module DataBuilders
|
6
|
+
class DataBuilder
|
7
|
+
def initialize(config)
|
8
|
+
@config = config
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :config
|
12
|
+
end
|
13
|
+
|
14
|
+
%w[transactions error].each do |f|
|
15
|
+
require "influx_reporter/data_builders/#{f}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'influx_reporter/filter'
|
4
|
+
|
5
|
+
module InfluxReporter
|
6
|
+
module DataBuilders
|
7
|
+
class Error < DataBuilder
|
8
|
+
# @param error_message [InfluxReporter::ErrorMessage]
|
9
|
+
def build(error_message)
|
10
|
+
{
|
11
|
+
series: 'errors',
|
12
|
+
values: build_values(error_message),
|
13
|
+
tags: build_tags(error_message),
|
14
|
+
timestamp: error_message.timestamp
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
# @param error_message [InfluxReporter::ErrorMessage]
|
21
|
+
def build_tags(error_message)
|
22
|
+
tags = {
|
23
|
+
level: error_message.level,
|
24
|
+
excpetion: error_message.exception&.type,
|
25
|
+
module: error_message.exception&.module,
|
26
|
+
user_id: error_message.user&.id,
|
27
|
+
method: error_message.http&.method
|
28
|
+
}
|
29
|
+
tags = error_message.extra[:tags].merge(tags) if error_message.extra && error_message.extra[:tags].is_a?(Hash)
|
30
|
+
tags = error_message.config.tags.merge(tags)
|
31
|
+
tags.reject { |_, value| value.nil? || value == '' }
|
32
|
+
end
|
33
|
+
|
34
|
+
# @param error_message [InfluxReporter::ErrorMessage]
|
35
|
+
def build_values(error_message)
|
36
|
+
values = {
|
37
|
+
message: error_message.message,
|
38
|
+
culprit: error_message.culprit
|
39
|
+
}
|
40
|
+
if error_message.http
|
41
|
+
values[:url] = error_message.http.url
|
42
|
+
values[:user_agent] = error_message.http.user_agent
|
43
|
+
values[:user_agent] = error_message.http.user_agent
|
44
|
+
values[:uuid] = error_message.http.uuid
|
45
|
+
end
|
46
|
+
values = error_message.extra[:values].merge(values) if error_message.extra && error_message.extra[:values].is_a?(Hash)
|
47
|
+
|
48
|
+
values.reject { |_, value| value.nil? }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'influx_reporter/transaction'
|
3
|
+
|
4
|
+
module InfluxReporter
|
5
|
+
module DataBuilders
|
6
|
+
class Transactions < DataBuilder
|
7
|
+
def build(transactions)
|
8
|
+
data_points = []
|
9
|
+
transactions.each do |transaction|
|
10
|
+
data_points << build_transaction(transaction)
|
11
|
+
transaction.traces.each do |trace|
|
12
|
+
next if trace.kind == InfluxReporter::Transaction::ROOT_TRACE_NAME
|
13
|
+
data_points << build_trace(trace)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
data_points
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# @param transaction [InfluxReporter::Transaction]
|
22
|
+
def build_transaction(transaction)
|
23
|
+
{
|
24
|
+
series: series(transaction),
|
25
|
+
tags: tags(transaction),
|
26
|
+
values: values(transaction),
|
27
|
+
timestamp: transaction.timestamp
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param transaction [InfluxReporter::Transaction, InfluxReporter::Trace]
|
32
|
+
# @return [String]
|
33
|
+
def series(transaction)
|
34
|
+
transaction.kind.split('.').first(2).join('.')
|
35
|
+
end
|
36
|
+
|
37
|
+
# @param transaction [InfluxReporter::Transaction]
|
38
|
+
# @return [Hash]
|
39
|
+
def tags(transaction)
|
40
|
+
tags = {
|
41
|
+
endpoint: transaction.endpoint,
|
42
|
+
result: transaction.result.to_i,
|
43
|
+
kind: transaction.kind.split('.')[2..-1].join('.')
|
44
|
+
}
|
45
|
+
tags = (transaction.root_trace.extra[:tags] || {}).merge(tags)
|
46
|
+
tags = transaction.config.tags.merge(tags) if transaction.config
|
47
|
+
clean tags
|
48
|
+
end
|
49
|
+
|
50
|
+
# @param transaction [InfluxReporter::Transaction]
|
51
|
+
# @return [Hash]
|
52
|
+
def values(transaction)
|
53
|
+
values = {
|
54
|
+
duration: ms(transaction.duration)
|
55
|
+
}.merge(values_from_traces(transaction))
|
56
|
+
values = (transaction.root_trace.extra[:values] || {}).merge(values)
|
57
|
+
clean values
|
58
|
+
end
|
59
|
+
|
60
|
+
# @param transaction [InfluxReporter::Transaction]
|
61
|
+
# @return [Hash]
|
62
|
+
def values_from_traces(transaction)
|
63
|
+
values = {}
|
64
|
+
transaction.traces.each do |trace|
|
65
|
+
next if trace.signature == InfluxReporter::Transaction::ROOT_TRACE_NAME || trace.transaction.root_trace == trace
|
66
|
+
values["#{trace.kind}.count"] ||= 0
|
67
|
+
values["#{trace.kind}.duration"] ||= 0
|
68
|
+
values["#{trace.kind}.count"] += 1
|
69
|
+
values["#{trace.kind}.duration"] += ms(trace.duration)
|
70
|
+
end
|
71
|
+
values
|
72
|
+
end
|
73
|
+
|
74
|
+
# @param trace [InfluxReporter::Trace]
|
75
|
+
# @return [Hash]
|
76
|
+
def build_trace(trace)
|
77
|
+
{
|
78
|
+
series: "trace.#{trace.kind.split('.').first}",
|
79
|
+
tags: trace_tags(trace),
|
80
|
+
values: trace_values(trace),
|
81
|
+
timestamp: trace.timestamp
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
# @param trace [InfluxReporter::Trace]
|
86
|
+
def trace_tags(trace)
|
87
|
+
tags = {
|
88
|
+
endpoint: trace.transaction.endpoint,
|
89
|
+
signature: trace.signature,
|
90
|
+
kind: trace.kind.split('.')[1..-1].join('.')
|
91
|
+
}
|
92
|
+
tags = (trace.transaction.root_trace.extra[:tags] || {}).merge(trace.extra[:tags] || {}).merge(tags)
|
93
|
+
tags = trace.transaction.config.tags.merge(tags) if trace.transaction.config
|
94
|
+
clean tags
|
95
|
+
end
|
96
|
+
|
97
|
+
# @param trace [InfluxReporter::Trace]
|
98
|
+
|
99
|
+
def trace_values(trace)
|
100
|
+
values = {
|
101
|
+
duration: ms(trace.duration),
|
102
|
+
start_time: ms(trace.relative_start)
|
103
|
+
}
|
104
|
+
values = (trace.extra[:values] || {}).merge(values)
|
105
|
+
values[:uuid] ||= trace.transaction.root_trace.extra[:values][:uuid] if trace.transaction.root_trace.extra[:values]
|
106
|
+
clean values
|
107
|
+
end
|
108
|
+
|
109
|
+
# @param hash [Hash]
|
110
|
+
# @return [Hash]
|
111
|
+
def clean(hash)
|
112
|
+
hash.reject { |_, value| value.nil? || value == '' }
|
113
|
+
end
|
114
|
+
|
115
|
+
def ms(nanos)
|
116
|
+
nanos.to_f / 1_000_000
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'influx_reporter/line_cache'
|
4
|
+
require 'influx_reporter/error_message/exception'
|
5
|
+
require 'influx_reporter/error_message/stacktrace'
|
6
|
+
require 'influx_reporter/error_message/http'
|
7
|
+
require 'influx_reporter/error_message/user'
|
8
|
+
require 'influx_reporter/util/timestamp'
|
9
|
+
|
10
|
+
module InfluxReporter
|
11
|
+
class ErrorMessage
|
12
|
+
extend Logging
|
13
|
+
|
14
|
+
DEFAULTS = {
|
15
|
+
level: :error,
|
16
|
+
logger: 'root'
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
def initialize(config, message, attrs = {})
|
20
|
+
@config = config
|
21
|
+
|
22
|
+
@message = message
|
23
|
+
@timestamp = Util.nanos
|
24
|
+
|
25
|
+
DEFAULTS.merge(attrs).each do |k, v|
|
26
|
+
send(:"#{k}=", v)
|
27
|
+
end
|
28
|
+
@filter = Filter.new config
|
29
|
+
|
30
|
+
yield self if block_given?
|
31
|
+
end
|
32
|
+
|
33
|
+
attr_reader :config
|
34
|
+
attr_accessor :message
|
35
|
+
attr_reader :timestamp
|
36
|
+
attr_reader :filter
|
37
|
+
attr_accessor :level
|
38
|
+
attr_accessor :logger
|
39
|
+
attr_accessor :culprit
|
40
|
+
attr_accessor :machine
|
41
|
+
attr_accessor :extra
|
42
|
+
attr_accessor :param_message
|
43
|
+
attr_accessor :exception
|
44
|
+
attr_accessor :stacktrace
|
45
|
+
attr_accessor :http
|
46
|
+
attr_accessor :user
|
47
|
+
|
48
|
+
def self.from_exception(config, exception, opts = {})
|
49
|
+
message = "#{exception.class}: #{exception.message}"
|
50
|
+
|
51
|
+
if config.excluded_exceptions.include? exception.class.to_s
|
52
|
+
info "Skipping excluded exception #{exception.class}"
|
53
|
+
return nil
|
54
|
+
end
|
55
|
+
|
56
|
+
error_message = new(config, message) do |msg|
|
57
|
+
msg.level = :error
|
58
|
+
msg.exception = Exception.from(exception)
|
59
|
+
msg.stacktrace = Stacktrace.from(config, exception)
|
60
|
+
end
|
61
|
+
|
62
|
+
if frames = error_message.stacktrace&.frames
|
63
|
+
if first_frame = frames.last
|
64
|
+
error_message.culprit = "#{first_frame.filename}:#{first_frame.lineno}:in `#{first_frame.function}'"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
if env = opts[:rack_env]
|
69
|
+
error_message.http = HTTP.from_rack_env env, filter: error_message.filter
|
70
|
+
error_message.user = User.from_rack_env config, env
|
71
|
+
end
|
72
|
+
|
73
|
+
if extra = opts[:extra]
|
74
|
+
error_message.extra = extra
|
75
|
+
end
|
76
|
+
|
77
|
+
error_message
|
78
|
+
end
|
79
|
+
|
80
|
+
def add_extra(info)
|
81
|
+
@extra ||= {}
|
82
|
+
@extra.merge! info
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module InfluxReporter
|
4
|
+
class ErrorMessage
|
5
|
+
class Exception < Struct.new(:type, :value, :module)
|
6
|
+
SPLIT = '::'
|
7
|
+
|
8
|
+
def self.from(exception)
|
9
|
+
new exception.class.to_s, exception.message,
|
10
|
+
exception.class.to_s.split(SPLIT)[0...-1].join(SPLIT)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module InfluxReporter
|
4
|
+
class ErrorMessage
|
5
|
+
class HTTP < Struct.new(:url, :method, :data, :query_string, :cookies,
|
6
|
+
:headers, :remote_host, :http_host, :user_agent,
|
7
|
+
:secure, :env, :uuid)
|
8
|
+
|
9
|
+
HTTP_ENV_KEY = /^HTTP_/
|
10
|
+
UNDERSCORE = '_'
|
11
|
+
|
12
|
+
DASH = '-'
|
13
|
+
QUESTION = '?'
|
14
|
+
|
15
|
+
def self.from_rack_env(env, opts = {})
|
16
|
+
req = if defined?(ActionDispatch::Request) && env.is_a?(ActionDispatch::Request)
|
17
|
+
env
|
18
|
+
else
|
19
|
+
Rack::Request.new env
|
20
|
+
end
|
21
|
+
|
22
|
+
http = new(
|
23
|
+
req.url.split(QUESTION).first, # url
|
24
|
+
req.request_method, # method
|
25
|
+
nil, # data
|
26
|
+
req.query_string, # query string
|
27
|
+
env['HTTP_COOKIE'], # cookies
|
28
|
+
{}, # headers
|
29
|
+
req.ip, # remote host
|
30
|
+
req.host_with_port, # http host
|
31
|
+
req.user_agent, # user agent
|
32
|
+
req.scheme == 'https', # secure
|
33
|
+
{}, # env
|
34
|
+
req.respond_to?(:uuid) ? req.uuid : nil
|
35
|
+
)
|
36
|
+
|
37
|
+
# In Rails < 5 ActionDispatch::Request inherits from Hash
|
38
|
+
headers = env.respond_to?(:headers) ? env.headers : env
|
39
|
+
|
40
|
+
headers.each do |k, v|
|
41
|
+
next unless k.upcase == k # lower case stuff isn't relevant
|
42
|
+
|
43
|
+
if k.match(HTTP_ENV_KEY)
|
44
|
+
header = k.gsub(HTTP_ENV_KEY, '')
|
45
|
+
.split(UNDERSCORE).map(&:capitalize).join(DASH)
|
46
|
+
http.headers[header] = v.to_s
|
47
|
+
else
|
48
|
+
http.env[k] = v.to_s
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
if req.form_data?
|
53
|
+
http.data = req.POST
|
54
|
+
elsif req.body
|
55
|
+
http.data = req.body.read
|
56
|
+
req.body.rewind
|
57
|
+
end
|
58
|
+
|
59
|
+
if filter = opts[:filter]
|
60
|
+
http.apply_filter filter
|
61
|
+
end
|
62
|
+
|
63
|
+
http
|
64
|
+
end
|
65
|
+
|
66
|
+
def apply_filter(filter)
|
67
|
+
self.data = filter.apply data
|
68
|
+
self.query_string = filter.apply query_string
|
69
|
+
self.cookies = filter.apply cookies
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|