tshield 0.13.5.0 → 0.14.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 +4 -4
- data/lib/tshield/configuration.rb +2 -5
- data/lib/tshield/controllers/requests.rb +0 -1
- data/lib/tshield/grpc/grpc_counter.rb +24 -0
- data/lib/tshield/grpc/vcr.rb +73 -25
- data/lib/tshield/grpc.rb +3 -3
- data/lib/tshield/logger.rb +1 -1
- data/lib/tshield/request_vcr.rb +5 -4
- data/lib/tshield/sessions.rb +2 -0
- data/lib/tshield/version.rb +2 -2
- data/spec/tshield/configuration_spec.rb +2 -3
- data/spec/tshield/controllers/requests_spec.rb +18 -20
- data/spec/tshield/request_vcr_spec.rb +18 -22
- metadata +13 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 83eb12f572bdfd5f6fade21d83ee7d4883253aa9e42cad7fe0e9feac380d7ae6
|
4
|
+
data.tar.gz: c1718a13671ee6899321dcda86c6d6dbaad23c1389cc24c0b6ea3b684024c725
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 003b70dbe21e80655ebfe6eae9e0260137a3f6e3e478200c04eefbc238ae72d8d172b62c4d980a934fd56a08eb7d2ad59d93b4d762a3c019e88d3e2e6cc39d46
|
7
|
+
data.tar.gz: 6c4ada87361e89edff1b8fe7353389861c3748986631ad9693d01f148c71fb2dbe06547b318d94c3247dc584081c047fc915f5d1d014d6026172b8cf406b5753
|
@@ -29,10 +29,7 @@ module TShield
|
|
29
29
|
# generated directory
|
30
30
|
#
|
31
31
|
attr_reader :request
|
32
|
-
attr_reader :domains
|
33
|
-
attr_reader :tcp_servers
|
34
|
-
attr_reader :session_path
|
35
|
-
attr_reader :windows_compatibility
|
32
|
+
attr_reader :domains, :tcp_servers, :session_path, :windows_compatibility
|
36
33
|
|
37
34
|
def initialize(attributes)
|
38
35
|
attributes.each { |key, value| instance_variable_set("@#{key}", value) }
|
@@ -106,6 +103,7 @@ module TShield
|
|
106
103
|
|
107
104
|
def send_header_content_type(domain)
|
108
105
|
return domains[domain]['send_header_content_type'] != false if domains[domain]
|
106
|
+
|
109
107
|
true
|
110
108
|
end
|
111
109
|
|
@@ -140,6 +138,5 @@ module TShield
|
|
140
138
|
def get_delay(domain, path)
|
141
139
|
((domains[domain] || {})['delay'] || {})[path] || 0
|
142
140
|
end
|
143
|
-
|
144
141
|
end
|
145
142
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TShield
|
4
|
+
# Increment counter for sessions requests
|
5
|
+
class GrpcCounter
|
6
|
+
def initialize
|
7
|
+
@requests = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def add(hexdigest)
|
11
|
+
count = @requests.fetch(hexdigest, 0)
|
12
|
+
count += 1
|
13
|
+
@requests[hexdigest] = count
|
14
|
+
end
|
15
|
+
|
16
|
+
def current(hexdigest)
|
17
|
+
@requests.fetch(hexdigest, 0)
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_json(options = {})
|
21
|
+
@requests.to_json(options)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/tshield/grpc/vcr.rb
CHANGED
@@ -5,79 +5,127 @@ require 'tshield/sessions'
|
|
5
5
|
|
6
6
|
module TShield
|
7
7
|
module Grpc
|
8
|
+
# Grpc vcr module
|
8
9
|
module VCR
|
10
|
+
# Path file to save Grpc request/response
|
11
|
+
class FilePath
|
12
|
+
attr_reader :path, :count
|
13
|
+
|
14
|
+
def initialize(path, count)
|
15
|
+
@path = path
|
16
|
+
@count = count
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
9
20
|
def initialize
|
10
21
|
@configuration = TShield::Configuration.singleton
|
11
22
|
end
|
23
|
+
|
12
24
|
def handler_in_vcr_mode(method_name, request, parameters, options)
|
13
25
|
parameters.peer =~ /ipv6:\[(.+?)\]|ipv4:(.+?):/
|
14
26
|
peer = Regexp.last_match(1) || Regexp.last_match(2)
|
15
27
|
|
16
28
|
TShield.logger.info("request from #{parameters.peer}")
|
17
29
|
@session = TShield::Sessions.current(peer)
|
30
|
+
@digest = hexdigest(request)
|
31
|
+
counter = @session ? request_count.current(@digest) : 0
|
18
32
|
|
19
33
|
TShield.logger.info("grpc using session #{@session || 'default'}")
|
20
34
|
module_name = options['module']
|
21
35
|
|
22
|
-
path = create_destiny(module_name, method_name
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
36
|
+
path = create_destiny(module_name, method_name)
|
37
|
+
@file_path = FilePath.new(path, counter)
|
38
|
+
save_request(request)
|
39
|
+
response = {}
|
40
|
+
saved_error
|
41
|
+
begin
|
42
|
+
response = saved_response
|
43
|
+
if response
|
44
|
+
TShield.logger.info("returning saved response for request #{request.to_json} saved into #{@digest}")
|
45
|
+
request_count.add(@digest) if @session
|
46
|
+
return response
|
47
|
+
end
|
48
|
+
|
49
|
+
response = send_request(request, module_name, options, method_name)
|
50
|
+
save_response(response)
|
51
|
+
rescue GRPC::BadStatus => e
|
52
|
+
save_error({ code: e.code, details: e.details })
|
53
|
+
raise e
|
28
54
|
end
|
55
|
+
request_count.add(@digest) if @session
|
56
|
+
response
|
57
|
+
end
|
29
58
|
|
59
|
+
def send_request(request, module_name, options, method_name)
|
30
60
|
TShield.logger.info("calling server to get response for #{request.to_json}")
|
31
61
|
client_class = Object.const_get("#{module_name}::Stub")
|
32
62
|
client_instance = client_class.new(options['hostname'], :this_channel_is_insecure)
|
33
|
-
|
34
|
-
|
35
|
-
|
63
|
+
client_instance.send(method_name, request)
|
64
|
+
end
|
65
|
+
|
66
|
+
def request_count
|
67
|
+
@session[:grpc_counter]
|
36
68
|
end
|
37
69
|
|
38
70
|
def encode_colon(value)
|
39
|
-
value.gsub(':','%3a')
|
71
|
+
value.gsub(':', '%3a')
|
40
72
|
end
|
41
73
|
|
42
|
-
def saved_response
|
43
|
-
response_file = File.join(path,
|
74
|
+
def saved_response
|
75
|
+
response_file = File.join(@file_path.path, "#{@file_path.count}.response")
|
44
76
|
return false unless File.exist? response_file
|
45
77
|
|
46
78
|
content = JSON.parse File.open(response_file).read
|
47
|
-
response_class = File.open(File.join(path,
|
79
|
+
response_class = File.open(File.join(@file_path.path, "#{@file_path.count}.response_class")).read.strip
|
48
80
|
Kernel.const_get(response_class).new(content)
|
49
81
|
end
|
50
82
|
|
51
|
-
def
|
52
|
-
|
83
|
+
def saved_error
|
84
|
+
error_file = File.join(@file_path.path, "#{@file_path.count}.error")
|
85
|
+
return false unless File.exist? error_file
|
86
|
+
|
87
|
+
request_count.add(@digest) if @session
|
88
|
+
content = JSON.parse File.open(error_file).read
|
89
|
+
grpc_error = GRPC::BadStatus.new(content['code'], content['details'])
|
90
|
+
raise grpc_error
|
91
|
+
end
|
92
|
+
|
93
|
+
def save_request(request)
|
94
|
+
file = File.open(File.join(@file_path.path, "#{@file_path.count}.original_request"), 'w')
|
53
95
|
file.puts request.to_json
|
54
96
|
file.close
|
55
97
|
end
|
56
98
|
|
57
|
-
def
|
58
|
-
file = File.open(File.join(path,
|
99
|
+
def save_error(error)
|
100
|
+
file = File.open(File.join(@file_path.path, "#{@file_path.count}.error"), 'w')
|
101
|
+
file.puts error.to_json
|
102
|
+
file.close
|
103
|
+
request_count.add(@digest) if @session
|
104
|
+
end
|
105
|
+
|
106
|
+
def save_response(response)
|
107
|
+
file = File.open(File.join(@file_path.path, "#{@file_path.count}.response"), 'w')
|
59
108
|
file.puts response.to_json
|
60
109
|
file.close
|
61
110
|
|
62
|
-
response_class = File.open(File.join(path,
|
111
|
+
response_class = File.open(File.join(@file_path.path, "#{@file_path.count}.response_class"), 'w')
|
63
112
|
response_class.puts response.class.to_s
|
64
113
|
response_class.close
|
65
114
|
end
|
66
115
|
|
67
|
-
def complete_path(module_name, method_name
|
116
|
+
def complete_path(module_name, method_name)
|
68
117
|
@session_name = (@session || {})[:name]
|
69
118
|
module_name = @configuration.windows_compatibility? ? encode_colon(module_name) : module_name
|
70
|
-
|
71
|
-
path
|
119
|
+
['requests', @session_name, module_name, method_name.to_s, @digest].compact
|
72
120
|
end
|
73
121
|
|
74
|
-
def create_destiny(module_name, method_name
|
122
|
+
def create_destiny(module_name, method_name)
|
75
123
|
current_path = []
|
76
124
|
|
77
|
-
path = complete_path(module_name, method_name
|
125
|
+
path = complete_path(module_name, method_name)
|
78
126
|
TShield.logger.info("using path #{path}")
|
79
|
-
path.each do |
|
80
|
-
current_path <<
|
127
|
+
path.each do |inner_path|
|
128
|
+
current_path << inner_path
|
81
129
|
destiny = File.join current_path
|
82
130
|
Dir.mkdir destiny unless File.exist? destiny
|
83
131
|
end
|
data/lib/tshield/grpc.rb
CHANGED
@@ -4,7 +4,6 @@ require 'grpc'
|
|
4
4
|
|
5
5
|
require 'tshield/configuration'
|
6
6
|
require 'tshield/grpc/vcr'
|
7
|
-
|
8
7
|
module TShield
|
9
8
|
module Grpc
|
10
9
|
module RequestHandler
|
@@ -14,6 +13,7 @@ module TShield
|
|
14
13
|
handler_in_vcr_mode(method_name, request, parameters, options)
|
15
14
|
end
|
16
15
|
end
|
16
|
+
|
17
17
|
def self.run!
|
18
18
|
@configuration = TShield::Configuration.singleton.grpc
|
19
19
|
|
@@ -41,6 +41,7 @@ module TShield
|
|
41
41
|
handlers = []
|
42
42
|
number_of_handlers = 0
|
43
43
|
services.each do |file, options|
|
44
|
+
|
44
45
|
require file
|
45
46
|
|
46
47
|
base = Object.const_get("#{options['module']}::Service")
|
@@ -55,8 +56,7 @@ module TShield
|
|
55
56
|
def self.build_handler(base, descriptions, number_of_handlers, options)
|
56
57
|
handler = Class.new(base) do
|
57
58
|
class << self
|
58
|
-
|
59
|
-
attr_reader :options
|
59
|
+
attr_accessor :options
|
60
60
|
end
|
61
61
|
descriptions.each do |service_name, description|
|
62
62
|
puts description
|
data/lib/tshield/logger.rb
CHANGED
data/lib/tshield/request_vcr.rb
CHANGED
@@ -79,7 +79,6 @@ module TShield
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def apply_set_cookie_header_values(raw_response, headers = {})
|
82
|
-
|
83
82
|
headers_clone = headers.clone
|
84
83
|
|
85
84
|
field = raw_response.get_fields('Set-Cookie')
|
@@ -98,6 +97,7 @@ module TShield
|
|
98
97
|
|
99
98
|
raw_response.headers.each do |k, v|
|
100
99
|
next if k == 'set-cookie'
|
100
|
+
|
101
101
|
headers[k] = v unless configuration.not_save_headers(domain).include? k
|
102
102
|
end
|
103
103
|
|
@@ -156,9 +156,10 @@ module TShield
|
|
156
156
|
end
|
157
157
|
|
158
158
|
def encode_for_windows_dir(directory)
|
159
|
-
replace = [['<','%3c'],['>','%3e'],[':','%3a'],['"','%22'],['?','%3f'],[' ','%20'],['*','%2a'],
|
159
|
+
replace = [['<', '%3c'], ['>', '%3e'], [':', '%3a'], ['"', '%22'], ['?', '%3f'], [' ', '%20'], ['*', '%2a'],
|
160
|
+
['/', '%2f']]
|
160
161
|
replace.each do |value|
|
161
|
-
directory = directory.gsub(value.first,value.last)
|
162
|
+
directory = directory.gsub(value.first, value.last)
|
162
163
|
end
|
163
164
|
directory
|
164
165
|
end
|
@@ -171,7 +172,7 @@ module TShield
|
|
171
172
|
else
|
172
173
|
directory = url.gsub(%r{/}, '-').gsub(/^-/, '')
|
173
174
|
end
|
174
|
-
|
175
|
+
configuration.windows_compatibility? ? encode_for_windows_dir(directory) : directory
|
175
176
|
end
|
176
177
|
end
|
177
178
|
end
|
data/lib/tshield/sessions.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'tshield/logger'
|
4
4
|
require 'tshield/counter'
|
5
|
+
require 'tshield/grpc/grpc_counter'
|
5
6
|
require 'tshield/errors'
|
6
7
|
|
7
8
|
module TShield
|
@@ -14,6 +15,7 @@ module TShield
|
|
14
15
|
sessions[normalize_ip(ip)] = {
|
15
16
|
name: name,
|
16
17
|
counter: TShield::Counter.new,
|
18
|
+
grpc_counter: TShield::GrpcCounter.new,
|
17
19
|
secondary_sessions: []
|
18
20
|
}
|
19
21
|
end
|
data/lib/tshield/version.rb
CHANGED
@@ -67,7 +67,7 @@ describe TShield::Configuration do
|
|
67
67
|
|
68
68
|
describe 'SO compatibility' do
|
69
69
|
it 'should be compatible with windows when configuration is true' do
|
70
|
-
allow(YAML).to receive(:safe_load).and_return({:
|
70
|
+
allow(YAML).to receive(:safe_load).and_return({ windows_compatibility: true })
|
71
71
|
TShield::Configuration.clear
|
72
72
|
@configuration = TShield::Configuration.singleton
|
73
73
|
|
@@ -75,7 +75,7 @@ describe TShield::Configuration do
|
|
75
75
|
end
|
76
76
|
|
77
77
|
it 'should be compatible with Unix when configuration is false' do
|
78
|
-
allow(YAML).to receive(:safe_load).and_return({:
|
78
|
+
allow(YAML).to receive(:safe_load).and_return({ windows_compatibility: false })
|
79
79
|
TShield::Configuration.clear
|
80
80
|
@configuration = TShield::Configuration.singleton
|
81
81
|
|
@@ -89,7 +89,6 @@ describe TShield::Configuration do
|
|
89
89
|
|
90
90
|
expect(@configuration.windows_compatibility?).to eq(false)
|
91
91
|
end
|
92
|
-
|
93
92
|
end
|
94
93
|
end
|
95
94
|
context 'on config not exist' do
|
@@ -73,7 +73,6 @@ describe TShield::Controllers::Requests do
|
|
73
73
|
allow(@configuration).to receive(:get_domain_for).and_return('example.org')
|
74
74
|
allow(@configuration).to receive(:get_delay).and_return(0)
|
75
75
|
|
76
|
-
|
77
76
|
allow(TShield::Options).to receive_message_chain(:instance, :break?)
|
78
77
|
@mock_logger = double
|
79
78
|
@controller = MockController.new(@mock_logger)
|
@@ -100,15 +99,15 @@ describe TShield::Controllers::Requests do
|
|
100
99
|
allow(matched_response).to receive(:body).and_return('')
|
101
100
|
allow(@mock_logger).to receive(:info)
|
102
101
|
|
103
|
-
expect(TShield::RequestVCR).to receive(:new).with(
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
102
|
+
expect(TShield::RequestVCR).to receive(:new).with('/', {
|
103
|
+
call: 0,
|
104
|
+
headers: {},
|
105
|
+
ip: '0.0.0.0',
|
106
|
+
method: 'GET',
|
107
|
+
raw_query: 'a=b',
|
108
|
+
secondary_sessions: nil,
|
109
|
+
session: nil
|
110
|
+
})
|
112
111
|
@controller.treat(params, request, nil)
|
113
112
|
end
|
114
113
|
end
|
@@ -135,16 +134,15 @@ describe TShield::Controllers::Requests do
|
|
135
134
|
allow(matched_response).to receive(:body).and_return('')
|
136
135
|
allow(@mock_logger).to receive(:info)
|
137
136
|
|
138
|
-
expect(TShield::RequestVCR).to receive(:new).with(
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
137
|
+
expect(TShield::RequestVCR).to receive(:new).with('/', {
|
138
|
+
call: 0,
|
139
|
+
headers: { 'Content-Type' => 'application/json' },
|
140
|
+
ip: '0.0.0.0',
|
141
|
+
method: 'GET',
|
142
|
+
raw_query: 'a=b',
|
143
|
+
secondary_sessions: nil,
|
144
|
+
session: nil
|
145
|
+
})
|
148
146
|
|
149
147
|
@controller.treat(params, request, nil)
|
150
148
|
end
|
@@ -107,9 +107,9 @@ describe TShield::RequestVCR do
|
|
107
107
|
|
108
108
|
it 'should create response directory in windows standard' do
|
109
109
|
allow(@configuration).to receive(:domains).and_return(
|
110
|
-
|
111
|
-
|
112
|
-
|
110
|
+
'example.org' => {
|
111
|
+
'skip_query_params' => []
|
112
|
+
}
|
113
113
|
)
|
114
114
|
|
115
115
|
allow(@configuration).to receive(:windows_compatibility?).and_return(true)
|
@@ -118,28 +118,28 @@ describe TShield::RequestVCR do
|
|
118
118
|
file_double = double
|
119
119
|
|
120
120
|
allow(File).to receive(:join)
|
121
|
-
|
122
|
-
|
121
|
+
.with('./requests/example.org', '%3fparam=value')
|
122
|
+
.and_return('./requests/example.org/%3fparam=value')
|
123
123
|
allow(File).to receive(:join)
|
124
|
-
|
125
|
-
|
124
|
+
.with('./requests/example.org/%3fparam=value', 'get')
|
125
|
+
.and_return('./requests/example.org/%3fparam=value/get')
|
126
126
|
allow(File).to receive(:join)
|
127
|
-
|
128
|
-
|
127
|
+
.with('./requests/example.org/%3fparam=value/get', '0')
|
128
|
+
.and_return('./requests/example.org/%3fparam=value/get/0')
|
129
129
|
|
130
130
|
allow(file_double).to receive(:read).and_return('{}')
|
131
131
|
|
132
132
|
expect(File).to receive('open')
|
133
|
-
|
134
|
-
|
133
|
+
.with('./requests/example.org/%3fparam=value/get/0.content', 'w')
|
134
|
+
.and_return(file_double)
|
135
135
|
|
136
136
|
expect(File).to receive('open')
|
137
|
-
|
138
|
-
|
137
|
+
.with('./requests/example.org/%3fparam=value/get/0.json', 'w')
|
138
|
+
.and_return(file_double)
|
139
139
|
|
140
140
|
expect(file_double).to receive(:write).ordered.with('this is the body')
|
141
141
|
expect(file_double).to receive(:write)
|
142
|
-
|
142
|
+
.with("{\n \"status\": 200,\n \"headers\": {\n }\n}")
|
143
143
|
expect(file_double).to receive(:close)
|
144
144
|
expect(file_double).to receive(:close)
|
145
145
|
|
@@ -148,7 +148,6 @@ describe TShield::RequestVCR do
|
|
148
148
|
method: 'GET',
|
149
149
|
call: 0
|
150
150
|
end
|
151
|
-
|
152
151
|
end
|
153
152
|
end
|
154
153
|
|
@@ -161,7 +160,7 @@ describe TShield::RequestVCR do
|
|
161
160
|
'this is the body'
|
162
161
|
end
|
163
162
|
|
164
|
-
def get_fields(
|
163
|
+
def get_fields(_field = '')
|
165
164
|
[]
|
166
165
|
end
|
167
166
|
|
@@ -172,22 +171,19 @@ describe TShield::RequestVCR do
|
|
172
171
|
|
173
172
|
class RawResponseCookiesMultipleValues
|
174
173
|
def headers
|
175
|
-
|
174
|
+
{ 'Set-Cookie' => ['FirstCookie=An Value', 'SecondCookie=An Value'] }
|
176
175
|
end
|
177
176
|
|
178
177
|
def body
|
179
178
|
'this is the body'
|
180
179
|
end
|
181
180
|
|
182
|
-
def get_fields(field =
|
183
|
-
|
181
|
+
def get_fields(field = '')
|
182
|
+
headers[filed] unless headers.key?(field)
|
184
183
|
end
|
185
184
|
|
186
185
|
def code
|
187
186
|
200
|
188
187
|
end
|
189
188
|
end
|
190
|
-
|
191
189
|
end
|
192
|
-
|
193
|
-
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tshield
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Diego Rubin
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-
|
12
|
+
date: 2021-10-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: grpc
|
@@ -415,6 +415,7 @@ files:
|
|
415
415
|
- lib/tshield/errors.rb
|
416
416
|
- lib/tshield/extensions/string_extensions.rb
|
417
417
|
- lib/tshield/grpc.rb
|
418
|
+
- lib/tshield/grpc/grpc_counter.rb
|
418
419
|
- lib/tshield/grpc/vcr.rb
|
419
420
|
- lib/tshield/logger.rb
|
420
421
|
- lib/tshield/matching/filters.rb
|
@@ -467,19 +468,19 @@ signing_key:
|
|
467
468
|
specification_version: 4
|
468
469
|
summary: Proxy for mocks API responses
|
469
470
|
test_files:
|
470
|
-
- spec/
|
471
|
+
- spec/spec_helper.rb
|
472
|
+
- spec/tshield/request_matching_spec.rb
|
473
|
+
- spec/tshield/sessions_spec.rb
|
474
|
+
- spec/tshield/request_vcr_spec.rb
|
471
475
|
- spec/tshield/after_filter_spec.rb
|
472
|
-
- spec/tshield/
|
473
|
-
- spec/tshield/
|
476
|
+
- spec/tshield/grpc_spec.rb
|
477
|
+
- spec/tshield/options_spec.rb
|
474
478
|
- spec/tshield/fixtures/config/tshield-without-grpc.yml
|
475
479
|
- spec/tshield/fixtures/config/tshield-with-send-content-type-header_as_false.yml
|
476
|
-
- spec/tshield/fixtures/config/tshield.yml
|
477
480
|
- spec/tshield/fixtures/config/tshield-with-send-content-type-header.yml
|
481
|
+
- spec/tshield/fixtures/config/tshield.yml
|
482
|
+
- spec/tshield/fixtures/proto/test_services_pb.rb
|
478
483
|
- spec/tshield/fixtures/matching/example.json
|
479
484
|
- spec/tshield/fixtures/filters/example_filter.rb
|
480
|
-
- spec/tshield/
|
481
|
-
- spec/tshield/
|
482
|
-
- spec/tshield/grpc_spec.rb
|
483
|
-
- spec/tshield/options_spec.rb
|
484
|
-
- spec/tshield/request_matching_spec.rb
|
485
|
-
- spec/spec_helper.rb
|
485
|
+
- spec/tshield/controllers/requests_spec.rb
|
486
|
+
- spec/tshield/configuration_spec.rb
|