grpcurl icon indicating copy to clipboard operation
grpcurl copied to clipboard

Option to add proxy

Open nkpanda opened this issue 4 years ago • 24 comments

Is there any option to forward the traffic via any app proxy? This will help in easy edit of json requests and understanding of full http requests.

nkpanda avatar Jun 16 '20 20:06 nkpanda

grpcurl does not implement the HTTP transport or gRPC protocol details. Instead, it relies on the grpc/grpc-go project for that.

Looking through proxy-related issues in that project (such as https://github.com/grpc/grpc-go/issues/1446), it appears that a proxy can be used by simply setting environment variables. I will investigate and report back how to set that up.

However, that linked issue above does state some limitations with the support of proxies that will apply here.

jhump avatar Jun 17 '20 16:06 jhump

@jhump Is there any update here? Trying to get grpcurl to proxy traffic through tools like Charles or Proxyman.

bbuckland avatar Mar 15 '21 18:03 bbuckland

It looks like the Go runtime for gRPC, which is what grpcurl uses under its hood, supports environment variables in a similar fashion as curl and python: HTTP_PROXY, HTTPS_PROXY, and NO_PROXY can inform the program how to route a request through a proxy.

So I think the following might work. Please try it out:

HTTP_PROXY=127.0.0.1:8080 grpcurl ...

jhump avatar Mar 31 '21 13:03 jhump

@jhump I've tried this with HTTP_PROXY and HTTPS_PROXY and neither changed the behavior of grpcurl. I can see with the output of ss -ntp | grep grpcurl that it continued to connect directly instead of using my SSH tunnel.

terinjokes avatar May 21 '21 19:05 terinjokes

@jhump I've tried this with HTTP_PROXY and HTTPS_PROXY and neither changed the behavior of grpcurl. I can see with the output of ss -ntp | grep grpcurl that it continued to connect directly instead of using my SSH tunnel.

Same here:

$ docker run --rm -e HTTP_PROXY=127.0.0.1:1234 fullstorydev/grpcurl api.grpc.me:443 list
grpc.reflection.v1alpha.ServerReflection
listennotes.v1.Podcasts

$ docker run --rm -e HTTPS_PROXY=127.0.0.1:1234 fullstorydev/grpcurl api.grpc.me:443 list
grpc.reflection.v1alpha.ServerReflection
listennotes.v1.Podcasts

$ docker run --rm -e HTTPS_PROXY=127.0.0.1:1234 -e GRPC_GO_LOG_VERBOSITY_LEVEL=99 -e GRPC_GO_LOG_SEVERITY_LEVEL=info fullstorydev/
grpcurl api.grpc.me:443 list
INFO: 2021/06/04 20:00:29 [core] parsed scheme: ""
INFO: 2021/06/04 20:00:29 [core] scheme "" not registered, fallback to default scheme
INFO: 2021/06/04 20:00:29 [core] ccResolverWrapper: sending update to cc: {[{api.grpc.me:443  <nil> 0 <nil>}] <nil> <nil>}
INFO: 2021/06/04 20:00:29 [core] ClientConn switching balancer to "pick_first"
INFO: 2021/06/04 20:00:29 [core] Channel switches to new LB policy "pick_first"
INFO: 2021/06/04 20:00:29 [core] Subchannel Connectivity change to CONNECTING
INFO: 2021/06/04 20:00:29 [core] Subchannel picks a new address "api.grpc.me:443" to connect
INFO: 2021/06/04 20:00:29 [core] pickfirstBalancer: UpdateSubConnState: 0xc0003504d0, {CONNECTING <nil>}
INFO: 2021/06/04 20:00:29 [core] Channel Connectivity change to CONNECTING
INFO: 2021/06/04 20:00:29 [core] Subchannel Connectivity change to READY
INFO: 2021/06/04 20:00:29 [core] pickfirstBalancer: UpdateSubConnState: 0xc0003504d0, {READY <nil>}
INFO: 2021/06/04 20:00:29 [core] Channel Connectivity change to READY
grpc.reflection.v1alpha.ServerReflection
listennotes.v1.Podcasts
INFO: 2021/06/04 20:00:29 [core] Channel Connectivity change to SHUTDOWN
INFO: 2021/06/04 20:00:29 [core] Subchannel Connectivity change to SHUTDOWN

Z5eyhS0uubejR0SVmX2O avatar Jun 04 '21 18:06 Z5eyhS0uubejR0SVmX2O

The proxy settings are overridden by the customized dialer:

	dialer := func(ctx context.Context, address string) (net.Conn, error) {
		// NB: We *could* handle the TLS handshake ourselves, in the custom
		// dialer (instead of customizing both the dialer and the credentials).
		// But that requires using WithInsecure dial option (so that the gRPC
		// library doesn't *also* try to do a handshake). And that would mean
		// that the library would send the wrong ":scheme" metaheader to
		// servers: it would send "http" instead of "https" because it is
		// unaware that TLS is actually in use.
		conn, err := (&net.Dialer{}).DialContext(ctx, network, address)
		if err != nil {
			writeResult(err)
		}
		return conn, err
	}

It looks like this is the recommended path to take for proxy setting administration according to https://github.com/grpc/grpc-go/issues/1446 It just wasn't coded to support proxies.

Z5eyhS0uubejR0SVmX2O avatar Jun 07 '21 19:06 Z5eyhS0uubejR0SVmX2O

@terinjokes and @Z5eyhS0uubejR0SVmX2O, thanks for trying it out. I'm sorry that didn't work.

I'll have to do more research to understand how to correctly do the proxying using a custom dialer and then figure out a way to test.

If you have the inclination to investigate and then implement and test a fix, I'd happily accept a pull request.

jhump avatar Jun 14 '21 20:06 jhump

Hi! Is there any option to implement this or it is not planned atm?

joanbono avatar Mar 21 '22 17:03 joanbono

Is there a plan to implement it?

krugi avatar Feb 15 '23 22:02 krugi