Socket
Socket
Sign inDemoInstall

github.com/mwitkow/grpc-proxy

Package Overview
Dependencies
10
Alerts
File Explorer

Install Socket

Detect and block malicious and high-risk dependencies

Install

    github.com/mwitkow/grpc-proxy


Version published

Readme

Source

gRPC Proxy

Travis Build Go Report Card Go Reference Apache 2.0 License

gRPC Go Proxy server

Project Goal

Build a transparent reverse proxy for gRPC targets that will make it easy to expose gRPC services over the internet. This includes:

  • no needed knowledge of the semantics of requests exchanged in the call (independent rollouts)
  • easy, declarative definition of backends and their mappings to frontends
  • simple round-robin load balancing of inbound requests from a single connection to multiple backends

The project now exists as a proof of concept, with the key piece being the proxy package that is a generic gRPC reverse proxy handler.

Proxy Handler

The package proxy contains a generic gRPC reverse proxy handler that allows a gRPC server to not know about registered handlers or their data types. Please consult the docs, here's an exaple usage.

You can call proxy.NewProxy to create a *grpc.Server that proxies requests.

proxy := proxy.NewProxy(clientConn)

More advanced users will want to define a StreamDirector that can make more complex decisions on what to do with the request.

director = func(ctx context.Context, fullMethodName string) (context.Context, *grpc.ClientConn, error) {
    md, _ := metadata.FromIncomingContext(ctx)
    outCtx = metadata.NewOutgoingContext(ctx, md.Copy())
    return outCtx, cc, nil
	
    // Make sure we never forward internal services.
    if strings.HasPrefix(fullMethodName, "/com.example.internal.") {
        return outCtx, nil, status.Errorf(codes.Unimplemented, "Unknown method")
    }
    
    if ok {
        // Decide on which backend to dial
        if val, exists := md[":authority"]; exists && val[0] == "staging.api.example.com" {
            // Make sure we use DialContext so the dialing can be cancelled/time out together with the context.
            return outCtx, grpc.DialContext(ctx, "api-service.staging.svc.local", grpc.WithCodec(proxy.Codec())), nil
        } else if val, exists := md[":authority"]; exists && val[0] == "api.example.com" {
            return outCtx, grpc.DialContext(ctx, "api-service.prod.svc.local", grpc.WithCodec(proxy.Codec())), nil
        }
    }
    return outCtx, nil, status.Errorf(codes.Unimplemented, "Unknown method")
}

Then you need to register it with a grpc.Server. The server may have other handlers that will be served locally.

server := grpc.NewServer(
    grpc.CustomCodec(proxy.Codec()),
    grpc.UnknownServiceHandler(proxy.TransparentHandler(director)))
pb_test.RegisterTestServiceServer(server, &testImpl{})

Testing

To make debugging a bit simpler, there are some helpers.

testservice contains a method TestTestServiceServerImpl which performs a complete test against the reference implementation of the TestServiceServer.

In proxy_test.go, the test framework spins up a TestServiceServer that it tests the proxy against. To make debugging a bit simpler (eg. if the developer needs to step into google.golang.org/grpc methods), this TestServiceServer can be provided by a server by passing -test-backend=addr to go test. A simple, local-only implementation of TestServiceServer exists in testservice/server.

License

grpc-proxy is released under the Apache 2.0 license. See LICENSE.txt.

FAQs

Last updated on 12 Feb 2023

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc