Coder Social home page Coder Social logo

grpcurl's Introduction

gRPCurl

Build Status Go Report Card

grpcurl is a command-line tool that lets you interact with gRPC servers. It's basically curl for gRPC servers.

The main purpose for this tool is to invoke RPC methods on a gRPC server from the command-line. gRPC servers use a binary encoding on the wire (protocol buffers, or "protobufs" for short). So they are basically impossible to interact with using regular curl (and older versions of curl that do not support HTTP/2 are of course non-starters). This program accepts messages using JSON encoding, which is much more friendly for both humans and scripts.

With this tool you can also browse the schema for gRPC services, either by querying a server that supports server reflection, by reading proto source files, or by loading in compiled "protoset" files (files that contain encoded file descriptor protos). In fact, the way the tool transforms JSON request data into a binary encoded protobuf is using that very same schema. So, if the server you interact with does not support reflection, you will either need the proto source files that define the service or need protoset files that grpcurl can use.

This repo also provides a library package, github.com/fullstorydev/grpcurl, that has functions for simplifying the construction of other command-line tools that dynamically invoke gRPC endpoints. This code is a great example of how to use the various packages of the protoreflect library, and shows off what they can do.

See also the grpcurl talk at GopherCon 2018.

Features

grpcurl supports all kinds of RPC methods, including streaming methods. You can even operate bi-directional streaming methods interactively by running grpcurl from an interactive terminal and using stdin as the request body!

grpcurl supports both secure/TLS servers and plain-text servers (i.e. no TLS) and has numerous options for TLS configuration. It also supports mutual TLS, where the client is required to present a client certificate.

As mentioned above, grpcurl works seamlessly if the server supports the reflection service. If not, you can supply the .proto source files or you can supply protoset files (containing compiled descriptors, produced by protoc) to grpcurl.

Installation

Binaries

Download the binary from the releases page.

Homebrew (macOS)

On macOS, grpcurl is available via Homebrew:

brew install grpcurl

Docker

For platforms that support Docker, you can download an image that lets you run grpcurl:

# Download image
docker pull fullstorydev/grpcurl:latest
# Run the tool
docker run fullstorydev/grpcurl api.grpc.me:443 list

Note that there are some pitfalls when using docker:

  • If you need to interact with a server listening on the host's loopback network, you must specify the host as host.docker.internal instead of localhost (for Mac or Windows) OR have the container use the host network with -network="host" (Linux only).
  • If you need to provide proto source files or descriptor sets, you must mount the folder containing the files as a volume (-v $(pwd):/protos) and adjust the import paths to container paths accordingly.
  • If you want to provide the request message via stdin, using the -d @ option, you need to use the -i flag on the docker command.

Other Packages

There are numerous other ways to install grpcurl, thanks to support from third parties that have created recipes/packages for it. These include other ways to install grpcurl on a variety of environments, including Windows and myriad Linux distributions.

You can see more details and the full list of other packages for grpcurl at repology.org: https://repology.org/project/grpcurl/information

From Source

If you already have the Go SDK installed, you can use the go tool to install grpcurl:

go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest

This installs the command into the bin sub-folder of wherever your $GOPATH environment variable points. (If you have no GOPATH environment variable set, the default install location is $HOME/go/bin). If this directory is already in your $PATH, then you should be good to go.

If you have already pulled down this repo to a location that is not in your $GOPATH and want to build from the sources, you can cd into the repo and then run make install.

If you encounter compile errors and are using a version of the Go SDK older than 1.13, you could have out-dated versions of grpcurl's dependencies. You can update the dependencies by running make updatedeps. Or, if you are using Go 1.11 or 1.12, you can add GO111MODULE=on as a prefix to the commands above, which will also build using the right versions of dependencies (vs. whatever you may already have in your GOPATH).

Usage

The usage doc for the tool explains the numerous options:

grpcurl -help

In the sections below, you will find numerous examples demonstrating how to use grpcurl.

Invoking RPCs

Invoking an RPC on a trusted server (e.g. TLS without self-signed key or custom CA) that requires no client certs and supports server reflection is the simplest thing to do with grpcurl. This minimal invocation sends an empty request body:

grpcurl grpc.server.com:443 my.custom.server.Service/Method

# no TLS
grpcurl -plaintext grpc.server.com:80 my.custom.server.Service/Method

To send a non-empty request, use the -d argument. Note that all arguments must come before the server address and method name:

grpcurl -d '{"id": 1234, "tags": ["foo","bar"]}' \
    grpc.server.com:443 my.custom.server.Service/Method

As can be seen in the example, the supplied body must be in JSON format. The body will be parsed and then transmitted to the server in the protobuf binary format.

If you want to include grpcurl in a command pipeline, such as when using jq to create a request body, you can use -d @, which tells grpcurl to read the actual request body from stdin:

grpcurl -d @ grpc.server.com:443 my.custom.server.Service/Method <<EOM
{
  "id": 1234,
  "tags": [
    "foor",
    "bar"
  ]
}
EOM

Listing Services

To list all services exposed by a server, use the "list" verb. When using .proto source or protoset files instead of server reflection, this lists all services defined in the source or protoset files.

# Server supports reflection
grpcurl localhost:8787 list

# Using compiled protoset files
grpcurl -protoset my-protos.bin list

# Using proto sources
grpcurl -import-path ../protos -proto my-stuff.proto list

The "list" verb also lets you see all methods in a particular service:

grpcurl localhost:8787 list my.custom.server.Service

Describing Elements

The "describe" verb will print the type of any symbol that the server knows about or that is found in a given protoset file. It also prints a description of that symbol, in the form of snippets of proto source. It won't necessarily be the original source that defined the element, but it will be equivalent.

# Server supports reflection
grpcurl localhost:8787 describe my.custom.server.Service.MethodOne

# Using compiled protoset files
grpcurl -protoset my-protos.bin describe my.custom.server.Service.MethodOne

# Using proto sources
grpcurl -import-path ../protos -proto my-stuff.proto describe my.custom.server.Service.MethodOne

Descriptor Sources

The grpcurl tool can operate on a variety of sources for descriptors. The descriptors are required, in order for grpcurl to understand the RPC schema, translate inputs into the protobuf binary format as well as translate responses from the binary format into text. The sections below document the supported sources and what command-line flags are needed to use them.

Server Reflection

Without any additional command-line flags, grpcurl will try to use server reflection.

Examples for how to set up server reflection can be found here.

When using reflection, the server address (host:port or path to Unix socket) is required even for "list" and "describe" operations, so that grpcurl can connect to the server and ask it for its descriptors.

Proto Source Files

To use grpcurl on servers that do not support reflection, you can use .proto source files.

In addition to using -proto flags to point grpcurl at the relevant proto source file(s), you may also need to supply -import-path flags to tell grpcurl the folders from which dependencies can be imported.

Just like when compiling with protoc, you do not need to provide an import path for the location of the standard protos included with protoc (which contain various "well-known types" with a package definition of google.protobuf). These files are "known" by grpcurl as a snapshot of their descriptors is built into the grpcurl binary.

When using proto sources, you can omit the server address (host:port or path to Unix socket) when using the "list" and "describe" operations since they only need to consult the proto source files.

Protoset Files

You can also use compiled protoset files with grpcurl. If you are scripting grpcurl and need to re-use the same proto sources for many invocations, you will see better performance by using protoset files (since it skips the parsing and compilation steps with each invocation).

Protoset files contain binary encoded google.protobuf.FileDescriptorSet protos. To create a protoset file, invoke protoc with the *.proto files that define the service:

protoc --proto_path=. \
    --descriptor_set_out=myservice.protoset \
    --include_imports \
    my/custom/server/service.proto

The --descriptor_set_out argument is what tells protoc to produce a protoset, and the --include_imports argument is necessary for the protoset to contain everything that grpcurl needs to process and understand the schema.

When using protosets, you can omit the server address (host:port or path to Unix socket) when using the "list" and "describe" operations since they only need to consult the protoset files.

grpcurl's People

Contributors

adambabik avatar bufdev avatar cuishuang avatar curiousleo avatar dependabot[bot] avatar dimo414 avatar dragonsinth avatar fdfzcq avatar ghatwala avatar gnossen avatar goodfirm avatar gpassini avatar jeanbza avatar jeffwidman avatar jhump avatar leighmcculloch avatar mkatychev avatar mprimeaux avatar namrata-ibm avatar ns-yuhanl avatar papacharlie avatar q3k avatar rolice avatar shalamai avatar sigv avatar srenatus avatar sunilthorat09 avatar violin0622 avatar vors avatar zliuva avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

grpcurl's Issues

Not getting proper result

Hello ,

When i am try to run below comman 👍
grpcurl localhost:9081 describe .
I am getting below error :
Failed to dial target host "localhost:9081": tls: oversized record received with length 20527
Please help me out what i am doing wrong .

Thanks

Send image (binary data)

Hi there, thanks for the time spended in this awesome tool, it helps me a lot to test my microservice architecture. :-)

It is possible to send binary data to the gRPC server?

Something like curl does.

Thank you for your time :-)

grpcurl not respecting -H value on CLI

Seem to be running into some issues using grpcurl with nginx-ingress

Specifically, i run

grpcurl -H 'content-type: application/grpc' mything.com:443 list

And get returned
Failed to list services: rpc error: code = Internal desc = transport: received the unexpected content-type "text/plain; charset=utf-8

Not sure if i'm meant to then add -reflect-header 'content-type: application/grpc' , but doing so gets me no fruther.

The Service in question has TLS enabled at the service (pod) level, and it is valid using letsencrypt production certificate (I would expect a TLS error anyone on the CLI if something was wrong here?)

Any thoughts? Something i'm doing wrong to pass the header in? Tried to following the --help documentation but cant see where i'm passing the header incorrectly

Support passing protobuf in text format

Hi,

I'm using grpcurl as a library in a client CLI application. Since writing JSON lacks a bit of user friendliness, I would prefer to use the protobuf text format instead.

Compare:

grpcurl -d '{"fan": 0, "mode": "FAN_MODE_PERCENTAGE", "percentage": 50}' -plaintext 127.0.0.1:80 bmc.ManagementService.SetFan

with:

grpcurl -d 'fan: 0, mode: FAN_MODE_PERCENTAGE, percentage: 50' -plaintext 127.0.0.1:80 bmc.ManagementService.SetFan

or as it will be in the client I'm writing:

ubmcctl SetFan fan: 0, mode: FAN_MODE_PERCENTAGE, percentage: 50

Looking at the code I don't see any clear way of making this happen without breaking the interface, except for allowing JSON / Text format interchangeably. Which may be a feature, but could also create some confusion.

Thanks for your consideration

Include headers on discovery calls

Headers are currently not sent along with service/method discovery calls. This prevents grpcurl from being used with any server that for example performs custom header-based authentication.

Any particular reasoning behind the decision not to send headers with the discovery calls? I think it would be sensible for any server performing (custom) authentication/authorization before executing a service call to extend the auth to the discovery of its services.

Describing service inputs/outputs

Hi @jhump. Thanks for this great project. I noticed that there is documentation for reflection of services - which I'm able to use without any problems - but there's no documentation / samples around reflection of service inputs and outputs. Is that at all possible? If so, does one go about it? I naively tried grpcurl describe <the value of InputType that the service description gave> but this did not work.

Thanks!

Automate releases to homebrew?

Related to #52: now that there is a grpcurl recipe in Homebrew, I think we need to look into ways to automate releases so that the brew artifacts are updated also. Currently, the release process results in a tag in the repo and artifacts uploaded to GitHub.

grpcurl doesn't respect GOAWAY frame from server

grpcurl retries forever even after server sends GOAWAY frame

I tried something like this:

gcurl -plaintext localhost:50051 describe

from server with GODEBUG="http2debug=2":

2019/08/10 22:56:11 connection is idle
2019/08/10 22:56:11 http2: Framer 0xc0002d9880: wrote GOAWAY len=8 LastStreamID=0 ErrCode=NO_ERROR Debug=""
2019/08/10 22:56:11 h2c: attempting h2c with prior knowledge.
2019/08/10 22:56:11 http2: server connection from [::1]:44508 on 0xc0001f95f0
2019/08/10 22:56:11 http2: Framer 0xc0002d9b20: wrote SETTINGS len=24, settings: MAX_FRAME_SIZE=1048576, MAX_CONCURRENT_STREAMS=250, MAX_HEADER_LIST_SIZE=1048896, INITIAL_WINDOW_SIZE=1048576
2019/08/10 22:56:11 http2: server: client [::1]:44508 said hello
2019/08/10 22:56:11 http2: Framer 0xc0002d9b20: read SETTINGS len=0
2019/08/10 22:56:11 http2: server read frame SETTINGS len=0
2019/08/10 22:56:11 http2: Framer 0xc0002d9b20: wrote SETTINGS flags=ACK len=0
2019/08/10 22:56:11 http2: Framer 0xc0002d9b20: wrote WINDOW_UPDATE len=4 (conn) incr=983041
2019/08/10 22:56:11 http2: Framer 0xc0002d9b20: read SETTINGS flags=ACK len=0
2019/08/10 22:56:11 http2: server read frame SETTINGS flags=ACK len=0

2019/08/10 22:56:12 connection is idle
2019/08/10 22:56:12 http2: Framer 0xc000181ce0: wrote GOAWAY len=8 LastStreamID=0 ErrCode=NO_ERROR Debug=""
2019/08/10 22:56:12 h2c: attempting h2c with prior knowledge.
2019/08/10 22:56:12 http2: server connection from [::1]:44510 on 0xc000269a00
2019/08/10 22:56:12 http2: Framer 0xc000181ea0: wrote SETTINGS len=24, settings: MAX_FRAME_SIZE=1048576, MAX_CONCURRENT_STREAMS=250, MAX_HEADER_LIST_SIZE=1048896, INITIAL_WINDOW_SIZE=1048576
2019/08/10 22:56:12 http2: server: client [::1]:44510 said hello
2019/08/10 22:56:12 http2: Framer 0xc000181ea0: read SETTINGS len=0
2019/08/10 22:56:12 http2: server read frame SETTINGS len=0
2019/08/10 22:56:12 http2: Framer 0xc000181ea0: wrote SETTINGS flags=ACK len=0
2019/08/10 22:56:12 http2: Framer 0xc000181ea0: wrote WINDOW_UPDATE len=4 (conn) incr=983041
2019/08/10 22:56:12 http2: Framer 0xc000181ea0: read SETTINGS flags=ACK len=0
2019/08/10 22:56:12 http2: server read frame SETTINGS flags=ACK len=0

... more GOAWAY frame from server and then new conn from grpcurl

The "Sent 1 request and received 1 response" log message means output isn't valid JSON

grpcurl -d '...' localhost:50051 foo.Bar/Method | jq .status
{
  ...
}
parse error: Invalid numeric literal at line 7, column 5

The parse error: ... is coming from jq as it tries to parse the "Sent 1 request and received 1 response" log message that grpcurl outputs.

I'd like some way to ensure the stdout is clean JSON. Ideally by default.

Perhaps the "Sent 1 request and received 1 response" message could go to stderr, and/or only be output with -v.

Cannot call methods

I have a very simple test setup with server reflection enabled - no proxies or multiple servers, just a single service exposing a few methods.

I can successfully list methods with:

grpcurl -plaintext localhost:50051 describe test.MyService.Login
test.MyService.Login is a method:
rpc Login ( .test.LoginRequest ) returns ( .test.LoginReply ) {
  option (.google.api.http) = { post:"/login" };
}

As well as get info on the types:

grpcurl -msg-template -plaintext localhost:50051 describe test.LoginRequest
test.LoginRequest is a message:
message LoginRequest {
  string email = 1;
  string password = 2;
}

Message template:
{
  "email": "",
  "password": ""
}

But, if i try to call a method - it fails:

grpcurl -plaintext -d '{"email":"test", "password":"test"}' localhost:50051 test.MyService/Login
Failed to construct request parser and formatter for "json": error creating message resolver: Symbol not found: grpc.reflection.v1alpha.ServerReflection

Any ideas?
Worth mentioning is that Polyglot works with no issues.

Release binaries

Hi! I love using grpcurl but installing it on new machines on first use can be pretty slow to download the dependencies and compile. Would it be possible to start releasing binaries?

Suggested approach I've used on my projects is to use goreleaser to build binaries for a few operating systems and architectures, then it will upload them to the releases page of this project.

Is this something that could be added?

Thanks!

Proposal: Streamline CLI flags and args

As grpcurl is using standard flags package, it's requires to pass flags before positional arguments.

It pretty difficult to "play around" with different commands. I would propose to use come well established CLI libraries for streamlining this process.

Here are one of the libraries that may work:

https://github.com/spf13/cobra/
https://github.com/alecthomas/kingpin
https://github.com/urfave/cli

The change could be done in a backward compatible way I believe.

I could work on a PR if this change would be desired.

Pre-built binaries

Sure would be nice if you built pre-built binaries for linux, mac, etc. in your releases (along with checksums). Most of the other tools in our pipeline do something like that...

Headers can be read from stdin?

I have a use case where I'd the headers to be able to be read from stdin, in particular I'm passing credentials through the headers and I don't want the credentials to show up as command line parameters which exposes the credentials.

Would it be possible to allow the headers to be read from stdin like the request data? I could put in a PR if this is simple, would you accept it?

I was thinking of putting a switch like this for reading from stdin just like the request data: https://github.com/fullstorydev/grpcurl/blob/master/cmd/grpcurl/grpcurl.go#L489

proto file "does not reside in any import path"

I've been happily using grpcurl with something like the following:

grpcurl -plaintext -import-path ../../filter/api/services -proto myservice.proto localhost:50055 myservice.MyService/MyRPC

and it's been working fine for me.
Today a colleague reported issues running this same line.
After comparing versions of grpcurl, turnw out I was using:
grpcurl dev build <no version set>
and he was using:
grpcurl 1.3.0

So I brew install grpcurl to get on the same official version and now grpcurl complains:

Failed to process proto source files.: my_current_absolute_path/myservice.proto does not reside in any import path

This is failing:

grpcurl -plaintext -import-path ../../filter/api/services -proto myservice.proto localhost:50055 myservice.MyService/MyRPC

but this is working:

grpcurl -plaintext -proto ../../filter/api/services/myservice.proto localhost:50055 myservice.MyService/MyRPC

is there anything I'm doing wrong?
has anything changed around this area that would explain why previous version worked fine but current does not?

Keep-alive - half the expected rate

When using the -keepalive-time option, grpcurl sends keepalive pings to the server at half the expected rate.

Steps to reproduce

  • Set up a gRPC service which listens, for example, on endpoint 1.2.3.4:123
  • Run grpcurl with a 60 seconds keepalive-time ping against an API which takes say 5 min to complete:
./grpcurl -keepalive-time 60 1.2.3.4:123 my.Service/ExtremelySlowAPI
  • Run tcpdump to monitor packets being sent from grpcurl to the service:
tcpdump -i eth0 dst 1.2.3.4

Expected

You should see keepalive ping packets sent on the wire every 60 seconds.

Observed

tcpdump reports 2 keepalive ping packets sent at once, every 120 seconds.

How to config protoset?

exec grpcurl -plaintext host:port list
return Failed to list services: server does not support the reflection API
generate protoset

exec grpcurl -protoset *.protoset
return Too few arguments. Try 'grpcurl -help' for more details.

However, the help info can not help me in fact.

What is the crrect method to config protoset?

Thanks

Install info

It might seem obvious but an small section in README file with installation instructions (make install) ,package dependencies (make), and configuration dependencies (GOBIN in $PATH) would be useful IMHO.

Enum with index 0 cannot be returned

grpcurl version: 1.1.0
proto3 is used

Case:
enum Status {
ACTIVE = 0;
INACTIVE = 1;
}

if Status is INACTIVE, return:
{
"status": "INACTIVE"
}

if Status is ACTIVE, return: {}
which should return
{
"status": "ACTIVE"
}

grpcurl and server reflection

I have couple of gRPC services and they are hosted in different servers and have fronted them using a Nginx reverse proxy. I created a new service that only does server reflection for all the services even though they are hosted in different servers and proxied all the /grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo calls to this service.

Service A
com.example.grpc.PublicHelloService/sayHello

Service B
com.example.grpc.HelloService/sayHello

Service - server reflection for Service A and Service B

When I try to call remote method in Service A using grpcurl

grpcurl -d '{}' nginx-reverse-proxy:443 "com.example.grpc.PublicHelloService/sayHello"

I get an error saying

Failed to construct request parser and formatter for "json": error creating message resolver: Symbol not found: com.example.grpc.HelloService

Is there a way to ignore symbols the are not required for current call.

unknown import path "github.com/jhump/protoreflect/dynamic/grpcdynamic": cannot find module providing package github.com/jhump/protoreflect/dynamic/grpcdynamic

As of d86529b, I tried to setup the project to reproduce a bug, but when running make install it says

$ make install
go install -ldflags '-X "main.version=dev build v1.0.0-15-gd86529b-dirty"' ./...
go: finding github.com/jhump/protoreflect/dynamic/grpcdynamic latest
go: finding github.com/jhump/protoreflect/grpcreflect latest
go: finding github.com/jhump/protoreflect/internal latest
go: finding github.com/jhump/protoreflect/dynamic latest
invoke.go:15:2: unknown import path "github.com/jhump/protoreflect/dynamic/grpcdynamic": cannot find module providing package github.com/jhump/protoreflect/dynamic/grpcdynamic
desc_source.go:14:2: unknown import path "github.com/jhump/protoreflect/grpcreflect": cannot find module providing package github.com/jhump/protoreflect/grpcreflect
../../go/pkg/mod/github.com/jhump/[email protected]/desc/descriptor.go:18:2: unknown import path "github.com/jhump/protoreflect/internal": cannot find module providing package github.com/jhump/protoreflect/internal
make: *** [Makefile:21: install] Error 1

Install fail

Neither go get github.com/fullstorydev/grpcurl/cmd/grpcurl nor make install is working.

make install
go install ./...
# github.com/jhump/protoreflect/desc/protoparse
../../jhump/protoreflect/desc/protoparse/parser.go:391:52: undefined: descriptor.EnumDescriptorProto_EnumReservedRange
../../jhump/protoreflect/desc/protoparse/parser.go:452:52: undefined: descriptor.EnumDescriptorProto_EnumReservedRange
../../jhump/protoreflect/desc/protoparse/parser.go:788:7: ed.ReservedName undefined (type *descriptor.EnumDescriptorProto has no field or method ReservedName)
../../jhump/protoreflect/desc/protoparse/parser.go:791:7: ed.ReservedRange undefined (type *descriptor.EnumDescriptorProto has no field or method ReservedRange)
../../jhump/protoreflect/desc/protoparse/parser.go:798:60: undefined: descriptor.EnumDescriptorProto_EnumReservedRange
../../jhump/protoreflect/desc/protoparse/parser.go:799:9: undefined: descriptor.EnumDescriptorProto_EnumReservedRange
../../jhump/protoreflect/desc/protoparse/parser.go:1164:25: enum.GetReservedRange undefined (type *descriptor.EnumDescriptorProto has no field or method GetReservedRange)
../../jhump/protoreflect/desc/protoparse/parser.go:1645:32: ed.ReservedRange undefined (type *descriptor.EnumDescriptorProto has no field or method ReservedRange)
../../jhump/protoreflect/desc/protoparse/parser.go:1646:22: ed.ReservedRange undefined (type *descriptor.EnumDescriptorProto has no field or method ReservedRange)
../../jhump/protoreflect/desc/protoparse/parser.go:1660:22: ed.ReservedName undefined (type *descriptor.EnumDescriptorProto has no field or method ReservedName)
../../jhump/protoreflect/desc/protoparse/parser.go:1660:22: too many errors
make: *** [install] Error 2

How do I invoke grpc services that need authorization?

go client code
auth := Authentication{
appKey: "duzhenxun",
appSecret: "password",
}
conn, err := grpc.Dial(*addr, grpc.WithInsecure(), grpc.WithPerRPCCredentials(&auth),grpc.WithAuthority("service1"))

Now I want to use curl to request how to add these parameters?
grpcurl -plaintext -authority service1 -d '{"name":"duzhenxun"}' ??????? 127.0.0.1:9080 hello.HelloService.Fun1

Store protoset from reflection endpoint

It would be great if grpcurl would have a switch that would allow to store protoset (and/or proto sources) to a file/directory. Maybe it could be a new flag that would work with describe command, or a completely new command.

Our use-case: We want to automatically generate Envoy configuration with gRPC-JSON transcoder - it requires the protoset and list of services. grpcurl allows to list available services, just the protoset export is missing.

Call service behind reverse proxy

I'm trying to deploy my grpc service behind traefik proxy, so localhost:9999 becomes localhost:80/api. Sadly I cannot do anything with grpcurl because it complains when adress contains path as well. Is it wrong to run grpc in such a way?

╭─krever@wp-xps ~                                             
╰─$ grpcurl localhost/api list 
Failed to dial target host "localhost/api": dial tcp: address localhost/api: missing port in address 
╭─krever@wp-xps ~                                                
╰─$ grpcurl localhost:80/api list                                           
Failed to dial target host "localhost:80/api": dial tcp: address tcp/80/api: unknown port 

Correct syntax for -d in PowerShell?

Hello,
I am not sure if this is an issue with grpcurl or me not being able to use PowerShell.

I have a grpc java Server with Reflection turned on and am using this command to ping it:

grpcurl -plaintext localhost:50051 com.example.coffee.services.CoffeeMachine/Ping

This works just fine and it shows my response message in the Shell.

But when I try to add a request message with -d like shown in the Readme I keep getting invalid character Error

grpcurl -d '{"product":1}' -plaintext localhost:50051 com.example.coffee.services.CoffeeMachine/GetProduct

Error invoking method "com.example.coffee.services.CoffeeMachine/GetProduct": error getting request data: invalid character 'p' looking for beginning of object key string

When I throw the command in the git bash it does work.

This looked to me like a parsing issue, so I tried different types of quotes and escape characters to get it to work. I found some comment where one claimed that in Windows the executable handles character unspacing?

This type of escaping seems to work in CMD, but not in PowerShell

grpcurl -d "{\"product\":1}" -plaintext localhost:50051 com.example.coffee.services.CoffeeMachine/GetProduct

Would be really grateful to find out how to use this tool in PowerShell on Windows.

Thanks a lot!

Who broke the build?

as of this date (and go version go1.12.1 darwin/amd64)

$ go get github.com/fullstorydev/grpcurl
results in

# github.com/fullstorydev/grpcurl
../GitHub/go/src/github.com/fullstorydev/grpcurl/grpcurl.go:600:4: undefined: grpc.WithContextDialer

`-d nested-json-string` error getting request data

Thanks for this great tool!
when i try to send nested json data as a string by grpcurl, it throws out the following error:
error getting request data: bad input: expecting string ; instead got {

my data schema:

{
  "origin": "test.jpg",
  "annotations": [
    {
      "title": "",
      "description": "",
      "view": {
        "y": 200,
        "x": 200
      }
    }
  ],
  "findings": [
    "finding_1",
    "finding_2",
    "finding_3"
  ],
  "image": "test_test.jpg"
}

sine the json data is too long for typing.. i use a make file to read in and pass it to grpcurl as the following:

FILE := test.json
json := $(shell cat ${FILE})
data := '{"appid": "test_app", "jsonData": ${json}, "others": ""}'

grpcurl_test:
	grpcurl -insecure -d ${data} \
	localhost:10000 Service/method

Could you please give me some hints about this?
Thanks.

-emit-defaults is needed to show output if the output only contains default values

If an Unary RPC is called and the output contains only default values (explicitly set on the response), the values don't show upless I set -emit-defaults. This is somewhat surprising behaviour because I would expect that option only to have any effect if the values on the response are not set. However if they are set and just happen to match the defaults, grpcurl is not printing the response unless I set -emit-defaults.
If I do the same call with a client library (such as the Node.js gRPC library), the values (the number 0 in this case) are there.

ERROR: requires length-delimited wire type

Hello !
I looked over the internet but so far I haven't seen an error like this elsewhere.

I get this when grpcurl tries to decode the response of my server.

ERROR:
  Code: Internal
  Message: grpc: failed to unmarshal the received message bad input; field api.Foo.UpdateTS requires length-delimited wire type

This field in question is of type google.protobuf.Timestamp.

Is there any chance you know what is going on and how I can fix this?

Cheers!

building binary

Hey, I'm very interested in this project but kinda new to go.
I have installed go on my mac, but how actually build binary?
How to install dependencies?
Thank you

0 feedback on wrong request fields when using .proto

Hi and thanks for awesome project! 👋

I guess it is thanks of forward and backward protobuf compatibility as you never know what server actually is implementing, but I just spent hour of crafting request in JSON only to get frustrated and coded Golang client in 2 minutes to find out that I was doing fields in snake_case instead of camelCase 🤦‍♂️

The request was coming through and even funnier -> It was succesful in some way due to default values.

Any way we can improve this? Either by validation or some tooling on how to craft the request? I guess you are parsing against given proto so it's clear that user uses field that does not exists? (:

Reflection issues

I have a proto set with 3 gRPC services (and some external dependencies) that compiles appropriately on the protobuf side, compiles and runs in go, and clients work when interacting with the server, but reflection fails within grpcurl on the 2 services which have dependencies in other packages.

I recreated a fake weatherman repo with a similar setup to provide an example.

proto & generated code repo: https://github.com/jamisonhyatt/grpc-multi-pkg-protos
Client gist: https://gist.github.com/jamisonhyatt/dd9d93b978472c960c9fa81b9f39fcf9

Here's tree of the protoset

└── protos
    ├── desktop_svc
    │   └── desktop_svc.proto
    ├── external
    │   ├── location
    │   │   └── location.proto
    │   └── weather
    │       ├── hurricanes.proto
    │       └── weather.proto
    ├── mobile_svc
    │   └── mobile_svc.proto
    └── weatherman_svc.proto

list returns

desktop.Desktop
grpc.reflection.v1alpha.ServerReflection
mobile.Mobile
weatherman.Weatherman

weatherman.Weatherman.Healthcheck returns

{
  "healthy": true
}

list mobile.Mobile throws an error

Failed to list methods for service "mobile.Mobile": Symbol not found: mobile.Mobile
caused by: File not found: location/location.proto

I'd like to avoid refactoring the packages (which does work, but I have to flatten them) but I'd like to know of this is a symptom of how I have the packae imports, the gRPC reflection service, or the reflection in grpcurl itself.

My feeling though, is that if the protos compile, the server compiles, the reflection service should have enough information to define the types. Any feedback is appreciated.

Edit: just for posterity, building the protosets and using those with grpcurl does work.

Proposal: Add details in error output

Hello there!
I would like to add the grpc status details in the error output of the CLI, I simply want to display the response as google designed it, see here

Currently the CLI print the error like this: (cmd/grpcurl/grpcurl.go)

if h.Status.Code() != codes.OK {
	fmt.Fprintf(os.Stderr, "ERROR:\n  Code: %s\n  Message: %s\n", 
		h.Status.Code().String(), h.Status.Message())
	exit(1)
}

I propose to add the details:

if h.Status.Code() != codes.OK {
	fmt.Fprintf(os.Stderr, "ERROR:\n  Code: %s\n  Message: %s\n Details: %+v\n", 
		h.Status.Code().String(), h.Status.Message(), h.Status.Details())
	exit(1)
}

I will be happy to do the PR, so what do you think?

P.S: I was wondering if we could add an option to output this in JSON too, since the CLI already outputs in JSON for OK responses.

Go get failing

Go get is failing with this error

# github.com/jhump/protoreflect/dynamic
../../../github.com/jhump/protoreflect/dynamic/json.go:960: undefined: jsonpb.AnyResolver
../../../github.com/jhump/protoreflect/dynamic/json.go:968: undefined: jsonpb.AnyResolver

Make maxMessageSize configurable

I have a service that has a method which outputs a very large data set (~8MB) which exceeds the default message size limit of gRPC (4MB). grpc-java has a property to increase this limit maxInboundMessageSize.

Can we add such a property to grpcurl as well?

$ grpcurl -plaintext -d {} 127.0.0.1:9090 my.example.Service.GetLargeDataSet
ERROR:
  Code: ResourceExhausted
  Message: grpc: received message larger than max (8259568 vs. 4194304)

Cannot install (go error)

Error:

$ go get github.com/fullstorydev/grpcurl
go get: warning: modules disabled by GO111MODULE=auto in GOPATH/src;
	ignoring ../../go.mod;
	see 'go help modules'
# github.com/jhump/protoreflect/dynamic/grpcdynamic
github.com/jhump/protoreflect/dynamic/grpcdynamic/stub.go:35:5: cannot use (*grpc.ClientConn)(nil) (type *grpc.ClientConn) as type Channel in assignment:
	*grpc.ClientConn does not implement Channel (missing Invoke method)


$ go install github.com/fullstorydev/grpcurl/cmd/grpcurl

# github.com/jhump/protoreflect/dynamic/grpcdynamic
github.com/jhump/protoreflect/dynamic/grpcdynamic/stub.go:35:5: cannot use (*grpc.ClientConn)(nil) (type *grpc.ClientConn) as type Channel in assignment:
	*grpc.ClientConn does not implement Channel (missing Invoke method)

Probably caused by newer(and breaking changes) dependency

JSON decoding is done using encoding/json, not jsonpb

This is not the general standard for Protobuf JSON https://developers.google.com/protocol-buffers/docs/proto3#json, jsonpb should be used instead. This will affect inputs such as Well-Known Types.

This can be accomplished via protoreflect, however jsonpb does not have a json.Decoder equivalent, you'll have to have semantics to denote the splitting of messages (perhaps just a newline). https://godoc.org/github.com/fullstorydev/grpcurl#RequestMessageSupplier should also return []byte instead of json.RawMessage to not bind the API to the encoding/json package.

Nil pointer dereference when using protoset option

(Thanks for this project!)

Assume a simple service like the one described in extended.proto, and libprotoc 3.5.1 installed.

I generate extended.protoset:

$ protoc --proto_path=$GOPATH/src --descriptor_set_out=extended.protoset --include_imports $GOPATH/src/github.com/kchristidis/nested/lib/extended/extended.proto

Then, when invoking grpcurl, I get:

$ grpcurl -protoset extended.protoset list
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x114de11]

goroutine 1 [running]:
github.com/golang/protobuf/protoc-gen-go/descriptor.(*FileDescriptorProto).GetName(...)
	/Users/kchrist/Go/src/github.com/jhump/protoreflect/desc/descriptor.go:77
github.com/jhump/protoreflect/desc.CreateFileDescriptor(0xc4201982d0, 0xc42004b400, 0x2, 0x2, 0x2, 0xc42004b400, 0x1)
	/Users/kchrist/Go/src/github.com/jhump/protoreflect/desc/descriptor.go:77 +0x1d1
github.com/fullstorydev/grpcurl.resolveFileDescriptor(0xc42017e2a0, 0xc42017e2d0, 0xc420018740, 0x39, 0xc420169380, 0x0, 0x0)
	/Users/kchrist/Go/src/github.com/fullstorydev/grpcurl/grpcurl.go:110 +0x2c2
github.com/fullstorydev/grpcurl.DescriptorSourceFromFileDescriptorSet(0xc42015ba38, 0xc42004b3a0, 0x2, 0x2, 0xc42004b290)
	/Users/kchrist/Go/src/github.com/fullstorydev/grpcurl/grpcurl.go:86 +0x1d1
github.com/fullstorydev/grpcurl.DescriptorSourceFromProtoSets(0xc42004b170, 0x1, 0x1, 0xc4200165d0, 0xc420059d80, 0x15219e4, 0x6)
	/Users/kchrist/Go/src/github.com/fullstorydev/grpcurl/grpcurl.go:75 +0x505
main.main()
	/Users/kchrist/Go/src/github.com/fullstorydev/grpcurl/cmd/grpcurl/grpcurl.go:230 +0x34c

What am I doing wrong?

insecure option not respected ?

I am getting a TLS handshake error even when I specify the -insecure option
Can you please help me understand what is going on

$ grpcurl -v -insecure localhost:9000 list
Failed to dial target host "localhost:9000": tls: first record does not look like a TLS handshake

main:

func main() {
	lis, err := net.Listen("tcp", "localhost:9000")
	if err != nil {
		log.Fatal(err)
	}
	srv := grpc.NewServer()
	foo.RegisterFooServer(srv, &foo.Server{})
	srv.Serve(lis)
}

Nice tool!

Using a github issue when I have no issue to report!

Great tool, this helped me.

Just saying thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.