Skip to content

Commit

Permalink
Add a ServeHTTP method to *grpc.Server
Browse files Browse the repository at this point in the history
This adds new http.Handler-based ServerTransport in the process,
reusing the HTTP/2 server code in x/net/http2 or Go 1.6+.

All end2end tests pass with this new ServerTransport.

Fixes grpc#75

Also:
Updates grpc#495 (lets user fix it with middleware in front)
Updates grpc#468 (x/net/http2 validates)
Updates grpc#147 (possible with x/net/http2)
Updates grpc#104 (x/net/http2 does this)
  • Loading branch information
bradfitz committed Feb 1, 2016
1 parent 93591e7 commit a4a61af
Show file tree
Hide file tree
Showing 9 changed files with 646 additions and 53 deletions.
22 changes: 17 additions & 5 deletions examples/helloworld/greeter_client/main.go
Expand Up @@ -34,22 +34,34 @@
package main

import (
"crypto/tls"
"flag"
"log"
"os"

pb "google.golang.org/grpc/examples/helloworld/helloworld"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
pb "google.golang.org/grpc/examples/helloworld/helloworld"
)

const (
address = "localhost:50051"
defaultName = "world"
)

var withInsecureTLS = flag.Bool("insecure_tls", false, "Use Insecure TLS; suitable for hitting the greeter_server in -use_http mode")

func main() {
flag.Parse()

// Set up a connection to the server.
conn, err := grpc.Dial(address, grpc.WithInsecure())
var opts []grpc.DialOption
if *withInsecureTLS {
opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})))
} else {
opts = append(opts, grpc.WithInsecure())
}
conn, err := grpc.Dial(address, opts...)
if err != nil {
log.Fatalf("did not connect: %v", err)
}
Expand All @@ -58,8 +70,8 @@ func main() {

// Contact the server and print out its response.
name := defaultName
if len(os.Args) > 1 {
name = os.Args[1]
if flag.NArg() > 0 {
name = flag.Arg(0)
}
r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name})
if err != nil {
Expand Down
35 changes: 27 additions & 8 deletions examples/helloworld/greeter_server/main.go
Expand Up @@ -34,16 +34,21 @@
package main

import (
"flag"
"log"
"net"
"net/http"
"path/filepath"

pb "google.golang.org/grpc/examples/helloworld/helloworld"
"golang.org/x/net/context"
"google.golang.org/grpc"
pb "google.golang.org/grpc/examples/helloworld/helloworld"
"google.golang.org/grpc/testdata"
)

const (
port = ":50051"
var (
listen = flag.String("listen", "localhost:50051", "address to listen on")
httpMode = flag.Bool("use_http", false, "Use net/http integration mode; enables TLS and requires -insecure_tls on the client side")
)

// server is used to implement helloworld.GreeterServer.
Expand All @@ -55,11 +60,25 @@ func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloRe
}

func main() {
lis, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
flag.Parse()

s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})
s.Serve(lis)

log.Printf("Running hello server on %s ...", *listen)
if *httpMode {
// Running a gRPC server when you need to integrate with an existing
// net/http server on the same port: (using HTTP routing as needed)
http.Handle("/", s)
log.Fatal(http.ListenAndServeTLS(*listen, file("server1.pem"), file("server1.key"), http.DefaultServeMux))
} else {
// Running a gRPC server on its own port, without net/http integration:
lis, err := net.Listen("tcp", *listen)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
log.Fatal(s.Serve(lis))
}
}

func file(base string) string { return filepath.Join(testdata.Dir(), base) }
24 changes: 18 additions & 6 deletions examples/route_guide/server/server.go
Expand Up @@ -43,8 +43,10 @@ import (
"fmt"
"io"
"io/ioutil"
"log"
"math"
"net"
"net/http"
"time"

"golang.org/x/net/context"
Expand All @@ -59,7 +61,8 @@ import (
)

var (
tls = flag.Bool("tls", false, "Connection uses TLS if true, else plain TCP")
useTLS = flag.Bool("tls", false, "Connection uses TLS if true, else plain TCP")
useHTTP = flag.Bool("http", false, "Use the ServeHTTP Transport; requires tls")
certFile = flag.String("cert_file", "testdata/server1.pem", "The TLS cert file")
keyFile = flag.String("key_file", "testdata/server1.key", "The TLS key file")
jsonDBFile = flag.String("json_db_file", "testdata/route_guide_db.json", "A json file containing a list of features")
Expand Down Expand Up @@ -221,12 +224,11 @@ func newServer() *routeGuideServer {

func main() {
flag.Parse()
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
if err != nil {
grpclog.Fatalf("failed to listen: %v", err)
if *useHTTP && !*useTLS {
log.Fatalf("-http flag requires -tls")
}
var opts []grpc.ServerOption
if *tls {
if *useTLS {
creds, err := credentials.NewServerTLSFromFile(*certFile, *keyFile)
if err != nil {
grpclog.Fatalf("Failed to generate credentials %v", err)
Expand All @@ -235,5 +237,15 @@ func main() {
}
grpcServer := grpc.NewServer(opts...)
pb.RegisterRouteGuideServer(grpcServer, newServer())
grpcServer.Serve(lis)
log.Printf("Listening on port %d ...", *port)
if *useHTTP {
http.Handle("/", grpcServer)
log.Fatal(http.ListenAndServeTLS(fmt.Sprintf(":%d", *port), *certFile, *keyFile, nil))
} else {
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
if err != nil {
grpclog.Fatalf("failed to listen: %v", err)
}
grpcServer.Serve(lis)
}
}
2 changes: 1 addition & 1 deletion rpc_util.go
Expand Up @@ -273,7 +273,7 @@ func checkRecvPayload(pf payloadFormat, recvCompress string, dc Decompressor) er
case compressionNone:
case compressionMade:
if recvCompress == "" {
return transport.StreamErrorf(codes.InvalidArgument, "grpc: received unexpected payload format %d", pf)
return transport.StreamErrorf(codes.InvalidArgument, "grpc: invalid grpc-encoding %q with compression enabled", recvCompress)
}
if dc == nil || recvCompress != dc.Type() {
return transport.StreamErrorf(codes.InvalidArgument, "grpc: Decompressor is not installed for grpc-encoding %q", recvCompress)
Expand Down

0 comments on commit a4a61af

Please sign in to comment.