grpc_reflection 0.4.0 → 0.5.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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '083f05c2730db17b2d790b16084a54c3b3e165607265747e564adc26b72d71b3'
|
|
4
|
+
data.tar.gz: 4d9033ce323235fc76ffbd6bb0bc43ba218fb166479e0a4347b12eec2604ccba
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 957c82b81d874bed400ccd707580b41c266d80f9a240fe7f81d21067e285ed5d508c24a362f274697168c0002aaa302669ea1c3341465018bb163980fd164f51
|
|
7
|
+
data.tar.gz: 5a6a5a469ea8829baf149b97888a8eb68e58bc1e229553a186cd6308256e54cf2db3511934114a02fbee92e91e5ef342c721c71360236046f8f65270debb9e2c
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
## 0.5.0
|
|
2
|
+
|
|
3
|
+
* Support multiple requests #24
|
|
4
|
+
* Find the RpcServer actually hosting the reflection service- #23
|
|
5
|
+
* Return error_response for not-found and invalid reflection requests #21
|
|
6
|
+
* Fix file_containing_extension to look up by extendee type, not extension name #20
|
|
7
|
+
* Fix symbol resolution for services/methods defined without a package #19
|
|
8
|
+
* Fix symbol lookup cache for non-dataset symbols #18
|
|
9
|
+
|
|
1
10
|
## 0.4.0
|
|
2
11
|
|
|
3
12
|
* Support `file_containing_extension` request #14
|
|
@@ -6,7 +6,7 @@ require "google/protobuf/descriptor_pb"
|
|
|
6
6
|
|
|
7
7
|
module GrpcReflection
|
|
8
8
|
class FileDescriptorDecorator
|
|
9
|
-
attr_reader :dataset, :serialized_file, :filename, :dependency
|
|
9
|
+
attr_reader :dataset, :serialized_file, :filename, :dependency, :file_descriptor_proto
|
|
10
10
|
|
|
11
11
|
def initialize(file_descriptor_proto)
|
|
12
12
|
@file_descriptor_proto = file_descriptor_proto
|
|
@@ -24,17 +24,23 @@ module GrpcReflection
|
|
|
24
24
|
def set_dataset
|
|
25
25
|
@file_descriptor_proto.service.each do |s|
|
|
26
26
|
converted_service = JSON.parse(s.to_json)
|
|
27
|
-
@dataset.add(
|
|
27
|
+
@dataset.add(qualified_name(converted_service["name"]))
|
|
28
28
|
converted_service["method"].each do |m|
|
|
29
|
-
@dataset.add(
|
|
29
|
+
@dataset.add(qualified_name(converted_service["name"] + "." + m["name"]))
|
|
30
30
|
@dataset.add(m["inputType"][1..])
|
|
31
31
|
@dataset.add(m["outputType"][1..])
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
@file_descriptor_proto.extension.each do |s|
|
|
36
|
-
@dataset.add(
|
|
36
|
+
@dataset.add(qualified_name(s.name))
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
|
+
|
|
40
|
+
def qualified_name(name)
|
|
41
|
+
return name if @file_descriptor_proto.package.empty?
|
|
42
|
+
|
|
43
|
+
@file_descriptor_proto.package + "." + name
|
|
44
|
+
end
|
|
39
45
|
end
|
|
40
46
|
end
|
|
@@ -2,25 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
module GrpcReflection
|
|
4
4
|
module FileDescriptorManager
|
|
5
|
-
@@file_descriptor_decorators =
|
|
5
|
+
@@file_descriptor_decorators = {}
|
|
6
6
|
|
|
7
7
|
class << self
|
|
8
8
|
def add(file_descriptor_proto)
|
|
9
|
-
|
|
10
|
-
@@file_descriptor_decorators
|
|
11
|
-
decorator
|
|
9
|
+
filename = file_descriptor_proto.name
|
|
10
|
+
@@file_descriptor_decorators[filename] ||= GrpcReflection::FileDescriptorDecorator.new(file_descriptor_proto)
|
|
12
11
|
end
|
|
13
12
|
|
|
14
13
|
def find(name)
|
|
15
14
|
file_descriptor = find_file_descriptor(name)
|
|
16
15
|
return [] if file_descriptor.nil?
|
|
17
16
|
|
|
17
|
+
collect_with_dependencies(file_descriptor)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def find_extension(containing_type, extension_number, service_names = [])
|
|
21
|
+
file_descriptor = find_extension_file_descriptor(containing_type, extension_number, service_names)
|
|
22
|
+
return [] if file_descriptor.nil?
|
|
23
|
+
|
|
24
|
+
collect_with_dependencies(file_descriptor)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def collect_with_dependencies(file_descriptor)
|
|
18
30
|
result = {}
|
|
19
31
|
result[file_descriptor.filename] = file_descriptor.serialized_file
|
|
20
32
|
dependencies = file_descriptor.dependency.dup
|
|
21
33
|
until dependencies.empty?
|
|
22
34
|
dependency = dependencies.shift
|
|
23
|
-
decorated_file_descriptor = @@file_descriptor_decorators
|
|
35
|
+
decorated_file_descriptor = @@file_descriptor_decorators[dependency]
|
|
24
36
|
if decorated_file_descriptor.nil? && proto = Google::Protobuf::DescriptorPool.generated_pool.lookup(dependency)&.to_proto
|
|
25
37
|
decorated_file_descriptor = add(proto)
|
|
26
38
|
end
|
|
@@ -34,26 +46,82 @@ module GrpcReflection
|
|
|
34
46
|
result.values
|
|
35
47
|
end
|
|
36
48
|
|
|
37
|
-
|
|
49
|
+
def find_extension_file_descriptor(containing_type, extension_number, service_names)
|
|
50
|
+
candidate_file_descriptor_protos(service_names).each_value do |file_descriptor_proto|
|
|
51
|
+
next unless extension_field_matches?(file_descriptor_proto, containing_type, extension_number)
|
|
52
|
+
|
|
53
|
+
return add(file_descriptor_proto)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
nil
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def candidate_file_descriptor_protos(service_names)
|
|
60
|
+
candidates = {}
|
|
61
|
+
|
|
62
|
+
@@file_descriptor_decorators.each_value do |decorated_file_descriptor|
|
|
63
|
+
candidates[decorated_file_descriptor.filename] = decorated_file_descriptor.file_descriptor_proto
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
pending = service_names.filter_map do |service_name|
|
|
67
|
+
descriptor = Google::Protobuf::DescriptorPool.generated_pool.lookup(service_name)
|
|
68
|
+
descriptor&.file_descriptor&.to_proto if descriptor.respond_to?(:file_descriptor)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
until pending.empty?
|
|
72
|
+
file_descriptor_proto = pending.shift
|
|
73
|
+
next if file_descriptor_proto.nil? || candidates.key?(file_descriptor_proto.name)
|
|
74
|
+
|
|
75
|
+
candidates[file_descriptor_proto.name] = file_descriptor_proto
|
|
76
|
+
file_descriptor_proto.dependency.each do |dependency|
|
|
77
|
+
next if candidates.key?(dependency)
|
|
78
|
+
|
|
79
|
+
dependency_proto = Google::Protobuf::DescriptorPool.generated_pool.lookup(dependency)&.to_proto
|
|
80
|
+
pending << dependency_proto unless dependency_proto.nil?
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
candidates
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def extension_field_matches?(file_descriptor_proto, containing_type, extension_number)
|
|
88
|
+
each_extension_field(file_descriptor_proto).any? do |field|
|
|
89
|
+
field.extendee == ".#{containing_type}" && field.number == extension_number
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def each_extension_field(file_descriptor_proto, &block)
|
|
94
|
+
return enum_for(:each_extension_field, file_descriptor_proto) unless block_given?
|
|
95
|
+
|
|
96
|
+
file_descriptor_proto.extension.each(&block)
|
|
97
|
+
file_descriptor_proto.message_type.each { |message_type| each_message_extension_field(message_type, &block) }
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def each_message_extension_field(message_type, &block)
|
|
101
|
+
message_type.extension.each(&block)
|
|
102
|
+
message_type.nested_type.each { |nested_type| each_message_extension_field(nested_type, &block) }
|
|
103
|
+
end
|
|
38
104
|
|
|
39
105
|
def find_file_descriptor(name)
|
|
40
|
-
file_descriptor = @@file_descriptor_decorators.detect { |f| f.dataset.include?(name) }
|
|
106
|
+
file_descriptor = @@file_descriptor_decorators.values.detect { |f| f.dataset.include?(name) }
|
|
41
107
|
return file_descriptor if file_descriptor
|
|
42
108
|
|
|
43
109
|
search_name = name
|
|
44
110
|
file_descriptor_proto = nil
|
|
45
|
-
|
|
111
|
+
loop do
|
|
46
112
|
descriptor = Google::Protobuf::DescriptorPool.generated_pool.lookup(search_name)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
113
|
+
pos = search_name.rindex(".")
|
|
114
|
+
search_name = pos ? search_name.slice(0..(pos - 1)) : nil
|
|
115
|
+
unless descriptor.nil? || !descriptor.respond_to?(:file_descriptor)
|
|
116
|
+
file_descriptor_proto = descriptor.file_descriptor&.to_proto
|
|
117
|
+
break unless file_descriptor_proto.nil?
|
|
118
|
+
end
|
|
119
|
+
break if search_name.nil?
|
|
51
120
|
end
|
|
52
121
|
|
|
53
122
|
return nil if file_descriptor_proto.nil?
|
|
54
123
|
|
|
55
124
|
add(file_descriptor_proto)
|
|
56
|
-
@@file_descriptor_decorators.detect { |f| f.dataset.include?(name) }
|
|
57
125
|
end
|
|
58
126
|
end
|
|
59
127
|
end
|
|
@@ -1,39 +1,57 @@
|
|
|
1
1
|
module GrpcReflection
|
|
2
2
|
module ServerShared
|
|
3
3
|
def server_reflection_info_response(req, proto_module)
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
req.lazy.map { |request| build_response(request, proto_module) }
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
private
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
def build_response(request, proto_module)
|
|
10
|
+
res = proto_module::ServerReflectionResponse.new(original_request: request, valid_host: request.host)
|
|
11
|
+
case request.message_request
|
|
12
|
+
when :list_services
|
|
9
13
|
res.list_services_response = proto_module::ListServiceResponse.new(service: list_services_response(proto_module))
|
|
10
|
-
|
|
14
|
+
when :file_containing_symbol
|
|
11
15
|
result = GrpcReflection::FileDescriptorManager.find(request.file_containing_symbol)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
res.file_descriptor_response = proto_module::FileDescriptorResponse.new(file_descriptor_proto: [Google::Protobuf::FileDescriptorProto.encode(proto)])
|
|
16
|
-
elsif !request.file_containing_extension.nil? && !request.file_containing_extension.containing_type.empty?
|
|
17
|
-
descriptor = Google::Protobuf::DescriptorPool.generated_pool.lookup(request.file_containing_extension.containing_type)
|
|
18
|
-
if descriptor.is_a?(Google::Protobuf::FieldDescriptor) && descriptor.number == request.file_containing_extension.extension_number
|
|
19
|
-
result = GrpcReflection::FileDescriptorManager.find(request.file_containing_extension.containing_type)
|
|
16
|
+
if result.empty?
|
|
17
|
+
res.error_response = error_response(proto_module, GRPC::Core::StatusCodes::NOT_FOUND, "symbol not found: #{request.file_containing_symbol}")
|
|
18
|
+
else
|
|
20
19
|
res.file_descriptor_response = proto_module::FileDescriptorResponse.new(file_descriptor_proto: result)
|
|
20
|
+
end
|
|
21
|
+
when :file_by_filename
|
|
22
|
+
descriptor = Google::Protobuf::DescriptorPool.generated_pool.lookup(request.file_by_filename)
|
|
23
|
+
if !descriptor.is_a?(Google::Protobuf::FileDescriptor)
|
|
24
|
+
res.error_response = error_response(proto_module, GRPC::Core::StatusCodes::NOT_FOUND, "file not found: #{request.file_by_filename}")
|
|
21
25
|
else
|
|
22
|
-
res.file_descriptor_response = proto_module::FileDescriptorResponse.new(file_descriptor_proto: [])
|
|
26
|
+
res.file_descriptor_response = proto_module::FileDescriptorResponse.new(file_descriptor_proto: [Google::Protobuf::FileDescriptorProto.encode(descriptor.to_proto)])
|
|
23
27
|
end
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
when :file_containing_extension
|
|
29
|
+
result = GrpcReflection::FileDescriptorManager.find_extension(
|
|
30
|
+
request.file_containing_extension.containing_type,
|
|
31
|
+
request.file_containing_extension.extension_number,
|
|
32
|
+
service_names
|
|
28
33
|
)
|
|
34
|
+
if result.empty?
|
|
35
|
+
res.error_response = error_response(proto_module, GRPC::Core::StatusCodes::NOT_FOUND, "extension not found: #{request.file_containing_extension.containing_type} #{request.file_containing_extension.extension_number}")
|
|
36
|
+
else
|
|
37
|
+
res.file_descriptor_response = proto_module::FileDescriptorResponse.new(file_descriptor_proto: result)
|
|
38
|
+
end
|
|
39
|
+
when :all_extension_numbers_of_type
|
|
40
|
+
res.error_response = error_response(proto_module, GRPC::Core::StatusCodes::UNIMPLEMENTED, "all_extension_numbers_of_type is not implemented")
|
|
41
|
+
else
|
|
42
|
+
res.error_response = error_response(proto_module, GRPC::Core::StatusCodes::INVALID_ARGUMENT, "invalid MessageRequest")
|
|
29
43
|
end
|
|
30
|
-
|
|
44
|
+
res
|
|
31
45
|
end
|
|
32
46
|
|
|
33
|
-
|
|
47
|
+
def error_response(proto_module, error_code, error_message)
|
|
48
|
+
proto_module::ErrorResponse.new(error_code: error_code, error_message: error_message)
|
|
49
|
+
end
|
|
34
50
|
|
|
35
51
|
def main_server
|
|
36
|
-
@main_server ||= ObjectSpace.each_object(GRPC::RpcServer).
|
|
52
|
+
@main_server ||= ObjectSpace.each_object(GRPC::RpcServer).find do |server|
|
|
53
|
+
server.send(:rpc_handlers).values.any? { |handler| handler.receiver.equal?(self) }
|
|
54
|
+
end
|
|
37
55
|
end
|
|
38
56
|
|
|
39
57
|
def service_names
|