From 4d88514f0a0fd214aa135a6ef3d42d9e17203faf Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Fri, 16 Jan 2015 17:03:31 -0800
Subject: [PATCH 01/44] Add README.md

---
 README.md | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 README.md

diff --git a/README.md b/README.md
new file mode 100644
index 00000000..32968848
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+This is the README

From 948f24223e6ca61801d8b6e12f6fd95c6ddc9139 Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Fri, 16 Jan 2015 17:32:04 -0800
Subject: [PATCH 02/44] gRPC-Go initial commit

---
 LICENSE                                |  28 ++
 README.md                              |   1 +
 call.go                                | 165 +++++++
 clientconn.go                          | 216 +++++++++
 codes/codes.go                         | 156 ++++++
 credentials/credentials.go             | 254 ++++++++++
 interop/client/client.go               | 254 ++++++++++
 interop/client/testdata/ca.pem         |  14 +
 interop/client/testdata/server1.key    |  15 +
 interop/client/testdata/server1.pem    |  16 +
 interop/server/server.go               | 209 ++++++++
 interop/server/testdata/ca.pem         |  14 +
 interop/server/testdata/server1.key    |  15 +
 interop/server/testdata/server1.pem    |  16 +
 interop/testdata/messages.proto        |  96 ++++
 interop/testdata/test.proto            |  42 ++
 interop/testdata/test_proto.pb.go      | 402 +++++++++++++++
 interop/testdata/test_proto_grpc.pb.go | 378 +++++++++++++++
 metadata/metadata.go                   | 150 ++++++
 metadata/metadata_test.go              |  81 ++++
 rpc_util.go                            | 281 +++++++++++
 rpc_util_test.go                       | 171 +++++++
 server.go                              | 364 ++++++++++++++
 stream.go                              | 240 +++++++++
 test/end2end_test.go                   | 462 ++++++++++++++++++
 test/testdata/ca.pem                   |  14 +
 test/testdata/server1.key              |  15 +
 test/testdata/server1.pem              |  16 +
 test/testdata/test.pb.go               | 182 +++++++
 test/testdata/test.proto               |  52 ++
 test/testdata/test_grpc.pb.go          | 292 +++++++++++
 transport/control.go                   | 125 +++++
 transport/http2_client_transport.go    | 644 +++++++++++++++++++++++++
 transport/http2_server_transport.go    | 598 +++++++++++++++++++++++
 transport/http_util.go                 | 288 +++++++++++
 transport/http_util_test.go            |  86 ++++
 transport/testdata/ca.pem              |  14 +
 transport/testdata/server1.key         |  15 +
 transport/testdata/server1.pem         |  16 +
 transport/transport.go                 | 437 +++++++++++++++++
 transport/transport_test.go            | 407 ++++++++++++++++
 41 files changed, 7241 insertions(+)
 create mode 100644 LICENSE
 create mode 100644 README.md
 create mode 100755 call.go
 create mode 100755 clientconn.go
 create mode 100755 codes/codes.go
 create mode 100755 credentials/credentials.go
 create mode 100755 interop/client/client.go
 create mode 100644 interop/client/testdata/ca.pem
 create mode 100644 interop/client/testdata/server1.key
 create mode 100644 interop/client/testdata/server1.pem
 create mode 100755 interop/server/server.go
 create mode 100644 interop/server/testdata/ca.pem
 create mode 100644 interop/server/testdata/server1.key
 create mode 100644 interop/server/testdata/server1.pem
 create mode 100644 interop/testdata/messages.proto
 create mode 100644 interop/testdata/test.proto
 create mode 100755 interop/testdata/test_proto.pb.go
 create mode 100755 interop/testdata/test_proto_grpc.pb.go
 create mode 100755 metadata/metadata.go
 create mode 100755 metadata/metadata_test.go
 create mode 100755 rpc_util.go
 create mode 100755 rpc_util_test.go
 create mode 100755 server.go
 create mode 100755 stream.go
 create mode 100755 test/end2end_test.go
 create mode 100644 test/testdata/ca.pem
 create mode 100644 test/testdata/server1.key
 create mode 100644 test/testdata/server1.pem
 create mode 100755 test/testdata/test.pb.go
 create mode 100644 test/testdata/test.proto
 create mode 100755 test/testdata/test_grpc.pb.go
 create mode 100755 transport/control.go
 create mode 100755 transport/http2_client_transport.go
 create mode 100755 transport/http2_server_transport.go
 create mode 100755 transport/http_util.go
 create mode 100755 transport/http_util_test.go
 create mode 100644 transport/testdata/ca.pem
 create mode 100644 transport/testdata/server1.key
 create mode 100644 transport/testdata/server1.pem
 create mode 100755 transport/transport.go
 create mode 100755 transport/transport_test.go

diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000..f4988b45
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,28 @@
+Copyright 2014, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+    * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..32968848
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+This is the README
diff --git a/call.go b/call.go
new file mode 100755
index 00000000..7d8f2f6b
--- /dev/null
+++ b/call.go
@@ -0,0 +1,165 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package rpc
+
+import (
+	"io"
+
+	"github.com/google/grpc-go/codes"
+	"github.com/google/grpc-go/metadata"
+	"github.com/google/grpc-go/transport"
+	"github.com/golang/protobuf/proto"
+	"golang.org/x/net/context"
+)
+
+// recv receives and parses an RPC response.
+// On error, it returns the error and indicates whether the call should be retried.
+//
+// TODO(zhaoq): Check whether the received message sequence is valid.
+func recv(stream *transport.Stream, reply proto.Message) error {
+	p := &parser{s: stream}
+	for {
+		if err := recvProto(p, reply); err != nil {
+			if err == io.EOF {
+				return nil
+			}
+			return err
+		}
+	}
+}
+
+// sendRPC writes out various information of an RPC such as Context and Message.
+func sendRPC(ctx context.Context, callHdr *transport.CallHdr, t transport.ClientTransport, args proto.Message, opts *transport.Options) (_ *transport.Stream, err error) {
+	stream, err := t.NewStream(ctx, callHdr)
+	if err != nil {
+		return nil, err
+	}
+	defer func() {
+		if err != nil {
+			if _, ok := err.(transport.ConnectionError); !ok {
+				t.CloseStream(stream, err)
+			}
+		}
+	}()
+	// TODO(zhaoq): Support compression.
+	outBuf, err := encode(args, compressionNone)
+	if err != nil {
+		return nil, transport.StreamErrorf(codes.Internal, "%v", err)
+	}
+	err = t.Write(stream, outBuf, opts)
+	if err != nil {
+		return nil, err
+	}
+	// Sent successfully.
+	return stream, nil
+}
+
+// callInfo contains all related configuration and information about an RPC.
+type callInfo struct {
+	failFast  bool
+	headerMD  metadata.MD
+	trailerMD metadata.MD
+}
+
+// Invoke is called by the generated code. It sends the RPC request on the
+// wire and returns after response is received.
+func Invoke(ctx context.Context, method string, args, reply proto.Message, cc *ClientConn, opts ...CallOption) error {
+	var c callInfo
+	for _, o := range opts {
+		if err := o.before(&c); err != nil {
+			return toRPCErr(err)
+		}
+	}
+	defer func() {
+		for _, o := range opts {
+			o.after(&c)
+		}
+	}()
+	callHdr := &transport.CallHdr{
+		Host:   cc.target,
+		Method: method,
+	}
+	topts := &transport.Options{
+		Last:  true,
+		Delay: false,
+	}
+	ts := 0
+	var lastErr error // record the error happened in the last iteration
+	for {
+		var (
+			err    error
+			t      transport.ClientTransport
+			stream *transport.Stream
+		)
+		// TODO(zhaoq): Need a formal spec of retry strategy for non-failfast rpcs.
+		if lastErr != nil && c.failFast {
+			return lastErr
+		}
+		t, ts, err = cc.wait(ctx, ts)
+		if err != nil {
+			if lastErr != nil {
+				// This was a retry; return the error from the last attempt.
+				return lastErr
+			}
+			return err
+		}
+		stream, err = sendRPC(ctx, callHdr, t, args, topts)
+		if err != nil {
+			if _, ok := err.(transport.ConnectionError); ok {
+				lastErr = err
+				continue
+			}
+			if lastErr != nil {
+				return toRPCErr(lastErr)
+			}
+			return toRPCErr(err)
+		}
+		// Try to acquire header metadata from the server if there is any.
+		m, err := stream.Header()
+		if err != nil {
+			return toRPCErr(err)
+		}
+		c.headerMD = metadata.New(m)
+		// Receive the response
+		lastErr = recv(stream, reply)
+		if _, ok := lastErr.(transport.ConnectionError); ok {
+			continue
+		}
+		c.trailerMD = stream.Trailer()
+		t.CloseStream(stream, lastErr)
+		if lastErr != nil {
+			return toRPCErr(lastErr)
+		}
+		return Errorf(stream.StatusCode(), stream.StatusDesc())
+	}
+}
diff --git a/clientconn.go b/clientconn.go
new file mode 100755
index 00000000..dda5e433
--- /dev/null
+++ b/clientconn.go
@@ -0,0 +1,216 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/*
+Package rpc implements various components to perform RPC on top of transport package.
+*/
+package rpc
+
+import (
+	"fmt"
+	"sync"
+	"time"
+
+	"github.com/google/grpc-go/credentials"
+	"github.com/google/grpc-go/transport"
+	"golang.org/x/net/context"
+)
+
+type dialOptions struct {
+	protocol    string
+	authOptions []credentials.Credentials
+	// TBD: other options
+}
+
+// DialOption configures how we set up the connection including auth
+// credentials.
+type DialOption func(*dialOptions)
+
+// WithClientTLS returns a DialOption which configures a TLS credentials
+// for connection.
+func WithClientTLS(creds credentials.TransportAuthenticator) DialOption {
+	return func(o *dialOptions) {
+		o.authOptions = append(o.authOptions, creds)
+	}
+}
+
+// WithComputeEngine returns a DialOption which sets a
+// credentials which uses application default credentials as provided to
+// Google Compute Engine. Note that TLS credentials is typically also
+// needed. If it is the case, users need to pass WithTLS option too.
+func WithComputeEngine(creds credentials.Credentials) DialOption {
+	return func(o *dialOptions) {
+		o.authOptions = append(o.authOptions, creds)
+	}
+}
+
+// Dial creates a client connection the given target.
+// TODO(zhaoq): Have an option to make Dial return immediately without waiting
+// for connection complete.
+func Dial(target string, opts ...DialOption) (*ClientConn, error) {
+	if target == "" {
+		return nil, fmt.Errorf("rpc.Dial: target is empty")
+	}
+	cc := &ClientConn{
+		target: target,
+	}
+	for _, opt := range opts {
+		opt(&cc.dopts)
+	}
+	err := cc.resetTransport(false)
+	if err != nil {
+		return nil, err
+	}
+	cc.shutdownChan = make(chan struct{})
+	// Start to monitor the error status of transport.
+	go cc.transportMonitor()
+	return cc, nil
+}
+
+// ClientConn represents a client connection to an RPC service.
+type ClientConn struct {
+	target       string
+	dopts        dialOptions
+	shutdownChan chan struct{}
+
+	mu sync.Mutex
+	// Is closed and becomes nil when a new transport is up.
+	ready chan struct{}
+	// Indicates the ClientConn is under destruction.
+	closing bool
+	// Every time a new transport is created, this is incremented by 1. Used
+	// to avoid trying to recreate a transport while the new one is already
+	// under construction.
+	transportSeq int
+	transport    transport.ClientTransport
+}
+
+func (cc *ClientConn) resetTransport(closeTransport bool) error {
+	var retries int
+	for {
+		cc.mu.Lock()
+		t := cc.transport
+		ts := cc.transportSeq
+		// Avoid wait() picking up a dying transport unnecessarily.
+		cc.transportSeq = 0
+		if cc.closing {
+			cc.mu.Unlock()
+			return fmt.Errorf("rpc.ClientConn.resetTransport: the channel is closing")
+		}
+		cc.mu.Unlock()
+		if closeTransport {
+			t.Close()
+		}
+		newTransport, err := transport.NewClientTransport(cc.dopts.protocol, cc.target, cc.dopts.authOptions)
+		if err != nil {
+			closeTransport = false
+			time.Sleep(backoff(retries))
+			retries++
+			continue
+		}
+		cc.mu.Lock()
+		cc.transport = newTransport
+		cc.transportSeq = ts + 1
+		if cc.ready != nil {
+			close(cc.ready)
+			cc.ready = nil
+		}
+		cc.mu.Unlock()
+		return nil
+	}
+}
+
+// Run in a goroutine to track the error in transport and create the
+// new transport if an error happens. It returns when the channel is closing.
+func (cc *ClientConn) transportMonitor() {
+	for {
+		select {
+		// shutdownChan is needed to detect the channel teardown when
+		// the ClientConn is idle (i.e., no RPC in flight).
+		case <-cc.shutdownChan:
+			return
+		case <-cc.transport.Error():
+			err := cc.resetTransport(true)
+			if err != nil {
+				// The channel is closing.
+				return
+			}
+			continue
+		}
+	}
+}
+
+// When wait returns, either the new transport is up or ClientConn is
+// closing. Used to avoid working on a dying transport. It updates and
+// returns the transport and its version when there is no error.
+func (cc *ClientConn) wait(ctx context.Context, ts int) (transport.ClientTransport, int, error) {
+	for {
+		cc.mu.Lock()
+		switch {
+		case cc.closing:
+			cc.mu.Unlock()
+			return nil, 0, fmt.Errorf("ClientConn is closing")
+		case ts < cc.transportSeq:
+			// Worked on a dying transport. Try the new one immediately.
+			defer cc.mu.Unlock()
+			return cc.transport, cc.transportSeq, nil
+		default:
+			ready := cc.ready
+			if ready == nil {
+				ready = make(chan struct{})
+				cc.ready = ready
+			}
+			cc.mu.Unlock()
+			select {
+			case <-ctx.Done():
+				return nil, 0, transport.ContextErr(ctx.Err())
+			// Wait until the new transport is ready.
+			case <-ready:
+			}
+		}
+	}
+}
+
+// Close starts to tear down the ClientConn.
+// TODO(zhaoq): Make this synchronous to avoid unbounded memory consumption in
+// some edge cases (e.g., the caller opens and closes many ClientConn's in a
+// tight loop.
+func (cc *ClientConn) Close() {
+	cc.mu.Lock()
+	defer cc.mu.Unlock()
+	if cc.closing {
+		return
+	}
+	cc.closing = true
+	cc.transport.Close()
+	close(cc.shutdownChan)
+}
diff --git a/codes/codes.go b/codes/codes.go
new file mode 100755
index 00000000..636cd022
--- /dev/null
+++ b/codes/codes.go
@@ -0,0 +1,156 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+// Package codes defines the canonical error codes used by gRPC. It is
+// consistent across various languages.
+package codes
+
+// An Code is an unsigned 32-bit error code as defined gRPC spec.
+type Code uint32
+
+const (
+	// OK means returned on success
+	OK Code = 0
+
+	// Canceled indicates the operation was cancelled (typically by the caller).
+	Canceled Code = 1
+
+	// Unknown error.  An example of where this error may be returned is
+	// if a Status value received from another address space belongs to
+	// an error-space that is not known in this address space.  Also
+	// errors raised by APIs that do not return enough error information
+	// may be converted to this error.
+	Unknown Code = 2
+
+	// InvalidArgument indicattes client specified an invalid argument.
+	// Note that this differs from FailedPrecondition. It indicates arguments
+	// that are problematic regardless of the state of the system
+	// (e.g., a malformed file name).
+	InvalidArgument Code = 3
+
+	// DeadlineExceeded means operation expired before completion.
+	// For operations that change the state of the system, this error may be
+	// returned even if the operation has completed successfully. For
+	// example, a successful response from a server could have been delayed
+	// long enough for the deadline to expire.
+	DeadlineExceeded Code = 4
+
+	// NotFound means some requested entity (e.g., file or directory) was
+	// not found.
+	NotFound Code = 5
+
+	// AlreadyExists means some entity that we attempted to create
+	// already exists.
+	AlreadyExists Code = 6
+
+	// PermissionDenied indicates the caller does not have permission to
+	// execute the specified operation. It must not be used for rejections
+	// caused by exhausting some resource (use ResourceExhausted
+	// instead for those errors).  It must not be
+	// used if the caller can not be identified (use Unauthenticated
+	// instead for those errors).
+	PermissionDenied Code = 7
+
+	// Unauthenticated indicates the request does not have valid
+	// authentication credentials for the operation.
+	Unauthenticated Code = 16
+
+	// ResourceExhausted indicates some resource has been exhausted, perhaps
+	// a per-user quota, or perhaps the entire file system is out of space.
+	ResourceExhausted Code = 8
+
+	// FailedPrecondition indicates operation was rejected because the
+	// system is not in a state required for the operation's execution.
+	// For example, directory to be deleted may be non-empty, an rmdir
+	// operation is applied to a non-directory, etc.
+	//
+	// A litmus test that may help a service implementor in deciding
+	// between FailedPrecondition, ABORTED, and Unavailable:
+	//  (a) Use Unavailable if the client can retry just the failing call.
+	//  (b) Use ABORTED if the client should retry at a higher-level
+	//      (e.g., restarting a read-modify-write sequence).
+	//  (c) Use FailedPrecondition if the client should not retry until
+	//      the system state has been explicitly fixed.  E.g., if an "rmdir"
+	//      fails because the directory is non-empty, FailedPrecondition
+	//      should be returned since the client should not retry unless
+	//      they have first fixed up the directory by deleting files from it.
+	//  (d) Use FailedPrecondition if the client performs conditional
+	//      REST Get/Update/Delete on a resource and the resource on the
+	//      server does not match the condition. E.g., conflicting
+	//      read-modify-write on the same resource.
+	FailedPrecondition Code = 9
+
+	// Aborted indicates the operation was aborted, typically due to a
+	// concurrency issue like sequencer check failures, transaction aborts,
+	// etc.
+	//
+	// See litmus test above for deciding between FailedPrecondition,
+	// ABORTED, and Unavailable.
+	Aborted Code = 10
+
+	// OutOfRange means oOperation was attempted past the valid range.
+	// E.g., seeking or reading past end of file.
+	//
+	// Unlike InvalidArgument, this error indicates a problem that may
+	// be fixed if the system state changes. For example, a 32-bit file
+	// system will generate InvalidArgument if asked to read at an
+	// offset that is not in the range [0,2^32-1], but it will generate
+	// OutOfRange if asked to read from an offset past the current
+	// file size.
+	//
+	// There is a fair bit of overlap between FailedPrecondition and
+	// OutOfRange.  We recommend using OutOfRange (the more specific
+	// error) when it applies so that callers who are iterating through
+	// a space can easily look for an OutOfRange error to detect when
+	// they are done.
+	OutOfRange Code = 11
+
+	// Unimplemented indicates operation is not implemented or not
+	// supported/enabled in this service.
+	Unimplemented Code = 12
+
+	// Internal errors.  Means some invariants expected by underlying
+	// system has been broken.  If you see one of these errors,
+	// something is very broken.
+	Internal Code = 13
+
+	// Unavailable indicates the service is currently unavailable.
+	// This is a most likely a transient condition and may be corrected
+	// by retrying with a backoff.
+	//
+	// See litmus test above for deciding between FailedPrecondition,
+	// Aborted, and Unavailable.
+	Unavailable Code = 14
+
+	// DataLoss indicates unrecoverable data loss or corruption.
+	DataLoss Code = 15
+)
diff --git a/credentials/credentials.go b/credentials/credentials.go
new file mode 100755
index 00000000..e4554db3
--- /dev/null
+++ b/credentials/credentials.go
@@ -0,0 +1,254 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+// Package credentials implements various credentials supported by gRPC library.
+package credentials
+
+import (
+	"crypto/tls"
+	"crypto/x509"
+	"encoding/json"
+	"fmt"
+	"io/ioutil"
+	"net"
+	"net/http"
+	"net/url"
+	"sync"
+	"time"
+)
+
+const (
+	metadataServer     = "metadata"
+	serviceAccountPath = "/computeMetadata/v1/instance/service-accounts/default/token"
+)
+
+var (
+	// alpnProtoStr are the specified application level protocols for gRPC.
+	alpnProtoStr = []string{"h2-14", "h2-15", "h2-16"}
+)
+
+// Credentials defines the common interface all supported credentials must
+// implement.
+type Credentials interface {
+	// GetRequestMetadata gets the current request metadata, refreshing
+	// tokens if required. This should be called by the transport layer on
+	// each request, and the data should be populated in headers or other
+	// context. The operation may do things like refresh tokens.
+	GetRequestMetadata() (map[string]string, error)
+}
+
+// TransportAuthenticator defines the common interface all supported transport
+// authentication protocols (e.g., TLS, SSL) must implement.
+type TransportAuthenticator interface {
+	// Dial connects to the given network address and does the authentication
+	// handshake specified by the corresponding authentication protocol.
+	Dial(add string) (net.Conn, error)
+	// NewListener creates a listener which accepts connections with requested
+	// authentication handshake.
+	NewListener(lis net.Listener) net.Listener
+	Credentials
+}
+
+// tlsCreds is the credentials required for authenticating a connection.
+type tlsCreds struct {
+	// serverName is used to verify the hostname on the returned
+	// certificates. It is also included in the client's handshake
+	// to support virtual hosting. This is optional. If it is not
+	// set gRPC internals will use the dialing address instead.
+	serverName string
+	// rootCAs defines the set of root certificate authorities
+	// that clients use when verifying server certificates.
+	// If rootCAs is nil, tls uses the host's root CA set.
+	rootCAs *x509.CertPool
+	// certificates contains one or more certificate chains
+	// to present to the other side of the connection.
+	// Server configurations must include at least one certificate.
+	certificates []tls.Certificate
+}
+
+// GetRequestMetadata returns nil, nil since TLS credentials does not have
+// metadata.
+func (c *tlsCreds) GetRequestMetadata() (map[string]string, error) {
+	return nil, nil
+}
+
+// Dial connects to addr and performs TLS handshake.
+func (c *tlsCreds) Dial(addr string) (_ net.Conn, err error) {
+	name := c.serverName
+	if name == "" {
+		name, _, err = net.SplitHostPort(addr)
+		if err != nil {
+			return nil, fmt.Errorf("failed to parse server address %v", err)
+		}
+	}
+	return tls.Dial("tcp", addr, &tls.Config{
+		RootCAs:    c.rootCAs,
+		NextProtos: alpnProtoStr,
+		ServerName: name,
+	})
+}
+
+// NewListener creates a net.Listener with a TLS configuration constructed
+// from the information in tlsCreds.
+func (c *tlsCreds) NewListener(lis net.Listener) net.Listener {
+	return tls.NewListener(lis, &tls.Config{
+		Certificates: c.certificates,
+		NextProtos:   alpnProtoStr,
+	})
+}
+
+// NewClientTLSFromCert constructs a TLS from the input certificate for client.
+func NewClientTLSFromCert(cp *x509.CertPool, serverName string) TransportAuthenticator {
+	return &tlsCreds{
+		serverName: serverName,
+		rootCAs:    cp,
+	}
+}
+
+// NewClientTLSFromFile constructs a TLS from the input certificate file for client.
+func NewClientTLSFromFile(certFile, serverName string) (TransportAuthenticator, error) {
+	b, err := ioutil.ReadFile(certFile)
+	if err != nil {
+		return nil, err
+	}
+	cp := x509.NewCertPool()
+	if !cp.AppendCertsFromPEM(b) {
+		return nil, fmt.Errorf("failed to append certificates")
+	}
+	return &tlsCreds{
+		serverName: serverName,
+		rootCAs:    cp,
+	}, nil
+}
+
+// NewServerTLSFromCert constructs a TLS from the input certificate for server.
+func NewServerTLSFromCert(cert *tls.Certificate) TransportAuthenticator {
+	return &tlsCreds{
+		certificates: []tls.Certificate{*cert},
+	}
+}
+
+// NewServerTLSFromFile constructs a TLS from the input certificate file and key
+// file for server.
+func NewServerTLSFromFile(certFile, keyFile string) (TransportAuthenticator, error) {
+	cert, err := tls.LoadX509KeyPair(certFile, keyFile)
+	if err != nil {
+		return nil, err
+	}
+	return &tlsCreds{
+		certificates: []tls.Certificate{cert},
+	}, nil
+}
+
+type tokenData struct {
+	accessToken string
+	expiresIn   float64
+	tokeType    string
+}
+
+type token struct {
+	accessToken string
+	expiry      time.Time
+}
+
+// expired returns true if there is no access token or the
+// access token is expired.
+func (t token) expired() bool {
+	if t.accessToken == "" {
+		return true
+	}
+	if t.expiry.IsZero() {
+		return false
+	}
+	return t.expiry.Before(time.Now())
+}
+
+// computeEngine uses the Application Default Credentials as provided to Google Compute Engine instances.
+type computeEngine struct {
+	mu sync.Mutex
+	t  token
+}
+
+// GetRequestMetadata returns a refreshed access token.
+func (c *computeEngine) GetRequestMetadata() (map[string]string, error) {
+	c.mu.Lock()
+	defer c.mu.Unlock()
+	if c.t.expired() {
+		if err := c.refresh(); err != nil {
+			return nil, err
+		}
+	}
+	return map[string]string{
+		"authorization": "Bearer " + c.t.accessToken,
+	}, nil
+}
+
+func (c *computeEngine) refresh() error {
+	// https://developers.google.com/compute/docs/metadata
+	// v1 requires "Metadata-Flavor: Google" header.
+	tokenURL := &url.URL{
+		Scheme: "http",
+		Host:   metadataServer,
+		Path:   serviceAccountPath,
+	}
+	req, err := http.NewRequest("GET", tokenURL.String(), nil)
+	if err != nil {
+		return err
+	}
+	req.Header.Add("Metadata-Flavor", "Google")
+	resp, err := http.DefaultClient.Do(req)
+	if err != nil {
+		return err
+	}
+	defer resp.Body.Close()
+	var td tokenData
+	err = json.NewDecoder(resp.Body).Decode(&td)
+	if err != nil {
+		return err
+	}
+	// No need to check td.tokenType.
+	c.t = token{
+		accessToken: td.accessToken,
+		expiry:      time.Now().Add(time.Duration(td.expiresIn) * time.Second),
+	}
+	return nil
+}
+
+// NewComputeEngine constructs a credentials for GCE.
+func NewComputeEngine() (Credentials, error) {
+	creds := &computeEngine{}
+	// TODO(zhaoq): This is not optimal if refresh() is persistently failed.
+	if err := creds.refresh(); err != nil {
+		return nil, err
+	}
+	return creds, nil
+}
diff --git a/interop/client/client.go b/interop/client/client.go
new file mode 100755
index 00000000..9ab97532
--- /dev/null
+++ b/interop/client/client.go
@@ -0,0 +1,254 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package main
+
+import (
+	"flag"
+	"io"
+	"log"
+	"net"
+	"strconv"
+
+	"github.com/google/grpc-go/credentials"
+	testpb "github.com/google/grpc-go/interop/testdata"
+	"github.com/google/grpc-go"
+	"github.com/golang/protobuf/proto"
+	"golang.org/x/net/context"
+)
+
+var (
+	useTLS     = flag.Bool("use_tls", false, "Connection uses TLS if true, else plain TCP")
+	caFile     = flag.String("tls_ca_file", "testdata/ca.pem", "The file containning the CA root cert file")
+	serverHost = flag.String("server_host", "127.0.0.1", "The server host name")
+	serverPort = flag.Int("server_port", 10000, "The server port number")
+	testCase   = flag.String("test_case", "large_unary", "The RPC method to be tested: large_unary|empty_unary|client_streaming|server_streaming|ping_pong")
+)
+
+var (
+	reqSizes  = []int{27182, 8, 1828, 45904}
+	respSizes = []int{31415, 9, 2653, 58979}
+)
+
+func newPayload(t testpb.PayloadType, size int) *testpb.Payload {
+	if size < 0 {
+		log.Fatalf("Requested a response with invalid length %d", size)
+	}
+	body := make([]byte, size)
+	switch t {
+	case testpb.PayloadType_COMPRESSABLE:
+	case testpb.PayloadType_UNCOMPRESSABLE:
+		log.Fatalf("PayloadType UNCOMPRESSABLE is not supported")
+	default:
+		log.Fatalf("Unsupported payload type: %d", t)
+	}
+	return &testpb.Payload{
+		Type: t.Enum(),
+		Body: body,
+	}
+}
+
+func doEmptyUnaryCall(tc testpb.TestServiceClient) {
+	reply, err := tc.EmptyCall(context.Background(), &testpb.Empty{})
+	if err != nil {
+		log.Fatal("/TestService/EmptyCall RPC failed: ", err)
+	}
+	if !proto.Equal(&testpb.Empty{}, reply) {
+		log.Fatalf("/TestService/EmptyCall receives %v, want %v", reply, testpb.Empty{})
+	}
+}
+
+func doLargeUnaryCall(tc testpb.TestServiceClient) {
+	argSize := 271828
+	respSize := 314159
+	pl := newPayload(testpb.PayloadType_COMPRESSABLE, argSize)
+	req := &testpb.SimpleRequest{
+		ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(),
+		ResponseSize: proto.Int32(int32(respSize)),
+		Payload:      pl,
+	}
+	reply, err := tc.UnaryCall(context.Background(), req)
+	if err != nil {
+		log.Fatal("/TestService/UnaryCall RPC failed: ", err)
+	}
+	t := reply.GetPayload().GetType()
+	s := len(reply.GetPayload().GetBody())
+	if t != testpb.PayloadType_COMPRESSABLE || s != respSize {
+		log.Fatalf("Got the reply with type %d len %d; want %d, %d", t, s, testpb.PayloadType_COMPRESSABLE, respSize)
+	}
+}
+
+func doClientStreaming(tc testpb.TestServiceClient) {
+	stream, err := tc.StreamingInputCall(context.Background())
+	if err != nil {
+		log.Fatalf("%v.StreamingInputCall(_) = _, %v", tc, err)
+	}
+	var sum int
+	for _, s := range reqSizes {
+		pl := newPayload(testpb.PayloadType_COMPRESSABLE, s)
+		req := &testpb.StreamingInputCallRequest{
+			Payload: pl,
+		}
+		if err := stream.Send(req); err != nil {
+			log.Fatalf("%v.Send(%v) = %v", stream, req, err)
+		}
+		sum += s
+		log.Printf("Sent a request of size %d, aggregated size %d", s, sum)
+
+	}
+	reply, err := stream.CloseAndRecv()
+	if err != io.EOF {
+		log.Fatalf("%v.CloseAndRecv() got error %v, want %v", stream, err, io.EOF)
+	}
+	if reply.GetAggregatedPayloadSize() != int32(sum) {
+		log.Fatalf("%v.CloseAndRecv().GetAggregatePayloadSize() = %v; want %v", stream, reply.GetAggregatedPayloadSize(), sum)
+	}
+}
+
+func doServerStreaming(tc testpb.TestServiceClient) {
+	respParam := make([]*testpb.ResponseParameters, len(respSizes))
+	for i, s := range respSizes {
+		respParam[i] = &testpb.ResponseParameters{
+			Size: proto.Int32(int32(s)),
+		}
+	}
+	req := &testpb.StreamingOutputCallRequest{
+		ResponseType:       testpb.PayloadType_COMPRESSABLE.Enum(),
+		ResponseParameters: respParam,
+	}
+	stream, err := tc.StreamingOutputCall(context.Background(), req)
+	if err != nil {
+		log.Fatalf("%v.StreamingOutputCall(_) = _, %v", tc, err)
+	}
+	var rpcStatus error
+	var respCnt int
+	var index int
+	for {
+		reply, err := stream.Recv()
+		if err != nil {
+			rpcStatus = err
+			break
+		}
+		t := reply.GetPayload().GetType()
+		if t != testpb.PayloadType_COMPRESSABLE {
+			log.Fatalf("Got the reply of type %d, want %d", t, testpb.PayloadType_COMPRESSABLE)
+		}
+		size := len(reply.GetPayload().GetBody())
+		if size != int(respSizes[index]) {
+			log.Fatalf("Got reply body of length %d, want %d", size, respSizes[index])
+		}
+		index++
+		respCnt++
+	}
+	if rpcStatus != io.EOF {
+		log.Fatalf("Failed to finish the server streaming rpc: %v", err)
+	}
+	if respCnt != len(respSizes) {
+		log.Fatalf("Got %d reply, want %d", len(respSizes), respCnt)
+	}
+}
+
+func doPingPong(tc testpb.TestServiceClient) {
+	stream, err := tc.FullDuplexCall(context.Background())
+	if err != nil {
+		log.Fatalf("%v.FullDuplexCall(_) = _, %v", tc, err)
+	}
+	var index int
+	for index < len(reqSizes) {
+		respParam := []*testpb.ResponseParameters{
+			&testpb.ResponseParameters{
+				Size: proto.Int32(int32(respSizes[index])),
+			},
+		}
+		pl := newPayload(testpb.PayloadType_COMPRESSABLE, reqSizes[index])
+		req := &testpb.StreamingOutputCallRequest{
+			ResponseType:       testpb.PayloadType_COMPRESSABLE.Enum(),
+			ResponseParameters: respParam,
+			Payload:            pl,
+		}
+		if err := stream.Send(req); err != nil {
+			log.Fatalf("%v.Send(%v) = %v", stream, req, err)
+		}
+		reply, err := stream.Recv()
+		if err != nil {
+			log.Fatalf("%v.Recv() = %v", stream, err)
+		}
+		t := reply.GetPayload().GetType()
+		if t != testpb.PayloadType_COMPRESSABLE {
+			log.Fatalf("Got the reply of type %d, want %d", t, testpb.PayloadType_COMPRESSABLE)
+		}
+		size := len(reply.GetPayload().GetBody())
+		if size != int(respSizes[index]) {
+			log.Fatalf("Got reply body of length %d, want %d", size, respSizes[index])
+		}
+		index++
+	}
+	if err := stream.CloseSend(); err != nil {
+		log.Fatalf("%v.CloseSend() got %v, want %v", stream, err, nil)
+	}
+	if _, err := stream.Recv(); err != io.EOF {
+		log.Fatalf("%v failed to complele the ping pong test: %v", stream, err)
+	}
+}
+
+func main() {
+	flag.Parse()
+	serverAddr := net.JoinHostPort(*serverHost, strconv.Itoa(*serverPort))
+	var opts []rpc.DialOption
+	if *useTLS {
+		creds, err := credentials.NewClientTLSFromFile(*caFile, "x.test.youtube.com")
+		if err != nil {
+			log.Fatalf("Failed to create credentials %v", err)
+		}
+		opts = append(opts, rpc.WithClientTLS(creds))
+	}
+	conn, err := rpc.Dial(serverAddr, opts...)
+	if err != nil {
+		log.Fatalf("fail to dial: %v", err)
+	}
+	defer conn.Close()
+	tc := testpb.NewTestServiceClient(conn)
+	switch *testCase {
+	case "empty_unary":
+		doEmptyUnaryCall(tc)
+	case "large_unary":
+		doLargeUnaryCall(tc)
+	case "client_streaming":
+		doClientStreaming(tc)
+	case "server_streaming":
+		doServerStreaming(tc)
+	case "ping_pong":
+		doPingPong(tc)
+	default:
+		log.Fatal("Unsupported test case: ", *testCase)
+	}
+}
diff --git a/interop/client/testdata/ca.pem b/interop/client/testdata/ca.pem
new file mode 100644
index 00000000..999da897
--- /dev/null
+++ b/interop/client/testdata/ca.pem
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICIzCCAYwCCQCFTbF7XNSvvjANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJB
+VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
+cyBQdHkgTHRkMQ8wDQYDVQQDDAZ0ZXN0Y2EwHhcNMTQwNzE3MjMxNzUxWhcNMjQw
+NzE0MjMxNzUxWjBWMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEh
+MB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQ8wDQYDVQQDDAZ0ZXN0
+Y2EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMBA3wVeTGHZR1Rye/i+J8a2
+cu5gXwFV6TnObzGM7bLFCO5i9v4mLo4iFzPsHmWDUxKS3Y8iXbu0eYBlLoNY0lSv
+xDx33O+DuwMmVN+DzSD+Eod9zfvwOWHsazYCZT2PhNxnVWIuJXViY4JAHUGodjx+
+QAi6yCAurUZGvYXGgZSBAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAQoQVD8bwdtWJ
+AniGBwcCfqYyH+/KpA10AcebJVVTyYbYvI9Q8d6RSVu4PZy9OALHR/QrWBdYTAyz
+fNAmc2cmdkSRJzjhIaOstnQy1J+Fk0T9XyvQtq499yFbq9xogUVlEGH62xP6vH0Y
+5ukK//dCPAzA11YuX2rnex0JhuTQfcI=
+-----END CERTIFICATE-----
diff --git a/interop/client/testdata/server1.key b/interop/client/testdata/server1.key
new file mode 100644
index 00000000..ed00cd50
--- /dev/null
+++ b/interop/client/testdata/server1.key
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICWwIBAAKBgQDhwxUnKCwlSaWAwzOB2LSHVegJHv7DDWminTg4wzLLsf+LQ8nZ
+bpjfn5vgIzxCuRh4Rp9QYM5FhfrJX9wcYawP/HTbJ7p7LVQO2QYAP+akMTHxgKuM
+BzVV++3wWToKfVZUjFX8nfTfGMGwWAHJDnlEGnU4tl9UujoCV4ENJtzFoQIDAQAB
+AoGAJ+6hpzNr24yTQZtFWQpDpEyFplddKJMOxDya3S9ppK3vTWrIITV2xNcucw7I
+ceTbdyrGsyjsU0/HdCcIf9ym2jfmGLUwmyhltKVw0QYcFB0XLkc0nI5YvEYoeVDg
+omZIXn1E3EW+sSIWSbkMu9bY2kstKXR2UZmMgWDtmBEPMaECQQD6yT4TAZM5hGBb
+ciBKgMUP6PwOhPhOMPIvijO50Aiu6iuCV88l1QIy38gWVhxjNrq6P346j4IBg+kB
+9alwpCODAkEA5nSnm9k6ykYeQWNS0fNWiRinCdl23A7usDGSuKKlm019iomJ/Rgd
+MKDOp0q/2OostbteOWM2MRFf4jMH3wyVCwJAfAdjJ8szoNKTRSagSbh9vWygnB2v
+IByc6l4TTuZQJRGzCveafz9lovuB3WohCABdQRd9ukCXL2CpsEpqzkafOQJAJUjc
+USedDlq3zGZwYM1Yw8d8RuirBUFZNqJelYai+nRYClDkRVFgb5yksoYycbq5TxGo
+VeqKOvgPpj4RWPHlLwJAGUMk3bqT91xBUCnLRs/vfoCpHpg6eywQTBDAV6xkyz4a
+RH3I7/+yj3ZxR2JoWHgUwZ7lZk1VnhffFye7SBXyag==
+-----END RSA PRIVATE KEY-----
diff --git a/interop/client/testdata/server1.pem b/interop/client/testdata/server1.pem
new file mode 100644
index 00000000..8e582e57
--- /dev/null
+++ b/interop/client/testdata/server1.pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIICmzCCAgSgAwIBAgIBAzANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJBVTET
+MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ
+dHkgTHRkMQ8wDQYDVQQDDAZ0ZXN0Y2EwHhcNMTQwNzIyMDYwMDU3WhcNMjQwNzE5
+MDYwMDU3WjBkMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
+BAcTB0NoaWNhZ28xFDASBgNVBAoTC0dvb2dsZSBJbmMuMRowGAYDVQQDFBEqLnRl
+c3QuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4cMVJygs
+JUmlgMMzgdi0h1XoCR7+ww1pop04OMMyy7H/i0PJ2W6Y35+b4CM8QrkYeEafUGDO
+RYX6yV/cHGGsD/x02ye6ey1UDtkGAD/mpDEx8YCrjAc1Vfvt8Fk6Cn1WVIxV/J30
+3xjBsFgByQ55RBp1OLZfVLo6AleBDSbcxaECAwEAAaNrMGkwCQYDVR0TBAIwADAL
+BgNVHQ8EBAMCBeAwTwYDVR0RBEgwRoIQKi50ZXN0Lmdvb2dsZS5mcoIYd2F0ZXJ6
+b29pLnRlc3QuZ29vZ2xlLmJlghIqLnRlc3QueW91dHViZS5jb22HBMCoAQMwDQYJ
+KoZIhvcNAQEFBQADgYEAM2Ii0LgTGbJ1j4oqX9bxVcxm+/R5Yf8oi0aZqTJlnLYS
+wXcBykxTx181s7WyfJ49WwrYXo78zTDAnf1ma0fPq3e4mpspvyndLh1a+OarHa1e
+aT0DIIYk7qeEa1YcVljx2KyLd0r1BBAfrwyGaEPVeJQVYWaOJRU2we/KD4ojf9s=
+-----END CERTIFICATE-----
diff --git a/interop/server/server.go b/interop/server/server.go
new file mode 100755
index 00000000..de3c6028
--- /dev/null
+++ b/interop/server/server.go
@@ -0,0 +1,209 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package main
+
+import (
+	"flag"
+	"fmt"
+	"io"
+	"log"
+	"net"
+	"strconv"
+	"time"
+
+	"github.com/google/grpc-go/credentials"
+	testpb "github.com/google/grpc-go/interop/testdata"
+	"github.com/google/grpc-go"
+	"github.com/golang/protobuf/proto"
+	"golang.org/x/net/context"
+)
+
+var (
+	useTLS   = flag.Bool("use_tls", false, "Connection uses TLS if true, else plain TCP")
+	certFile = flag.String("tls_cert_file", "testdata/server1.pem", "The TLS cert file")
+	keyFile  = flag.String("tls_key_file", "testdata/server1.key", "The TLS key file")
+	port     = flag.Int("port", 10000, "The server port")
+)
+
+type testServer struct {
+}
+
+func (s *testServer) EmptyCall(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) {
+	return new(testpb.Empty), nil
+}
+
+func newPayload(t testpb.PayloadType, size int32) (*testpb.Payload, error) {
+	if size < 0 {
+		return nil, fmt.Errorf("Requested a response with invalid length %d", size)
+	}
+	body := make([]byte, size)
+	switch t {
+	case testpb.PayloadType_COMPRESSABLE:
+	case testpb.PayloadType_UNCOMPRESSABLE:
+		return nil, fmt.Errorf("PayloadType UNCOMPRESSABLE is not supported")
+	default:
+		return nil, fmt.Errorf("Unsupported payload type: %d", t)
+	}
+	return &testpb.Payload{
+		Type: t.Enum(),
+		Body: body,
+	}, nil
+}
+
+func (s *testServer) UnaryCall(ctx context.Context, in *testpb.SimpleRequest) (*testpb.SimpleResponse, error) {
+	pl, err := newPayload(in.GetResponseType(), in.GetResponseSize())
+	if err != nil {
+		return nil, err
+	}
+	return &testpb.SimpleResponse{
+		Payload: pl,
+	}, nil
+}
+
+func (s *testServer) StreamingOutputCall(args *testpb.StreamingOutputCallRequest, stream testpb.TestService_StreamingOutputCallServer) error {
+	cs := args.GetResponseParameters()
+	for _, c := range cs {
+		if us := c.GetIntervalUs(); us > 0 {
+			time.Sleep(time.Duration(us) * time.Microsecond)
+		}
+		pl, err := newPayload(args.GetResponseType(), c.GetSize())
+		if err != nil {
+			return err
+		}
+		if err := stream.Send(&testpb.StreamingOutputCallResponse{
+			Payload: pl,
+		}); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (s *testServer) StreamingInputCall(stream testpb.TestService_StreamingInputCallServer) error {
+	var sum int
+	for {
+		in, err := stream.Recv()
+		if err == io.EOF {
+			return stream.SendAndClose(&testpb.StreamingInputCallResponse{
+				AggregatedPayloadSize: proto.Int32(int32(sum)),
+			})
+		}
+		if err != nil {
+			return err
+		}
+		p := in.GetPayload().GetBody()
+		sum += len(p)
+	}
+}
+
+func (s *testServer) FullDuplexCall(stream testpb.TestService_FullDuplexCallServer) error {
+	for {
+		in, err := stream.Recv()
+		if err == io.EOF {
+			// read done.
+			return nil
+		}
+		if err != nil {
+			return err
+		}
+		cs := in.GetResponseParameters()
+		for _, c := range cs {
+			if us := c.GetIntervalUs(); us > 0 {
+				time.Sleep(time.Duration(us) * time.Microsecond)
+			}
+			pl, err := newPayload(in.GetResponseType(), c.GetSize())
+			if err != nil {
+				return err
+			}
+			if err := stream.Send(&testpb.StreamingOutputCallResponse{
+				Payload: pl,
+			}); err != nil {
+				return err
+			}
+		}
+	}
+}
+
+func (s *testServer) HalfDuplexCall(stream testpb.TestService_HalfDuplexCallServer) error {
+	msgBuf := make([]*testpb.StreamingOutputCallRequest, 0)
+	for {
+		in, err := stream.Recv()
+		if err == io.EOF {
+			// read done.
+			break
+		}
+		if err != nil {
+			return err
+		}
+		msgBuf = append(msgBuf, in)
+	}
+	for _, m := range msgBuf {
+		cs := m.GetResponseParameters()
+		for _, c := range cs {
+			if us := c.GetIntervalUs(); us > 0 {
+				time.Sleep(time.Duration(us) * time.Microsecond)
+			}
+			pl, err := newPayload(m.GetResponseType(), c.GetSize())
+			if err != nil {
+				return err
+			}
+			if err := stream.Send(&testpb.StreamingOutputCallResponse{
+				Payload: pl,
+			}); err != nil {
+				return err
+			}
+		}
+	}
+	return nil
+}
+
+func main() {
+	flag.Parse()
+	p := strconv.Itoa(*port)
+	lis, err := net.Listen("tcp", ":"+p)
+	if err != nil {
+		log.Fatalf("failed to listen: %v", err)
+	}
+	var server *rpc.Server
+	if *useTLS {
+		creds, err := credentials.NewServerTLSFromFile(*certFile, *keyFile)
+		if err != nil {
+			log.Fatalf("Failed to generate credentials %v", err)
+		}
+		server = rpc.NewServer(lis, rpc.WithServerTLS(creds))
+	} else {
+		server = rpc.NewServer(lis)
+	}
+	testpb.RegisterService(server, &testServer{})
+	server.Run()
+}
diff --git a/interop/server/testdata/ca.pem b/interop/server/testdata/ca.pem
new file mode 100644
index 00000000..999da897
--- /dev/null
+++ b/interop/server/testdata/ca.pem
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICIzCCAYwCCQCFTbF7XNSvvjANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJB
+VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
+cyBQdHkgTHRkMQ8wDQYDVQQDDAZ0ZXN0Y2EwHhcNMTQwNzE3MjMxNzUxWhcNMjQw
+NzE0MjMxNzUxWjBWMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEh
+MB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQ8wDQYDVQQDDAZ0ZXN0
+Y2EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMBA3wVeTGHZR1Rye/i+J8a2
+cu5gXwFV6TnObzGM7bLFCO5i9v4mLo4iFzPsHmWDUxKS3Y8iXbu0eYBlLoNY0lSv
+xDx33O+DuwMmVN+DzSD+Eod9zfvwOWHsazYCZT2PhNxnVWIuJXViY4JAHUGodjx+
+QAi6yCAurUZGvYXGgZSBAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAQoQVD8bwdtWJ
+AniGBwcCfqYyH+/KpA10AcebJVVTyYbYvI9Q8d6RSVu4PZy9OALHR/QrWBdYTAyz
+fNAmc2cmdkSRJzjhIaOstnQy1J+Fk0T9XyvQtq499yFbq9xogUVlEGH62xP6vH0Y
+5ukK//dCPAzA11YuX2rnex0JhuTQfcI=
+-----END CERTIFICATE-----
diff --git a/interop/server/testdata/server1.key b/interop/server/testdata/server1.key
new file mode 100644
index 00000000..ed00cd50
--- /dev/null
+++ b/interop/server/testdata/server1.key
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICWwIBAAKBgQDhwxUnKCwlSaWAwzOB2LSHVegJHv7DDWminTg4wzLLsf+LQ8nZ
+bpjfn5vgIzxCuRh4Rp9QYM5FhfrJX9wcYawP/HTbJ7p7LVQO2QYAP+akMTHxgKuM
+BzVV++3wWToKfVZUjFX8nfTfGMGwWAHJDnlEGnU4tl9UujoCV4ENJtzFoQIDAQAB
+AoGAJ+6hpzNr24yTQZtFWQpDpEyFplddKJMOxDya3S9ppK3vTWrIITV2xNcucw7I
+ceTbdyrGsyjsU0/HdCcIf9ym2jfmGLUwmyhltKVw0QYcFB0XLkc0nI5YvEYoeVDg
+omZIXn1E3EW+sSIWSbkMu9bY2kstKXR2UZmMgWDtmBEPMaECQQD6yT4TAZM5hGBb
+ciBKgMUP6PwOhPhOMPIvijO50Aiu6iuCV88l1QIy38gWVhxjNrq6P346j4IBg+kB
+9alwpCODAkEA5nSnm9k6ykYeQWNS0fNWiRinCdl23A7usDGSuKKlm019iomJ/Rgd
+MKDOp0q/2OostbteOWM2MRFf4jMH3wyVCwJAfAdjJ8szoNKTRSagSbh9vWygnB2v
+IByc6l4TTuZQJRGzCveafz9lovuB3WohCABdQRd9ukCXL2CpsEpqzkafOQJAJUjc
+USedDlq3zGZwYM1Yw8d8RuirBUFZNqJelYai+nRYClDkRVFgb5yksoYycbq5TxGo
+VeqKOvgPpj4RWPHlLwJAGUMk3bqT91xBUCnLRs/vfoCpHpg6eywQTBDAV6xkyz4a
+RH3I7/+yj3ZxR2JoWHgUwZ7lZk1VnhffFye7SBXyag==
+-----END RSA PRIVATE KEY-----
diff --git a/interop/server/testdata/server1.pem b/interop/server/testdata/server1.pem
new file mode 100644
index 00000000..8e582e57
--- /dev/null
+++ b/interop/server/testdata/server1.pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIICmzCCAgSgAwIBAgIBAzANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJBVTET
+MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ
+dHkgTHRkMQ8wDQYDVQQDDAZ0ZXN0Y2EwHhcNMTQwNzIyMDYwMDU3WhcNMjQwNzE5
+MDYwMDU3WjBkMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
+BAcTB0NoaWNhZ28xFDASBgNVBAoTC0dvb2dsZSBJbmMuMRowGAYDVQQDFBEqLnRl
+c3QuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4cMVJygs
+JUmlgMMzgdi0h1XoCR7+ww1pop04OMMyy7H/i0PJ2W6Y35+b4CM8QrkYeEafUGDO
+RYX6yV/cHGGsD/x02ye6ey1UDtkGAD/mpDEx8YCrjAc1Vfvt8Fk6Cn1WVIxV/J30
+3xjBsFgByQ55RBp1OLZfVLo6AleBDSbcxaECAwEAAaNrMGkwCQYDVR0TBAIwADAL
+BgNVHQ8EBAMCBeAwTwYDVR0RBEgwRoIQKi50ZXN0Lmdvb2dsZS5mcoIYd2F0ZXJ6
+b29pLnRlc3QuZ29vZ2xlLmJlghIqLnRlc3QueW91dHViZS5jb22HBMCoAQMwDQYJ
+KoZIhvcNAQEFBQADgYEAM2Ii0LgTGbJ1j4oqX9bxVcxm+/R5Yf8oi0aZqTJlnLYS
+wXcBykxTx181s7WyfJ49WwrYXo78zTDAnf1ma0fPq3e4mpspvyndLh1a+OarHa1e
+aT0DIIYk7qeEa1YcVljx2KyLd0r1BBAfrwyGaEPVeJQVYWaOJRU2we/KD4ojf9s=
+-----END CERTIFICATE-----
diff --git a/interop/testdata/messages.proto b/interop/testdata/messages.proto
new file mode 100644
index 00000000..626540fa
--- /dev/null
+++ b/interop/testdata/messages.proto
@@ -0,0 +1,96 @@
+// Message definitions to be used by integration test service definitions.
+
+syntax = "proto2";
+
+package grpc.testing;
+
+message Empty {}
+
+// The type of payload that should be returned.
+enum PayloadType {
+  // Compressable text format.
+  COMPRESSABLE = 0;
+
+  // Uncompressable binary format.
+  UNCOMPRESSABLE = 1;
+
+  // Randomly chosen from all other formats defined in this enum.
+  RANDOM = 2;
+}
+
+// A block of data, to simply increase gRPC message size.
+message Payload {
+  // The type of data in body.
+  optional PayloadType type = 1;
+  // Primary contents of payload.
+  optional bytes body = 2;
+}
+
+// Unary request.
+message SimpleRequest {
+  // Desired payload type in the response from the server.
+  // If response_type is RANDOM, server randomly chooses one from other formats.
+  optional PayloadType response_type = 1;
+
+  // Desired payload size in the response from the server.
+  // If response_type is COMPRESSABLE, this denotes the size before compression.
+  optional int32 response_size = 2;
+
+  // Optional input payload sent along with the request.
+  optional Payload payload = 3;
+}
+
+// Unary response, as configured by the request.
+message SimpleResponse {
+  // Payload to increase message size.
+  optional Payload payload = 1;
+  // The user the request came from, for verifying authentication was
+  // successful when the client expected it.
+  optional int64 effective_gaia_user_id = 2;
+}
+
+// Client-streaming request.
+message StreamingInputCallRequest {
+  // Optional input payload sent along with the request.
+  optional Payload payload = 1;
+
+  // Not expecting any payload from the response.
+}
+
+// Client-streaming response.
+message StreamingInputCallResponse {
+  // Aggregated size of payloads received from the client.
+  optional int32 aggregated_payload_size = 1;
+}
+
+// Configuration for a particular response.
+message ResponseParameters {
+  // Desired payload sizes in responses from the server.
+  // If response_type is COMPRESSABLE, this denotes the size before compression.
+  optional int32 size = 1;
+
+  // Desired interval between consecutive responses in the response stream in
+  // microseconds.
+  optional int32 interval_us = 2;
+}
+
+// Server-streaming request.
+message StreamingOutputCallRequest {
+  // Desired payload type in the response from the server.
+  // If response_type is RANDOM, the payload from each response in the stream
+  // might be of different types. This is to simulate a mixed type of payload
+  // stream.
+  optional PayloadType response_type = 1;
+
+  // Configuration for each expected response message.
+  repeated ResponseParameters response_parameters = 2;
+
+  // Optional input payload sent along with the request.
+  optional Payload payload = 3;
+}
+
+// Server-streaming response, as configured by the request and parameters.
+message StreamingOutputCallResponse {
+  // Payload to increase response size.
+  optional Payload payload = 1;
+}
diff --git a/interop/testdata/test.proto b/interop/testdata/test.proto
new file mode 100644
index 00000000..b1899590
--- /dev/null
+++ b/interop/testdata/test.proto
@@ -0,0 +1,42 @@
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+syntax = "proto2";
+
+import "github.com/google/grpc_go/interop/testdata/empty.proto";
+import "github.com/google/grpc_go/interop/testdata/messages.proto";
+
+package grpc.testing;
+
+// A simple service to test the various types of RPCs and experiment with
+// performance with various types of payload.
+service TestService {
+  // One empty request followed by one empty response.
+  rpc EmptyCall(grpc.testing.Empty) returns (grpc.testing.Empty);
+
+  // One request followed by one response.
+  // The server returns the client payload as-is.
+  rpc UnaryCall(SimpleRequest) returns (SimpleResponse);
+
+  // One request followed by a sequence of responses (streamed download).
+  // The server returns the payload with client desired type and sizes.
+  rpc StreamingOutputCall(StreamingOutputCallRequest)
+      returns (stream StreamingOutputCallResponse);
+
+  // A sequence of requests followed by one response (streamed upload).
+  // The server returns the aggregated size of client payload as the result.
+  rpc StreamingInputCall(stream StreamingInputCallRequest)
+      returns (StreamingInputCallResponse);
+
+  // A sequence of requests with each request served by the server immediately.
+  // As one request could lead to multiple responses, this interface
+  // demonstrates the idea of full duplexing.
+  rpc FullDuplexCall(stream StreamingOutputCallRequest)
+      returns (stream StreamingOutputCallResponse);
+
+  // A sequence of requests followed by a sequence of responses.
+  // The server buffers all the client requests and then serves them in order. A
+  // stream of responses are returned to the client when the server starts with
+  // first request.
+  rpc HalfDuplexCall(stream StreamingOutputCallRequest)
+      returns (stream StreamingOutputCallResponse);
+}
diff --git a/interop/testdata/test_proto.pb.go b/interop/testdata/test_proto.pb.go
new file mode 100755
index 00000000..a7a532dc
--- /dev/null
+++ b/interop/testdata/test_proto.pb.go
@@ -0,0 +1,402 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+// Code generated by protoc-gen-go.
+// source: net/grpc/go/interop/test.proto
+// DO NOT EDIT!
+
+/*
+Package grpc_testing is a generated protocol buffer package.
+
+It is generated from these files:
+	net/grpc/go/interop/test.proto
+
+It has these top-level messages:
+	Payload
+	SimpleRequest
+	SimpleResponse
+	SimpleContext
+	StreamingInputCallRequest
+	StreamingInputCallResponse
+	ResponseParameters
+	StreamingOutputCallRequest
+	StreamingOutputCallResponse
+*/
+package grpc_testing
+
+import proto "github.com/golang/protobuf/proto"
+import math "math"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = math.Inf
+
+type Empty struct {
+	XXX_unrecognized []byte `json:"-"`
+}
+
+func (m *Empty) Reset()                    { *m = Empty{} }
+func (m *Empty) String() string            { return proto.CompactTextString(m) }
+func (*Empty) ProtoMessage()               {}
+func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
+
+// The type of payload that should be returned.
+type PayloadType int32
+
+const (
+	// Compressable text format.
+	PayloadType_COMPRESSABLE PayloadType = 0
+	// Uncompressable binary format.
+	PayloadType_UNCOMPRESSABLE PayloadType = 1
+	// Randomly chosen from all other formats defined in this enum.
+	PayloadType_RANDOM PayloadType = 2
+)
+
+var PayloadType_name = map[int32]string{
+	0: "COMPRESSABLE",
+	1: "UNCOMPRESSABLE",
+	2: "RANDOM",
+}
+var PayloadType_value = map[string]int32{
+	"COMPRESSABLE":   0,
+	"UNCOMPRESSABLE": 1,
+	"RANDOM":         2,
+}
+
+func (x PayloadType) Enum() *PayloadType {
+	p := new(PayloadType)
+	*p = x
+	return p
+}
+func (x PayloadType) String() string {
+	return proto.EnumName(PayloadType_name, int32(x))
+}
+func (x *PayloadType) UnmarshalJSON(data []byte) error {
+	value, err := proto.UnmarshalJSONEnum(PayloadType_value, data, "PayloadType")
+	if err != nil {
+		return err
+	}
+	*x = PayloadType(value)
+	return nil
+}
+func (PayloadType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
+
+// A block of data, to simply increase gRPC message size.
+type Payload struct {
+	// The type of data in body.
+	Type *PayloadType `protobuf:"varint,1,opt,name=type,enum=grpc.testing.PayloadType" json:"type,omitempty"`
+	// Primary contents of payload.
+	Body             []byte `protobuf:"bytes,2,opt,name=body" json:"body,omitempty"`
+	XXX_unrecognized []byte `json:"-"`
+}
+
+func (m *Payload) Reset()                    { *m = Payload{} }
+func (m *Payload) String() string            { return proto.CompactTextString(m) }
+func (*Payload) ProtoMessage()               {}
+func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
+
+func (m *Payload) GetType() PayloadType {
+	if m != nil && m.Type != nil {
+		return *m.Type
+	}
+	return PayloadType_COMPRESSABLE
+}
+
+func (m *Payload) GetBody() []byte {
+	if m != nil {
+		return m.Body
+	}
+	return nil
+}
+
+// Unary request.
+type SimpleRequest struct {
+	// Desired payload type in the response from the server.
+	// If response_type is RANDOM, server randomly chooses one from other formats.
+	ResponseType *PayloadType `protobuf:"varint,1,opt,name=response_type,enum=grpc.testing.PayloadType" json:"response_type,omitempty"`
+	// Desired payload size in the response from the server.
+	// If response_type is COMPRESSABLE, this denotes the size before compression.
+	ResponseSize *int32 `protobuf:"varint,2,opt,name=response_size" json:"response_size,omitempty"`
+	// Optional input payload sent along with the request.
+	Payload          *Payload `protobuf:"bytes,3,opt,name=payload" json:"payload,omitempty"`
+	XXX_unrecognized []byte   `json:"-"`
+}
+
+func (m *SimpleRequest) Reset()                    { *m = SimpleRequest{} }
+func (m *SimpleRequest) String() string            { return proto.CompactTextString(m) }
+func (*SimpleRequest) ProtoMessage()               {}
+func (*SimpleRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
+
+func (m *SimpleRequest) GetResponseType() PayloadType {
+	if m != nil && m.ResponseType != nil {
+		return *m.ResponseType
+	}
+	return PayloadType_COMPRESSABLE
+}
+
+func (m *SimpleRequest) GetResponseSize() int32 {
+	if m != nil && m.ResponseSize != nil {
+		return *m.ResponseSize
+	}
+	return 0
+}
+
+func (m *SimpleRequest) GetPayload() *Payload {
+	if m != nil {
+		return m.Payload
+	}
+	return nil
+}
+
+// Unary response, as configured by the request.
+type SimpleResponse struct {
+	// Payload to increase message size.
+	Payload *Payload `protobuf:"bytes,1,opt,name=payload" json:"payload,omitempty"`
+	// The user the request came from, for verifying authentication was
+	// successful when the client expected it.
+	EffectiveGaiaUserId *int64 `protobuf:"varint,2,opt,name=effective_gaia_user_id" json:"effective_gaia_user_id,omitempty"`
+	XXX_unrecognized    []byte `json:"-"`
+}
+
+func (m *SimpleResponse) Reset()                    { *m = SimpleResponse{} }
+func (m *SimpleResponse) String() string            { return proto.CompactTextString(m) }
+func (*SimpleResponse) ProtoMessage()               {}
+func (*SimpleResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
+
+func (m *SimpleResponse) GetPayload() *Payload {
+	if m != nil {
+		return m.Payload
+	}
+	return nil
+}
+
+func (m *SimpleResponse) GetEffectiveGaiaUserId() int64 {
+	if m != nil && m.EffectiveGaiaUserId != nil {
+		return *m.EffectiveGaiaUserId
+	}
+	return 0
+}
+
+type SimpleContext struct {
+	Value            *string `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"`
+	XXX_unrecognized []byte  `json:"-"`
+}
+
+func (m *SimpleContext) Reset()                    { *m = SimpleContext{} }
+func (m *SimpleContext) String() string            { return proto.CompactTextString(m) }
+func (*SimpleContext) ProtoMessage()               {}
+func (*SimpleContext) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
+
+func (m *SimpleContext) GetValue() string {
+	if m != nil && m.Value != nil {
+		return *m.Value
+	}
+	return ""
+}
+
+func init() {
+}
+
+// Client-streaming request.
+type StreamingInputCallRequest struct {
+	// Optional input payload sent along with the request.
+	Payload          *Payload `protobuf:"bytes,1,opt,name=payload" json:"payload,omitempty"`
+	XXX_unrecognized []byte   `json:"-"`
+}
+
+func (m *StreamingInputCallRequest) Reset()                    { *m = StreamingInputCallRequest{} }
+func (m *StreamingInputCallRequest) String() string            { return proto.CompactTextString(m) }
+func (*StreamingInputCallRequest) ProtoMessage()               {}
+func (*StreamingInputCallRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
+
+func (m *StreamingInputCallRequest) GetPayload() *Payload {
+	if m != nil {
+		return m.Payload
+	}
+	return nil
+}
+
+// Client-streaming response.
+type StreamingInputCallResponse struct {
+	// Aggregated size of payloads received from the client.
+	AggregatedPayloadSize *int32 `protobuf:"varint,1,opt,name=aggregated_payload_size" json:"aggregated_payload_size,omitempty"`
+	XXX_unrecognized      []byte `json:"-"`
+}
+
+func (m *StreamingInputCallResponse) Reset()                    { *m = StreamingInputCallResponse{} }
+func (m *StreamingInputCallResponse) String() string            { return proto.CompactTextString(m) }
+func (*StreamingInputCallResponse) ProtoMessage()               {}
+func (*StreamingInputCallResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
+
+func (m *StreamingInputCallResponse) GetAggregatedPayloadSize() int32 {
+	if m != nil && m.AggregatedPayloadSize != nil {
+		return *m.AggregatedPayloadSize
+	}
+	return 0
+}
+
+// Configuration for a particular response.
+type ResponseParameters struct {
+	// Desired payload sizes in responses from the server.
+	// If response_type is COMPRESSABLE, this denotes the size before compression.
+	Size *int32 `protobuf:"varint,1,opt,name=size" json:"size,omitempty"`
+	// Desired interval between consecutive responses in the response stream in
+	// microseconds.
+	IntervalUs       *int32 `protobuf:"varint,2,opt,name=interval_us" json:"interval_us,omitempty"`
+	XXX_unrecognized []byte `json:"-"`
+}
+
+func (m *ResponseParameters) Reset()                    { *m = ResponseParameters{} }
+func (m *ResponseParameters) String() string            { return proto.CompactTextString(m) }
+func (*ResponseParameters) ProtoMessage()               {}
+func (*ResponseParameters) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
+
+func (m *ResponseParameters) GetSize() int32 {
+	if m != nil && m.Size != nil {
+		return *m.Size
+	}
+	return 0
+}
+
+func (m *ResponseParameters) GetIntervalUs() int32 {
+	if m != nil && m.IntervalUs != nil {
+		return *m.IntervalUs
+	}
+	return 0
+}
+
+// Server-streaming request.
+type StreamingOutputCallRequest struct {
+	// Desired payload type in the response from the server.
+	// If response_type is RANDOM, the payload from each response in the stream
+	// might be of different types. This is to simulate a mixed type of payload
+	// stream.
+	ResponseType *PayloadType `protobuf:"varint,1,opt,name=response_type,enum=grpc.testing.PayloadType" json:"response_type,omitempty"`
+	// Configuration for each expected response message.
+	ResponseParameters []*ResponseParameters `protobuf:"bytes,2,rep,name=response_parameters" json:"response_parameters,omitempty"`
+	// Optional input payload sent along with the request.
+	Payload          *Payload `protobuf:"bytes,3,opt,name=payload" json:"payload,omitempty"`
+	XXX_unrecognized []byte   `json:"-"`
+}
+
+func (m *StreamingOutputCallRequest) Reset()                    { *m = StreamingOutputCallRequest{} }
+func (m *StreamingOutputCallRequest) String() string            { return proto.CompactTextString(m) }
+func (*StreamingOutputCallRequest) ProtoMessage()               {}
+func (*StreamingOutputCallRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
+
+func (m *StreamingOutputCallRequest) GetResponseType() PayloadType {
+	if m != nil && m.ResponseType != nil {
+		return *m.ResponseType
+	}
+	return PayloadType_COMPRESSABLE
+}
+
+func (m *StreamingOutputCallRequest) GetResponseParameters() []*ResponseParameters {
+	if m != nil {
+		return m.ResponseParameters
+	}
+	return nil
+}
+
+func (m *StreamingOutputCallRequest) GetPayload() *Payload {
+	if m != nil {
+		return m.Payload
+	}
+	return nil
+}
+
+// Server-streaming response, as configured by the request and parameters.
+type StreamingOutputCallResponse struct {
+	// Payload to increase response size.
+	Payload          *Payload `protobuf:"bytes,1,opt,name=payload" json:"payload,omitempty"`
+	XXX_unrecognized []byte   `json:"-"`
+}
+
+func (m *StreamingOutputCallResponse) Reset()                    { *m = StreamingOutputCallResponse{} }
+func (m *StreamingOutputCallResponse) String() string            { return proto.CompactTextString(m) }
+func (*StreamingOutputCallResponse) ProtoMessage()               {}
+func (*StreamingOutputCallResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
+
+func (m *StreamingOutputCallResponse) GetPayload() *Payload {
+	if m != nil {
+		return m.Payload
+	}
+	return nil
+}
+
+func init() {
+	proto.RegisterEnum("grpc.testing.PayloadType", PayloadType_name, PayloadType_value)
+}
+
+var fileDescriptor0 = []byte{
+	// 628 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xbc, 0x55, 0x4d, 0x6f, 0xd3, 0x40,
+	0x10, 0xc5, 0x49, 0x3f, 0xd4, 0xc9, 0x87, 0xa2, 0xad, 0x0a, 0xa9, 0x5b, 0x95, 0xe2, 0x03, 0x4d,
+	0x38, 0xd8, 0x28, 0x17, 0x4e, 0x15, 0xb4, 0x69, 0x2a, 0x90, 0xe8, 0x87, 0x9a, 0x56, 0xea, 0xcd,
+	0xda, 0x24, 0xd3, 0x95, 0x25, 0xdb, 0x6b, 0xec, 0x75, 0xd5, 0x70, 0x42, 0xfc, 0x11, 0x38, 0xf6,
+	0x0f, 0x70, 0xe4, 0x6f, 0x71, 0x66, 0x9d, 0xb5, 0x8b, 0x13, 0x5c, 0x48, 0x0f, 0x70, 0xf4, 0xee,
+	0x9b, 0xf7, 0xde, 0xbc, 0x99, 0x4d, 0x60, 0xcb, 0x47, 0x61, 0xb1, 0x30, 0x18, 0x5a, 0x8c, 0x5b,
+	0x8e, 0x2f, 0x30, 0xe4, 0x81, 0x25, 0x30, 0x12, 0x66, 0x10, 0x72, 0xc1, 0x49, 0x35, 0xb9, 0x33,
+	0x93, 0x03, 0xc7, 0x67, 0x7a, 0x3b, 0x41, 0x4f, 0x2e, 0x3a, 0xd6, 0x20, 0x74, 0x46, 0x0c, 0xd5,
+	0x97, 0xe5, 0x61, 0x14, 0x51, 0x86, 0x76, 0x84, 0x69, 0xa1, 0xbe, 0x99, 0x83, 0x2a, 0x0c, 0x7a,
+	0x81, 0x18, 0xab, 0x5b, 0xe3, 0x0d, 0x2c, 0x9f, 0xd2, 0xb1, 0xcb, 0xe9, 0x88, 0xec, 0xc0, 0x82,
+	0x18, 0x07, 0xd8, 0xd4, 0xb6, 0xb5, 0x56, 0xbd, 0xb3, 0x6e, 0xe6, 0x05, 0xcd, 0x14, 0x74, 0x2e,
+	0x01, 0xa4, 0x0a, 0x0b, 0x03, 0x3e, 0x1a, 0x37, 0x4b, 0x12, 0x58, 0x35, 0x3e, 0x69, 0x50, 0xeb,
+	0x3b, 0x5e, 0xe0, 0xe2, 0x19, 0x7e, 0x88, 0x25, 0x9c, 0xbc, 0x84, 0x5a, 0x88, 0x51, 0xc0, 0xfd,
+	0x08, 0xed, 0xf9, 0x18, 0xd7, 0x72, 0x15, 0x91, 0xf3, 0x11, 0x27, 0xd4, 0x8b, 0xe4, 0x39, 0x2c,
+	0x07, 0x0a, 0xd5, 0x2c, 0xcb, 0x83, 0x4a, 0x67, 0xad, 0x90, 0xc2, 0xb8, 0x84, 0x7a, 0xe6, 0x40,
+	0x91, 0xe4, 0x2b, 0xb5, 0x3f, 0x54, 0x92, 0x2d, 0x78, 0x8c, 0x57, 0x57, 0x38, 0x14, 0xce, 0x35,
+	0xda, 0x8c, 0x3a, 0xd4, 0x8e, 0x23, 0x0c, 0x6d, 0x67, 0x34, 0x71, 0x50, 0x36, 0x6e, 0xb2, 0xde,
+	0xba, 0x5c, 0x8e, 0xe4, 0x46, 0x90, 0x1a, 0x2c, 0x5e, 0x53, 0x37, 0x56, 0x3d, 0xad, 0x74, 0x2e,
+	0x61, 0x2d, 0x97, 0xb8, 0x2d, 0x11, 0xe8, 0x47, 0x0e, 0xf7, 0xc9, 0xba, 0xca, 0xb7, 0x63, 0xaa,
+	0xe9, 0x98, 0x47, 0x0a, 0xd5, 0x47, 0xd1, 0xfc, 0xf2, 0xf9, 0xc7, 0xb3, 0x89, 0xa7, 0x8d, 0x69,
+	0x4f, 0x53, 0x42, 0x46, 0x17, 0xd6, 0xfb, 0x22, 0x44, 0xea, 0xc9, 0xab, 0x77, 0x7e, 0x10, 0x8b,
+	0x2e, 0x75, 0xdd, 0x2c, 0xe1, 0x39, 0xdb, 0x33, 0x76, 0x41, 0x2f, 0x22, 0x49, 0x43, 0x7a, 0x0a,
+	0x4f, 0x28, 0x63, 0x21, 0x32, 0x2a, 0x70, 0x64, 0xa7, 0x84, 0x2a, 0xff, 0x84, 0x75, 0xd1, 0x78,
+	0x05, 0x24, 0x03, 0x9f, 0xd2, 0x90, 0x7a, 0x28, 0xb7, 0x32, 0x4a, 0xc6, 0xff, 0x0b, 0x43, 0x56,
+	0xa1, 0x32, 0xd9, 0x56, 0x99, 0x8a, 0xcc, 0x4e, 0x0d, 0xce, 0xf8, 0xa6, 0xe5, 0x84, 0x4f, 0x62,
+	0x31, 0x63, 0xff, 0xe1, 0x0b, 0xb2, 0x0b, 0xab, 0x77, 0x15, 0xc1, 0x9d, 0x15, 0xa9, 0x56, 0x96,
+	0xcd, 0x6f, 0x4f, 0xd7, 0x15, 0x58, 0x9e, 0x77, 0x91, 0x7a, 0xb0, 0x51, 0x68, 0xfb, 0x61, 0x5b,
+	0xf5, 0xe2, 0x35, 0x54, 0xf2, 0xe6, 0x1b, 0x50, 0xed, 0x9e, 0x1c, 0x9d, 0x9e, 0xf5, 0xfa, 0xfd,
+	0xbd, 0xfd, 0xf7, 0xbd, 0xc6, 0x23, 0x42, 0xa0, 0x7e, 0x71, 0x3c, 0x75, 0xa6, 0x11, 0x80, 0xa5,
+	0xb3, 0xbd, 0xe3, 0x83, 0x93, 0xa3, 0x46, 0xa9, 0xf3, 0x7d, 0x01, 0x2a, 0xe7, 0x92, 0xb4, 0x2f,
+	0x73, 0x75, 0x86, 0x48, 0xda, 0xb0, 0xd2, 0x4b, 0x1e, 0x6d, 0xe2, 0x86, 0xd4, 0xb2, 0xd5, 0x9a,
+	0x1c, 0xe9, 0xd3, 0x9f, 0xe4, 0x10, 0x56, 0x2e, 0x7c, 0x1a, 0x2a, 0x68, 0xe1, 0x86, 0xa5, 0x53,
+	0xd0, 0x37, 0x8b, 0x2f, 0xd3, 0x5e, 0x39, 0xac, 0x16, 0x44, 0x41, 0x5a, 0x33, 0x45, 0xf7, 0x0e,
+	0x59, 0x6f, 0xcf, 0x81, 0x54, 0x5a, 0x46, 0xf9, 0x56, 0xd3, 0x88, 0x0b, 0xe4, 0xf7, 0x5d, 0x25,
+	0x3b, 0xf7, 0xb0, 0xcc, 0x3e, 0x09, 0xbd, 0xf5, 0x77, 0x60, 0xa6, 0xf6, 0x55, 0xaa, 0x79, 0x50,
+	0x3f, 0x8c, 0x5d, 0xf7, 0x20, 0x96, 0x3d, 0xdf, 0xfc, 0xbb, 0xce, 0x96, 0xa4, 0xd6, 0xad, 0x92,
+	0x7b, 0x4b, 0xdd, 0xab, 0xff, 0x24, 0xb7, 0x6f, 0x41, 0x7b, 0xc8, 0x3d, 0x93, 0x71, 0xce, 0x5c,
+	0x34, 0xe5, 0x1f, 0x80, 0x19, 0x89, 0x78, 0x30, 0x18, 0xdf, 0x91, 0x24, 0x4f, 0x96, 0x85, 0x54,
+	0xc8, 0x9f, 0xaa, 0x46, 0xa9, 0x55, 0xfa, 0x19, 0x00, 0x00, 0xff, 0xff, 0x0b, 0xad, 0xee, 0x7c,
+	0x7e, 0x06, 0x00, 0x00,
+}
diff --git a/interop/testdata/test_proto_grpc.pb.go b/interop/testdata/test_proto_grpc.pb.go
new file mode 100755
index 00000000..e99885d5
--- /dev/null
+++ b/interop/testdata/test_proto_grpc.pb.go
@@ -0,0 +1,378 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package grpc_testing
+
+import (
+	"fmt"
+	"github.com/google/grpc-go"
+	proto "github.com/golang/protobuf/proto"
+	context "golang.org/x/net/context"
+	"io"
+)
+
+type TestServiceClient interface {
+	EmptyCall(ctx context.Context, in *Empty, opts ...rpc.CallOption) (*Empty, error)
+	UnaryCall(ctx context.Context, in *SimpleRequest, opts ...rpc.CallOption) (*SimpleResponse, error)
+	StreamingOutputCall(ctx context.Context, m *StreamingOutputCallRequest, opts ...rpc.CallOption) (TestService_StreamingOutputCallClient, error)
+	StreamingInputCall(ctx context.Context, opts ...rpc.CallOption) (TestService_StreamingInputCallClient, error)
+	FullDuplexCall(ctx context.Context, opts ...rpc.CallOption) (TestService_FullDuplexCallClient, error)
+	HalfDuplexCall(ctx context.Context, opts ...rpc.CallOption) (TestService_HalfDuplexCallClient, error)
+}
+
+type testServiceClient struct {
+	cc *rpc.ClientConn
+}
+
+func NewTestServiceClient(cc *rpc.ClientConn) TestServiceClient {
+	return &testServiceClient{cc}
+}
+
+func (c *testServiceClient) EmptyCall(ctx context.Context, in *Empty, opts ...rpc.CallOption) (*Empty, error) {
+	out := new(Empty)
+	err := rpc.Invoke(ctx, "/grpc.testing.TestService/EmptyCall", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *testServiceClient) UnaryCall(ctx context.Context, in *SimpleRequest, opts ...rpc.CallOption) (*SimpleResponse, error) {
+	out := new(SimpleResponse)
+	err := rpc.Invoke(ctx, "/grpc.testing.TestService/UnaryCall", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *testServiceClient) StreamingOutputCall(ctx context.Context, m *StreamingOutputCallRequest, opts ...rpc.CallOption) (TestService_StreamingOutputCallClient, error) {
+	stream, err := rpc.NewClientStream(ctx, c.cc, "/grpc.testing.TestService/StreamingOutputCall", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &testServiceStreamingOutputCallClient{stream}
+	if err := x.ClientStream.SendProto(m); err != nil {
+		return nil, err
+	}
+	if err := x.ClientStream.CloseSend(); err != nil {
+		return nil, err
+	}
+	return x, nil
+}
+
+type TestService_StreamingOutputCallClient interface {
+	Recv() (*StreamingOutputCallResponse, error)
+	rpc.ClientStream
+}
+
+type testServiceStreamingOutputCallClient struct {
+	rpc.ClientStream
+}
+
+func (x *testServiceStreamingOutputCallClient) Recv() (*StreamingOutputCallResponse, error) {
+	m := new(StreamingOutputCallResponse)
+	if err := x.ClientStream.RecvProto(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func (c *testServiceClient) StreamingInputCall(ctx context.Context, opts ...rpc.CallOption) (TestService_StreamingInputCallClient, error) {
+	stream, err := rpc.NewClientStream(ctx, c.cc, "/grpc.testing.TestService/StreamingInputCall", opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &testServiceStreamingInputCallClient{stream}, nil
+}
+
+type TestService_StreamingInputCallClient interface {
+	Send(*StreamingInputCallRequest) error
+	CloseAndRecv() (*StreamingInputCallResponse, error)
+	rpc.ClientStream
+}
+
+type testServiceStreamingInputCallClient struct {
+	rpc.ClientStream
+}
+
+func (x *testServiceStreamingInputCallClient) Send(m *StreamingInputCallRequest) error {
+	return x.ClientStream.SendProto(m)
+}
+
+func (x *testServiceStreamingInputCallClient) CloseAndRecv() (*StreamingInputCallResponse, error) {
+	if err := x.ClientStream.CloseSend(); err != nil {
+		return nil, err
+	}
+	m := new(StreamingInputCallResponse)
+	if err := x.ClientStream.RecvProto(m); err != nil {
+		return nil, err
+	}
+	// Read EOF.
+	if err := x.ClientStream.RecvProto(m); err == io.EOF {
+		return m, io.EOF
+	}
+	// gRPC protocol violation.
+	return m, fmt.Errorf("Violate gRPC client streaming protocol: no EOF after the response.")
+}
+
+func (c *testServiceClient) FullDuplexCall(ctx context.Context, opts ...rpc.CallOption) (TestService_FullDuplexCallClient, error) {
+	stream, err := rpc.NewClientStream(ctx, c.cc, "/grpc.testing.TestService/FullDuplexCall", opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &testServiceFullDuplexCallClient{stream}, nil
+}
+
+type TestService_FullDuplexCallClient interface {
+	Send(*StreamingOutputCallRequest) error
+	Recv() (*StreamingOutputCallResponse, error)
+	rpc.ClientStream
+}
+
+type testServiceFullDuplexCallClient struct {
+	rpc.ClientStream
+}
+
+func (x *testServiceFullDuplexCallClient) Send(m *StreamingOutputCallRequest) error {
+	return x.ClientStream.SendProto(m)
+}
+
+func (x *testServiceFullDuplexCallClient) Recv() (*StreamingOutputCallResponse, error) {
+	m := new(StreamingOutputCallResponse)
+	if err := x.ClientStream.RecvProto(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func (c *testServiceClient) HalfDuplexCall(ctx context.Context, opts ...rpc.CallOption) (TestService_HalfDuplexCallClient, error) {
+	stream, err := rpc.NewClientStream(ctx, c.cc, "/grpc.testing.TestService/HalfDuplexCall", opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &testServiceHalfDuplexCallClient{stream}, nil
+}
+
+type TestService_HalfDuplexCallClient interface {
+	Send(*StreamingOutputCallRequest) error
+	Recv() (*StreamingOutputCallResponse, error)
+	rpc.ClientStream
+}
+
+type testServiceHalfDuplexCallClient struct {
+	rpc.ClientStream
+}
+
+func (x *testServiceHalfDuplexCallClient) Send(m *StreamingOutputCallRequest) error {
+	return x.ClientStream.SendProto(m)
+}
+
+func (x *testServiceHalfDuplexCallClient) Recv() (*StreamingOutputCallResponse, error) {
+	m := new(StreamingOutputCallResponse)
+	if err := x.ClientStream.RecvProto(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+type TestServiceServer interface {
+	EmptyCall(context.Context, *Empty) (*Empty, error)
+	UnaryCall(context.Context, *SimpleRequest) (*SimpleResponse, error)
+	StreamingOutputCall(*StreamingOutputCallRequest, TestService_StreamingOutputCallServer) error
+	StreamingInputCall(TestService_StreamingInputCallServer) error
+	FullDuplexCall(TestService_FullDuplexCallServer) error
+	HalfDuplexCall(TestService_HalfDuplexCallServer) error
+}
+
+func RegisterService(s *rpc.Server, srv TestServiceServer) {
+	s.RegisterService(&_TestService_serviceDesc, srv)
+}
+
+func _TestService_EmptyCall_Handler(srv interface{}, ctx context.Context, buf []byte) (proto.Message, error) {
+	in := new(Empty)
+	if err := proto.Unmarshal(buf, in); err != nil {
+		return nil, err
+	}
+	out, err := srv.(TestServiceServer).EmptyCall(ctx, in)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func _TestService_UnaryCall_Handler(srv interface{}, ctx context.Context, buf []byte) (proto.Message, error) {
+	in := new(SimpleRequest)
+	if err := proto.Unmarshal(buf, in); err != nil {
+		return nil, err
+	}
+	out, err := srv.(TestServiceServer).UnaryCall(ctx, in)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func _TestService_StreamingOutputCall_Handler(srv interface{}, stream rpc.ServerStream) error {
+	m := new(StreamingOutputCallRequest)
+	if err := stream.RecvProto(m); err != nil {
+		return err
+	}
+	return srv.(TestServiceServer).StreamingOutputCall(m, &testServiceStreamingOutputCallServer{stream})
+}
+
+type TestService_StreamingOutputCallServer interface {
+	Send(*StreamingOutputCallResponse) error
+	rpc.ServerStream
+}
+
+type testServiceStreamingOutputCallServer struct {
+	rpc.ServerStream
+}
+
+func (x *testServiceStreamingOutputCallServer) Send(m *StreamingOutputCallResponse) error {
+	return x.ServerStream.SendProto(m)
+}
+
+func _TestService_StreamingInputCall_Handler(srv interface{}, stream rpc.ServerStream) error {
+	return srv.(TestServiceServer).StreamingInputCall(&testServiceStreamingInputCallServer{stream})
+}
+
+type TestService_StreamingInputCallServer interface {
+	SendAndClose(*StreamingInputCallResponse) error
+	Recv() (*StreamingInputCallRequest, error)
+	rpc.ServerStream
+}
+
+type testServiceStreamingInputCallServer struct {
+	rpc.ServerStream
+}
+
+func (x *testServiceStreamingInputCallServer) SendAndClose(m *StreamingInputCallResponse) error {
+	if err := x.ServerStream.SendProto(m); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (x *testServiceStreamingInputCallServer) Recv() (*StreamingInputCallRequest, error) {
+	m := new(StreamingInputCallRequest)
+	if err := x.ServerStream.RecvProto(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func _TestService_FullDuplexCall_Handler(srv interface{}, stream rpc.ServerStream) error {
+	return srv.(TestServiceServer).FullDuplexCall(&testServiceFullDuplexCallServer{stream})
+}
+
+type TestService_FullDuplexCallServer interface {
+	Send(*StreamingOutputCallResponse) error
+	Recv() (*StreamingOutputCallRequest, error)
+	rpc.ServerStream
+}
+
+type testServiceFullDuplexCallServer struct {
+	rpc.ServerStream
+}
+
+func (x *testServiceFullDuplexCallServer) Send(m *StreamingOutputCallResponse) error {
+	return x.ServerStream.SendProto(m)
+}
+
+func (x *testServiceFullDuplexCallServer) Recv() (*StreamingOutputCallRequest, error) {
+	m := new(StreamingOutputCallRequest)
+	if err := x.ServerStream.RecvProto(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func _TestService_HalfDuplexCall_Handler(srv interface{}, stream rpc.ServerStream) error {
+	return srv.(TestServiceServer).HalfDuplexCall(&testServiceHalfDuplexCallServer{stream})
+}
+
+type TestService_HalfDuplexCallServer interface {
+	Send(*StreamingOutputCallResponse) error
+	Recv() (*StreamingOutputCallRequest, error)
+	rpc.ServerStream
+}
+
+type testServiceHalfDuplexCallServer struct {
+	rpc.ServerStream
+}
+
+func (x *testServiceHalfDuplexCallServer) Send(m *StreamingOutputCallResponse) error {
+	return x.ServerStream.SendProto(m)
+}
+
+func (x *testServiceHalfDuplexCallServer) Recv() (*StreamingOutputCallRequest, error) {
+	m := new(StreamingOutputCallRequest)
+	if err := x.ServerStream.RecvProto(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+var _TestService_serviceDesc = rpc.ServiceDesc{
+	ServiceName: "grpc.testing.TestService",
+	HandlerType: (*TestServiceServer)(nil),
+	Methods: []rpc.MethodDesc{
+		{
+			MethodName: "EmptyCall",
+			Handler:    _TestService_EmptyCall_Handler,
+		},
+		{
+			MethodName: "UnaryCall",
+			Handler:    _TestService_UnaryCall_Handler,
+		},
+	},
+	Streams: []rpc.StreamDesc{
+		{
+			StreamName: "StreamingOutputCall",
+			Handler:    _TestService_StreamingOutputCall_Handler,
+		},
+		{
+			StreamName: "StreamingInputCall",
+			Handler:    _TestService_StreamingInputCall_Handler,
+		},
+		{
+			StreamName: "FullDuplexCall",
+			Handler:    _TestService_FullDuplexCall_Handler,
+		},
+		{
+			StreamName: "HalfDuplexCall",
+			Handler:    _TestService_HalfDuplexCall_Handler,
+		},
+	},
+}
diff --git a/metadata/metadata.go b/metadata/metadata.go
new file mode 100755
index 00000000..ece53874
--- /dev/null
+++ b/metadata/metadata.go
@@ -0,0 +1,150 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+// Package metadata define the structure of the metadata supported by gRPC library.
+package metadata
+
+import (
+	"encoding/base64"
+	"fmt"
+	"strings"
+
+	"golang.org/x/net/context"
+)
+
+const (
+	binHdrSuffix = "-bin"
+)
+
+// grpc-http2 requires ASCII header key and value (more detail can be found in
+// "Requests" subsection in go/grpc-http2).
+func isASCII(s string) bool {
+	for _, c := range s {
+		if c > 127 {
+			return false
+		}
+	}
+	return true
+}
+
+// encodeKeyValue encodes key and value qualified for transmission via gRPC.
+// Transmitting binary headers violates HTTP/2 spec.
+// TODO(zhaoq): Maybe check if k is ASCII also.
+func encodeKeyValue(k, v string) (string, string) {
+	if isASCII(v) {
+		return k, v
+	}
+	key := k + binHdrSuffix
+	val := base64.StdEncoding.EncodeToString([]byte(v))
+	return key, string(val)
+}
+
+// DecodeKeyValue returns the original key and value corresponding to the
+// encoded data in k, v.
+func DecodeKeyValue(k, v string) (string, string, error) {
+	if !strings.HasSuffix(k, binHdrSuffix) {
+		return k, v, nil
+	}
+	key := k[:len(k)-len(binHdrSuffix)]
+	val, err := base64.StdEncoding.DecodeString(v)
+	if err != nil {
+		return "", "", err
+	}
+	return key, string(val), nil
+}
+
+// MD is a mapping from metadata keys to values.
+type MD struct {
+	m map[string]string
+}
+
+// New creates a MD from given key-value map.
+func New(m map[string]string) (md MD) {
+	if len(m) == 0 {
+		return
+	}
+	md.m = make(map[string]string)
+	for k, v := range m {
+		key, val := encodeKeyValue(k, v)
+		md.m[key] = val
+	}
+	return
+}
+
+// Pairs returns an MD formed by the mapping of key, value ...
+// Pairs panics if len(kv) is odd.
+func Pairs(kv ...string) (md MD) {
+	if len(kv)%2 == 1 {
+		panic(fmt.Sprintf("Got the odd number of input pairs for metadata: %d", len(kv)))
+	}
+	if len(kv) == 0 {
+		return
+	}
+	md.m = make(map[string]string)
+	var k string
+	for i, s := range kv {
+		if i%2 == 0 {
+			k = s
+			continue
+		}
+		key, val := encodeKeyValue(k, s)
+		md.m[key] = val
+	}
+	return
+}
+
+// Len returns the length of md.
+func (md MD) Len() int {
+	return len(md.m)
+}
+
+// Copy returns a copy of md's mapping.
+func (md MD) Copy() (m map[string]string) {
+	m = make(map[string]string)
+	for k, v := range md.m {
+		m[k] = v
+	}
+	return
+}
+
+type mdKey struct{}
+
+// NewContext creates a new context with md attached.
+func NewContext(ctx context.Context, md MD) context.Context {
+	return context.WithValue(ctx, mdKey{}, md)
+}
+
+// FromContext returns the MD in ctx if it exists.
+func FromContext(ctx context.Context) (md MD, ok bool) {
+	md, ok = ctx.Value(mdKey{}).(MD)
+	return
+}
diff --git a/metadata/metadata_test.go b/metadata/metadata_test.go
new file mode 100755
index 00000000..00d4dca5
--- /dev/null
+++ b/metadata/metadata_test.go
@@ -0,0 +1,81 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package metadata
+
+import (
+	"reflect"
+	"testing"
+)
+
+const binaryValue = string(128)
+
+func TestDecodeKeyValue(t *testing.T) {
+	for _, test := range []struct {
+		// input
+		kin string
+		vin string
+		// output
+		kout string
+		vout string
+		err  error
+	}{
+		{"a", "abc", "a", "abc", nil},
+		{"key-bin", "Zm9vAGJhcg==", "key", "foo\x00bar", nil},
+		{"key-bin", "woA=", "key", binaryValue, nil},
+	} {
+		k, v, err := DecodeKeyValue(test.kin, test.vin)
+		if k != test.kout || !reflect.DeepEqual(v, test.vout) || !reflect.DeepEqual(err, test.err) {
+			t.Fatalf("DecodeKeyValue(%q, %q) = %q, %q, %v, want %q, %q, %v", test.kin, test.vin, k, v, err, test.kout, test.vout, test.err)
+		}
+	}
+}
+
+func TestPairsMD(t *testing.T) {
+	for _, test := range []struct {
+		// input
+		kv []string
+		// output
+		md MD
+	}{
+		{[]string{}, MD{}},
+		{[]string{"k1", "v1", "k2", binaryValue}, New(map[string]string{
+			"k1":     "v1",
+			"k2-bin": "woA=",
+		})},
+	} {
+		md := Pairs(test.kv...)
+		if !reflect.DeepEqual(md, test.md) {
+			t.Fatalf("Pairs(%v) = %v, want %v", test.kv, md, test.md)
+		}
+	}
+}
diff --git a/rpc_util.go b/rpc_util.go
new file mode 100755
index 00000000..9b7449f6
--- /dev/null
+++ b/rpc_util.go
@@ -0,0 +1,281 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package rpc
+
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"io"
+	"math/rand"
+	"os"
+	"time"
+
+	"github.com/google/grpc-go/codes"
+	"github.com/google/grpc-go/metadata"
+	"github.com/google/grpc-go/transport"
+	"github.com/golang/protobuf/proto"
+	"golang.org/x/net/context"
+)
+
+// CallOption configures a Call before it starts or extracts information from
+// a Call after it completes.
+type CallOption interface {
+	// before is called before the call is sent to any server.  If before
+	// returns a non-nil error, the RPC fails with that error.
+	before(*callInfo) error
+
+	// after is called after the call has completed.  after cannot return an
+	// error, so any failures should be reported via output parameters.
+	after(*callInfo)
+}
+
+type beforeCall func(c *callInfo) error
+
+func (o beforeCall) before(c *callInfo) error { return o(c) }
+func (o beforeCall) after(c *callInfo)        {}
+
+type afterCall func(c *callInfo)
+
+func (o afterCall) before(c *callInfo) error { return nil }
+func (o afterCall) after(c *callInfo)        { o(c) }
+
+// Header returns a CallOptions that retrieves the header metadata
+// for a unary RPC.
+func Header(md *metadata.MD) CallOption {
+	return afterCall(func(c *callInfo) {
+		*md = c.headerMD
+	})
+}
+
+// Trailer returns a CallOptions that retrieves the trailer metadata
+// for a unary RPC.
+func Trailer(md *metadata.MD) CallOption {
+	return afterCall(func(c *callInfo) {
+		*md = c.trailerMD
+	})
+}
+
+// The format of the payload: compressed or not?
+type payloadFormat uint8
+
+const (
+	compressionNone payloadFormat = iota // no compression
+	compressionFlate
+	// More formats
+)
+
+// parser reads complelete gRPC messages from the underlying reader.
+type parser struct {
+	s io.Reader
+}
+
+// msgFixedHeader defines the header of a gRPC message (go/grpc-wirefmt).
+type msgFixedHeader struct {
+	T      payloadFormat
+	Length uint32
+}
+
+// recvMsg is to read a complete gRPC message from the stream. It is blocking if
+// the message has not been complete yet. It returns the message and its type,
+// EOF is returned with nil msg and 0 pf if the entire stream is done. Other
+// non-nil error is returned if something is wrong on reading.
+func (p *parser) recvMsg() (pf payloadFormat, msg []byte, err error) {
+	var hdr msgFixedHeader
+	if err := binary.Read(p.s, binary.BigEndian, &hdr); err != nil {
+		return 0, nil, err
+	}
+	if hdr.Length == 0 {
+		return hdr.T, nil, nil
+	}
+	msg = make([]byte, int(hdr.Length))
+	if _, err := io.ReadFull(p.s, msg); err != nil {
+		if err == io.EOF {
+			err = io.ErrUnexpectedEOF
+		}
+		return 0, nil, err
+	}
+	return hdr.T, msg, nil
+}
+
+// encode serializes msg and prepends the message header. If msg is nil, it
+// generates the message header of 0 message length.
+func encode(msg proto.Message, pf payloadFormat) ([]byte, error) {
+	var buf bytes.Buffer
+	// Write message fixed header.
+	if err := buf.WriteByte(uint8(pf)); err != nil {
+		return nil, err
+	}
+	var b []byte
+	var length uint32
+	if msg != nil {
+		var err error
+		// TODO(zhaoq): optimize to reduce memory alloc and copying.
+		b, err = proto.Marshal(msg)
+		if err != nil {
+			return nil, err
+		}
+		length = uint32(len(b))
+	}
+	if err := binary.Write(&buf, binary.BigEndian, length); err != nil {
+		return nil, err
+	}
+	if _, err := buf.Write(b); err != nil {
+		return nil, err
+	}
+	return buf.Bytes(), nil
+}
+
+func recvProto(p *parser, m proto.Message) error {
+	pf, d, err := p.recvMsg()
+	if err != nil {
+		return err
+	}
+	switch pf {
+	case compressionNone:
+		if err := proto.Unmarshal(d, m); err != nil {
+			return Errorf(codes.Internal, "%v", err)
+		}
+	default:
+		return Errorf(codes.Internal, "compression is not supported yet.")
+	}
+	return nil
+}
+
+// rpcError defines the status from an RPC.
+type rpcError struct {
+	code codes.Code
+	desc string
+}
+
+func (e rpcError) Error() string {
+	return fmt.Sprintf("rpc error: code = %d desc = %q", e.code, e.desc)
+}
+
+// Code returns the error code for err if it was produced by the rpc system.
+// Otherwise, it returns codes.Unknown.
+func Code(err error) codes.Code {
+	if e, ok := err.(rpcError); ok {
+		return e.code
+	}
+	return codes.Unknown
+}
+
+// Errorf returns an error containing an error code and a description;
+// CodeOf extracts the Code.
+// Errorf returns nil if c is OK.
+func Errorf(c codes.Code, format string, a ...interface{}) error {
+	if c == codes.OK {
+		return nil
+	}
+	return rpcError{
+		code: c,
+		desc: fmt.Sprintf(format, a...),
+	}
+}
+
+// toRPCErr converts a transport error into a rpcError if possible.
+func toRPCErr(err error) error {
+	switch e := err.(type) {
+	case transport.StreamError:
+		return rpcError{
+			code: e.Code,
+			desc: e.Desc,
+		}
+	case transport.ConnectionError:
+		return rpcError{
+			code: codes.Internal,
+			desc: e.Desc,
+		}
+	}
+	return Errorf(codes.Unknown, "failed to convert %v to rpcErr", err)
+}
+
+// convertCode converts a standard Go error into its canonical code. Note that
+// this is only used to translate the error returned by the server applications.
+func convertCode(err error) codes.Code {
+	switch err {
+	case nil:
+		return codes.OK
+	case io.EOF:
+		return codes.OutOfRange
+	case io.ErrClosedPipe, io.ErrNoProgress, io.ErrShortBuffer, io.ErrShortWrite, io.ErrUnexpectedEOF:
+		return codes.FailedPrecondition
+	case os.ErrInvalid:
+		return codes.InvalidArgument
+	case context.Canceled:
+		return codes.Canceled
+	case context.DeadlineExceeded:
+		return codes.DeadlineExceeded
+	}
+	switch {
+	case os.IsExist(err):
+		return codes.AlreadyExists
+	case os.IsNotExist(err):
+		return codes.NotFound
+	case os.IsPermission(err):
+		return codes.PermissionDenied
+	}
+	return codes.Unknown
+}
+
+const (
+	// how long to wait after the first failure before retrying
+	baseDelay = 1.0 * time.Second
+	// upper bound on backoff delay
+	maxDelay      = 120 * time.Second
+	backoffFactor = 2.0 // backoff increases by this factor on each retry
+	backoffRange  = 0.4 // backoff is randomized downwards by this factor
+)
+
+// backoff returns a value in [0, maxDelay] that increases exponentially with
+// retries, starting from baseDelay.
+func backoff(retries int) time.Duration {
+	backoff, max := float64(baseDelay), float64(maxDelay)
+	for backoff < max && retries > 0 {
+		backoff = backoff * backoffFactor
+		retries--
+	}
+	if backoff > max {
+		backoff = max
+	}
+
+	// Randomize backoff delays so that if a cluster of requests start at
+	// the same time, they won't operate in lockstep.  We just subtract up
+	// to 40% so that we obey maxDelay.
+	backoff -= backoff * backoffRange * rand.Float64()
+	if backoff < 0 {
+		return 0
+	}
+	return time.Duration(backoff)
+}
diff --git a/rpc_util_test.go b/rpc_util_test.go
new file mode 100755
index 00000000..62dc2e1f
--- /dev/null
+++ b/rpc_util_test.go
@@ -0,0 +1,171 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package rpc
+
+import (
+	"bytes"
+	"io"
+	"math"
+	"reflect"
+	"testing"
+	"time"
+
+	"github.com/google/grpc-go/codes"
+	"github.com/google/grpc-go/transport"
+	"github.com/golang/protobuf/proto"
+	"golang.org/x/net/context"
+)
+
+func TestSimpleParsing(t *testing.T) {
+	for _, test := range []struct {
+		// input
+		p []byte
+		// outputs
+		err error
+		b   []byte
+		pt  payloadFormat
+	}{
+		{nil, io.EOF, nil, compressionNone},
+		{[]byte{0, 0, 0, 0, 0}, nil, nil, compressionNone},
+		{[]byte{0, 0, 0, 0, 1, 'a'}, nil, []byte{'a'}, compressionNone},
+		{[]byte{1, 0}, io.ErrUnexpectedEOF, nil, compressionNone},
+		{[]byte{0, 0, 0, 0, 10, 'a'}, io.ErrUnexpectedEOF, nil, compressionNone},
+	} {
+		buf := bytes.NewReader(test.p)
+		parser := &parser{buf}
+		pt, b, err := parser.recvMsg()
+		if err != test.err || !bytes.Equal(b, test.b) || pt != test.pt {
+			t.Fatalf("parser{%v}.recvMsg() = %v, %v, %v\nwant %v, %v, %v", test.p, pt, b, err, test.pt, test.b, test.err)
+		}
+	}
+}
+
+func TestMultipleParsing(t *testing.T) {
+	// Set a byte stream consists of 3 messages with their headers.
+	p := []byte{0, 0, 0, 0, 1, 'a', 0, 0, 0, 0, 2, 'b', 'c', 0, 0, 0, 0, 1, 'd'}
+	b := bytes.NewReader(p)
+	parser := &parser{b}
+
+	wantRecvs := []struct {
+		pt   payloadFormat
+		data []byte
+	}{
+		{compressionNone, []byte("a")},
+		{compressionNone, []byte("bc")},
+		{compressionNone, []byte("d")},
+	}
+	for i, want := range wantRecvs {
+		pt, data, err := parser.recvMsg()
+		if err != nil || pt != want.pt || !reflect.DeepEqual(data, want.data) {
+			t.Fatalf("after %d calls, parser{%v}.recvMsg() = %v, %v, %v\nwant %v, %v, <nil>",
+				i, p, pt, data, err, want.pt, want.data)
+		}
+	}
+
+	pt, data, err := parser.recvMsg()
+	if err != io.EOF {
+		t.Fatalf("after %d recvMsgs calls, parser{%v}.recvMsg() = %v, %v, %v\nwant _, _, %v",
+			len(wantRecvs), p, pt, data, err, io.EOF)
+	}
+}
+
+func TestEncode(t *testing.T) {
+	for _, test := range []struct {
+		// input
+		msg proto.Message
+		pt  payloadFormat
+		// outputs
+		b   []byte
+		err error
+	}{
+		{nil, compressionNone, []byte{0, 0, 0, 0, 0}, nil},
+	} {
+		b, err := encode(test.msg, test.pt)
+		if err != test.err || !bytes.Equal(b, test.b) {
+			t.Fatalf("encode(_, %d) = %v, %v\nwant %v, %v", test.pt, b, err, test.b, test.err)
+		}
+	}
+}
+
+func TestToRPCErr(t *testing.T) {
+	for _, test := range []struct {
+		// input
+		errIn error
+		// outputs
+		errOut error
+	}{
+		{transport.StreamErrorf(codes.Unknown, ""), Errorf(codes.Unknown, "")},
+		{transport.ErrConnClosing, Errorf(codes.Internal, transport.ErrConnClosing.Desc)},
+	} {
+		err := toRPCErr(test.errIn)
+		if err != test.errOut {
+			t.Fatalf("toRPCErr{%v} = %v \nwant %v", test.errIn, err, test.errOut)
+		}
+	}
+}
+
+func TestContextErr(t *testing.T) {
+	for _, test := range []struct {
+		// input
+		errIn error
+		// outputs
+		errOut transport.StreamError
+	}{
+		{context.DeadlineExceeded, transport.StreamErrorf(codes.DeadlineExceeded, "%v", context.DeadlineExceeded)},
+		{context.Canceled, transport.StreamErrorf(codes.Canceled, "%v", context.Canceled)},
+	} {
+		err := transport.ContextErr(test.errIn)
+		if err != test.errOut {
+			t.Fatalf("ContextErr{%v} = %v \nwant %v", test.errIn, err, test.errOut)
+		}
+	}
+}
+
+func TestBackoff(t *testing.T) {
+	for _, test := range []struct {
+		retries   int
+		maxResult time.Duration
+	}{
+		{0, time.Second},
+		{1, time.Duration(1e9 * math.Pow(backoffFactor, 1))},
+		{2, time.Duration(1e9 * math.Pow(backoffFactor, 2))},
+		{3, time.Duration(1e9 * math.Pow(backoffFactor, 3))},
+		{4, time.Duration(1e9 * math.Pow(backoffFactor, 4))},
+		{int(math.Log2(float64(maxDelay)/float64(baseDelay))) + 1, maxDelay},
+	} {
+		delay := backoff(test.retries)
+		if delay < 0 || delay > test.maxResult {
+			t.Errorf("backoff(%d) = %v outside [0, %v]", test.retries, delay, test.maxResult)
+		}
+	}
+}
diff --git a/server.go b/server.go
new file mode 100755
index 00000000..ecf91d5d
--- /dev/null
+++ b/server.go
@@ -0,0 +1,364 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package rpc
+
+import (
+	"fmt"
+	"io"
+	"log"
+	"net"
+	"reflect"
+	"strings"
+	"sync"
+
+	"github.com/google/grpc-go/codes"
+	"github.com/google/grpc-go/credentials"
+	"github.com/google/grpc-go/metadata"
+	"github.com/google/grpc-go/transport"
+	"github.com/golang/protobuf/proto"
+	"golang.org/x/net/context"
+)
+
+type methodHandler func(srv interface{}, ctx context.Context, buf []byte) (proto.Message, error)
+
+// MethodDesc represents an RPC service's method specification.
+type MethodDesc struct {
+	MethodName string
+	Handler    methodHandler
+}
+
+type streamHandler func(srv interface{}, stream ServerStream) error
+
+// StreamDesc represents a streaming RPC service's method specification.
+type StreamDesc struct {
+	StreamName string
+	Handler    streamHandler
+}
+
+// ServiceDesc represents an RPC service's specification.
+type ServiceDesc struct {
+	ServiceName string
+	// The pointer to the service interface. Used to check whether the user
+	// provided implementation satisfies the interface requirements.
+	HandlerType interface{}
+	Methods     []MethodDesc
+	Streams     []StreamDesc
+}
+
+// service consists of the information of the server serving this service and
+// the methods in this service.
+type service struct {
+	server interface{} // the server for service methods
+	md     map[string]*MethodDesc
+	sd     map[string]*StreamDesc
+}
+
+// Server is a gRPC server to serve RPC requests.
+type Server struct {
+	lis   net.Listener
+	opts  options
+	mu    sync.Mutex
+	conns map[transport.ServerTransport]bool
+	m     map[string]*service // service name -> service info
+}
+
+type options struct {
+	maxConcurrentStreams uint32
+	connCreds            credentials.TransportAuthenticator
+}
+
+// ServerOption sets options.
+type ServerOption func(*options)
+
+// MaxConcurrentStreams returns an Option that will apply a limit on the number
+// of concurrent streams to each ServerTransport.
+func MaxConcurrentStreams(n uint32) ServerOption {
+	return func(o *options) {
+		o.maxConcurrentStreams = n
+	}
+}
+
+// WithServerTLS returns an Option that consists of the input TLSCredentials.
+func WithServerTLS(creds credentials.TransportAuthenticator) ServerOption {
+	return func(o *options) {
+		o.connCreds = creds
+	}
+}
+
+// NewServer creates a gRPC server which has no service registered and has not
+// started to accept requests yet.
+func NewServer(lis net.Listener, opt ...ServerOption) *Server {
+	var opts options
+	for _, o := range opt {
+		o(&opts)
+	}
+	if opts.connCreds != nil {
+		lis = opts.connCreds.NewListener(lis)
+	}
+	return &Server{
+		lis:   lis,
+		opts:  opts,
+		conns: make(map[transport.ServerTransport]bool),
+		m:     make(map[string]*service),
+	}
+}
+
+// RegisterService register a service and its implementation to the gRPC
+// server. Called from the IDL generated code.
+func (s *Server) RegisterService(sd *ServiceDesc, ss interface{}) {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	// Does some sanity checks.
+	if _, ok := s.m[sd.ServiceName]; ok {
+		log.Fatalf("rpc: Duplicate service registration for %q", sd.ServiceName)
+	}
+	ht := reflect.TypeOf(sd.HandlerType).Elem()
+	st := reflect.TypeOf(ss)
+	if !st.Implements(ht) {
+		log.Fatalf("rpc: The handler of type %v that does not satisfy %v", st, ht)
+	}
+	srv := &service{
+		server: ss,
+		md:     make(map[string]*MethodDesc),
+		sd:     make(map[string]*StreamDesc),
+	}
+	for i := range sd.Methods {
+		d := &sd.Methods[i]
+		srv.md[d.MethodName] = d
+	}
+	for i := range sd.Streams {
+		d := &sd.Streams[i]
+		srv.sd[d.StreamName] = d
+	}
+	s.m[sd.ServiceName] = srv
+}
+
+// Run makes the server start to accept connections on s.lis. Upon each received
+// connection request, it creates a ServerTransport and starts receiving gRPC
+// requests from it. Non-nil error returns if something goes wrong.
+func (s *Server) Run() error {
+	for {
+		c, err := s.lis.Accept()
+		if err != nil {
+			return err
+		}
+
+		s.mu.Lock()
+		if s.conns == nil {
+			s.mu.Unlock()
+			c.Close()
+			return nil
+		}
+		st, err := transport.NewServerTransport("http2", c, s.opts.maxConcurrentStreams)
+		if err != nil {
+			s.mu.Unlock()
+			c.Close()
+			log.Println("failed to create ServerTransport: ", err)
+			continue
+		}
+		s.conns[st] = true
+		s.mu.Unlock()
+
+		go func() {
+			st.HandleStreams(func(stream *transport.Stream) {
+				s.handleStream(st, stream)
+			})
+			s.mu.Lock()
+			delete(s.conns, st)
+			s.mu.Unlock()
+		}()
+	}
+}
+
+func (s *Server) sendProto(t transport.ServerTransport, stream *transport.Stream, msg proto.Message, pf payloadFormat, opts *transport.Options) error {
+	p, err := encode(msg, pf)
+	if err != nil {
+		// This typically indicates a fatal issue (e.g., memory
+		// corruption or hardware faults) the application program
+		// cannot handle.
+		//
+		// TODO(zhaoq): There exist other options also such as only closing the
+		// faulty stream locally and remotely (Other streams can keep going). Find
+		// the optimal option.
+		log.Fatalf("Server: failed to encode proto message %v", err)
+	}
+	return t.Write(stream, p, opts)
+}
+
+func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.Stream, srv *service, md *MethodDesc) {
+	p := &parser{s: stream}
+	for {
+		pf, req, err := p.recvMsg()
+		if err == io.EOF {
+			// The entire stream is done (for unary rpc only).
+			return
+		}
+		if err != nil {
+			switch err := err.(type) {
+			case transport.ConnectionError:
+				// Nothing to do here.
+			case transport.StreamError:
+				t.WriteStatus(stream, err.Code, err.Desc)
+			default:
+				panic(fmt.Sprintf("BUG: Unexpected error (%T) from recvMsg: %v", err, err))
+			}
+			return
+		}
+		switch pf {
+		case compressionNone:
+			reply, appErr := md.Handler(srv.server, stream.Context(), req)
+			if appErr != nil {
+				t.WriteStatus(stream, convertCode(appErr), appErr.Error())
+				return
+			}
+			opts := &transport.Options{
+				Last:  true,
+				Delay: false,
+			}
+			statusCode := codes.OK
+			statusDesc := ""
+			if err := s.sendProto(t, stream, reply, compressionNone, opts); err != nil {
+				if _, ok := err.(transport.ConnectionError); ok {
+					return
+				}
+				if e, ok := err.(transport.StreamError); ok {
+					statusCode = e.Code
+					statusDesc = e.Desc
+				} else {
+					statusCode = codes.Unknown
+					statusDesc = err.Error()
+				}
+			}
+			t.WriteStatus(stream, statusCode, statusDesc)
+		default:
+			panic(fmt.Sprintf("payload format to be supported: %d", pf))
+		}
+	}
+}
+
+func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transport.Stream, srv *service, sd *StreamDesc) {
+	ss := &serverStream{
+		t: t,
+		s: stream,
+		p: &parser{s: stream},
+	}
+	if err := sd.Handler(srv.server, ss); err != nil {
+		ss.statusCode = convertCode(err)
+		ss.statusDesc = err.Error()
+	}
+	t.WriteStatus(ss.s, ss.statusCode, ss.statusDesc)
+}
+
+func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Stream) {
+	sm := stream.Method()
+	if sm != "" && sm[0] == '/' {
+		sm = sm[1:]
+	}
+	pos := strings.LastIndex(sm, "/")
+	if pos == -1 {
+		t.WriteStatus(stream, codes.InvalidArgument, fmt.Sprintf("malformed method name: %q", stream.Method()))
+		return
+	}
+	service := sm[:pos]
+	method := sm[pos+1:]
+	srv, ok := s.m[service]
+	if !ok {
+		t.WriteStatus(stream, codes.Unimplemented, fmt.Sprintf("unknown service %v", service))
+		return
+	}
+	// Unary RPC or Streaming RPC?
+	if md, ok := srv.md[method]; ok {
+		s.processUnaryRPC(t, stream, srv, md)
+		return
+	}
+	if sd, ok := srv.sd[method]; ok {
+		s.processStreamingRPC(t, stream, srv, sd)
+		return
+	}
+	t.WriteStatus(stream, codes.Unimplemented, fmt.Sprintf("unknown method %v", method))
+}
+
+// Stop stops the gRPC server. Once it returns, the server stops accepting
+// connection requests and closes all the connected connections.
+func (s *Server) Stop() {
+	s.lis.Close()
+	s.mu.Lock()
+	cs := s.conns
+	s.conns = nil
+	s.mu.Unlock()
+	for c := range cs {
+		c.Close()
+	}
+}
+
+// CloseConns closes all exiting transports but keeps s.lis accepting new
+// connections. This is for test only now.
+func (s *Server) CloseConns() {
+	s.mu.Lock()
+	for c := range s.conns {
+		c.Close()
+		delete(s.conns, c)
+	}
+	s.mu.Unlock()
+}
+
+// SendHeader sends header metadata. It may be called at most once from a unary
+// RPC handler. The ctx is the RPC handler's Context or one derived from it.
+func SendHeader(ctx context.Context, md metadata.MD) error {
+	if md.Len() == 0 {
+		return nil
+	}
+	stream, ok := transport.StreamFromContext(ctx)
+	if !ok {
+		return fmt.Errorf("rpc: failed to fetch the stream from the context %v", ctx)
+	}
+	t := stream.ServerTransport()
+	if t == nil {
+		log.Fatalf("rpc.SendHeader: %v has no ServerTransport to send header metadata.", stream)
+	}
+	return t.WriteHeader(stream, md)
+}
+
+// SetTrailer sets the trailer metadata that will be sent when an RPC returns.
+// It may be called at most once from a unary RPC handler. The ctx is the RPC
+// handler's Context or one derived from it.
+func SetTrailer(ctx context.Context, md metadata.MD) error {
+	if md.Len() == 0 {
+		return nil
+	}
+	stream, ok := transport.StreamFromContext(ctx)
+	if !ok {
+		return fmt.Errorf("rpc: failed to fetch the stream from the context %v", ctx)
+	}
+	return stream.SetTrailer(md)
+}
diff --git a/stream.go b/stream.go
new file mode 100755
index 00000000..db05bf57
--- /dev/null
+++ b/stream.go
@@ -0,0 +1,240 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package rpc
+
+import (
+	"io"
+
+	"github.com/google/grpc-go/codes"
+	"github.com/google/grpc-go/metadata"
+	"github.com/google/grpc-go/transport"
+	"github.com/golang/protobuf/proto"
+	"golang.org/x/net/context"
+)
+
+// Stream defines the common interface a client or server stream has to satisfy.
+type Stream interface {
+	// Context returns the context for this stream.
+	Context() context.Context
+	// SendProto blocks until it sends a proto message out or some
+	// error happens.
+	SendProto(proto.Message) error
+	// RecvProto blocks until either a proto message is received or some
+	// error happens.
+	RecvProto(proto.Message) error
+}
+
+// ClientStream defines the interface a client stream has to satify.
+type ClientStream interface {
+	// Header returns the header metedata received from the server if there
+	// is any. It blocks if the metadata is not ready to read.
+	Header() (metadata.MD, error)
+	// Trailer returns the trailer metadata from the server. It must be called
+	// after stream.Recv() returns non-nil error (including io.EOF) for
+	// bi-directional streaming and server streaming or stream.CloseAndRecv()
+	// returns for client streaming in order to receive trailer metadata if
+	// present.
+	Trailer() metadata.MD
+	// CloseSend closes the send direction of the stream.
+	CloseSend() error
+	Stream
+}
+
+// NewClientStream creates a new Stream for the client side. This is called
+// by generated code.
+func NewClientStream(ctx context.Context, cc *ClientConn, method string, opts ...CallOption) (ClientStream, error) {
+	// TODO(zhaoq): CallOption is omitted. Add support when it is needed.
+	callHdr := &transport.CallHdr{
+		Host:   cc.target,
+		Method: method,
+	}
+	t, _, err := cc.wait(ctx, 0)
+	if err != nil {
+		return nil, toRPCErr(err)
+	}
+	s, err := t.NewStream(ctx, callHdr)
+	if err != nil {
+		return nil, toRPCErr(err)
+	}
+	return &clientStream{
+		t: t,
+		s: s,
+		p: &parser{s: s},
+	}, nil
+}
+
+// clientStream implements a client side Stream.
+type clientStream struct {
+	t transport.ClientTransport
+	s *transport.Stream
+	p *parser
+}
+
+// Context returns the clientStream's associated context.
+func (cs *clientStream) Context() context.Context {
+	return cs.s.Context()
+}
+
+// Header returns the header metedata received from the server if there
+// is any. Empty metadata.MD is returned if there is no header metadata.
+// It blocks if the metadata is not ready to read.
+func (cs *clientStream) Header() (md metadata.MD, err error) {
+	m, err := cs.s.Header()
+	if err != nil {
+		return md, err
+	}
+	return metadata.New(m), nil
+}
+
+// Trailer returns the trailer metadata from the server. It must be called
+// after stream.Recv() returns non-nil error (including io.EOF) for
+// bi-directional streaming and server streaming or stream.CloseAndRecv()
+// returns for client streaming in order to receive trailer metadata if
+// present.
+func (cs *clientStream) Trailer() metadata.MD {
+	return cs.s.Trailer()
+}
+
+// SendProto blocks until m is sent out or an error happens. It closes the
+// stream when a non-nil error is met. This is called by generated code.
+func (cs *clientStream) SendProto(m proto.Message) (err error) {
+	defer func() {
+		if err == nil || err == io.EOF {
+			return
+		}
+		if _, ok := err.(transport.ConnectionError); !ok {
+			cs.t.CloseStream(cs.s, err)
+		}
+		err = toRPCErr(err)
+	}()
+	out, err := encode(m, compressionNone)
+	if err != nil {
+		return transport.StreamErrorf(codes.Internal, "%v", err)
+	}
+	return cs.t.Write(cs.s, out, &transport.Options{Last: false})
+}
+
+// RecvProto blocks until it receives a proto message or an error happens.
+// When an non-nil error (including EOF which indicates the success of an
+// RPC) is met, it also closes the stream and returns the RPC status to
+// the caller. This is called by generated code.
+func (cs *clientStream) RecvProto(m proto.Message) (err error) {
+	err = recvProto(cs.p, m)
+	if err == nil {
+		return
+	}
+	if err == io.EOF {
+		if cs.s.StatusCode() == codes.OK {
+			// Returns io.EOF to indicate the end of the stream.
+			return
+		}
+		return Errorf(cs.s.StatusCode(), cs.s.StatusDesc())
+	}
+	if _, ok := err.(transport.ConnectionError); !ok {
+		cs.t.CloseStream(cs.s, err)
+	}
+	return toRPCErr(err)
+}
+
+// CloseSend closes the send direction of the stream. It closes the stream
+// when non-nil error is met.
+func (cs *clientStream) CloseSend() (err error) {
+	err = cs.t.Write(cs.s, nil, &transport.Options{Last: true})
+	if err == nil || err == io.EOF {
+		return
+	}
+	if _, ok := err.(transport.ConnectionError); !ok {
+		cs.t.CloseStream(cs.s, err)
+	}
+	err = toRPCErr(err)
+	return
+}
+
+// ServerStream defines the interface a server stream has to satisfy.
+type ServerStream interface {
+	// SendHeader sends the header metadata. It should not be called
+	// after SendProto.
+	SendHeader(metadata.MD) error
+	// SetTrailer sets the trailer metadata which will be sent with the
+	// RPC status.
+	SetTrailer(metadata.MD)
+	Stream
+}
+
+// serverStream implements a server side Stream.
+type serverStream struct {
+	t          transport.ServerTransport
+	s          *transport.Stream
+	p          *parser
+	statusCode codes.Code
+	statusDesc string
+}
+
+// Context returns the associated context so that server applications can
+// manipulate it.
+func (ss *serverStream) Context() context.Context {
+	return ss.s.Context()
+}
+
+// SendHeader sends header metadata. It fails if called multiple times or if
+// called after SendProto.
+func (ss *serverStream) SendHeader(md metadata.MD) error {
+	return ss.t.WriteHeader(ss.s, md)
+}
+
+// SetTrailer sends trailer metadata. The metadata will be sent with the final
+// RPC status.
+func (ss *serverStream) SetTrailer(md metadata.MD) {
+	if md.Len() == 0 {
+		return
+	}
+	ss.s.SetTrailer(md)
+	return
+}
+
+// SendProto blocks until m is sent out or an error is met. This is called by
+// generated code.
+func (ss *serverStream) SendProto(m proto.Message) error {
+	out, err := encode(m, compressionNone)
+	if err != nil {
+		err = transport.StreamErrorf(codes.Internal, "%v", err)
+		return err
+	}
+	return ss.t.Write(ss.s, out, &transport.Options{Last: false})
+}
+
+// RecvProto blocks until it receives a message or an error is met. This is
+// called by generated code.
+func (ss *serverStream) RecvProto(m proto.Message) error {
+	return recvProto(ss.p, m)
+}
diff --git a/test/end2end_test.go b/test/end2end_test.go
new file mode 100755
index 00000000..33441290
--- /dev/null
+++ b/test/end2end_test.go
@@ -0,0 +1,462 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package grpc_test
+
+import (
+	"fmt"
+	"io"
+	"log"
+	"math"
+	"net"
+	"reflect"
+	"strconv"
+	"strings"
+	"sync"
+	"testing"
+	"time"
+
+	"github.com/google/grpc-go/codes"
+	"github.com/google/grpc-go/credentials"
+	"github.com/google/grpc-go/metadata"
+	"github.com/google/grpc-go"
+	testpb "github.com/google/grpc-go/test/testdata"
+	"github.com/golang/protobuf/proto"
+	"golang.org/x/net/context"
+)
+
+var (
+	testMetadata = map[string]string{
+		"key1": "value1",
+		"key2": "value2",
+	}
+)
+
+type mathServer struct {
+}
+
+func (s *mathServer) Div(ctx context.Context, in *testpb.DivArgs) (*testpb.DivReply, error) {
+	md, ok := metadata.FromContext(ctx)
+	if ok {
+		if err := rpc.SendHeader(ctx, md); err != nil {
+			log.Fatalf("rpc.SendHeader(%v, %v) = %v, want %v", ctx, md, err, nil)
+		}
+		rpc.SetTrailer(ctx, md)
+	}
+	n, d := in.GetDividend(), in.GetDivisor()
+	if d == 0 {
+		return nil, fmt.Errorf("math: divide by 0")
+	}
+	out := new(testpb.DivReply)
+	out.Quotient = proto.Int64(n / d)
+	out.Remainder = proto.Int64(n % d)
+	// Simulate some service delay.
+	time.Sleep(2 * time.Millisecond)
+	return out, nil // no error
+}
+
+func (s *mathServer) DivMany(stream testpb.Math_DivManyServer) error {
+	md, ok := metadata.FromContext(stream.Context())
+	if ok {
+		if err := stream.SendHeader(md); err != nil {
+			log.Fatalf("%v.SendHeader(%v) = %v, want %v", stream, md, err, nil)
+		}
+		stream.SetTrailer(md)
+	}
+	for {
+		in, err := stream.Recv()
+		if err == io.EOF {
+			// read done.
+			return nil
+		}
+		if err != nil {
+			return err
+		}
+		n, d := in.GetDividend(), in.GetDivisor()
+		if d == 0 {
+			return fmt.Errorf("math: divide by 0")
+		}
+		err = stream.Send(&testpb.DivReply{
+			Quotient:  proto.Int64(n / d),
+			Remainder: proto.Int64(n % d),
+		})
+		if err != nil {
+			return err
+		}
+	}
+}
+
+func (s *mathServer) Fib(args *testpb.FibArgs, stream testpb.Math_FibServer) error {
+	var (
+		limit = args.GetLimit()
+		count int64
+		x, y  int64 = 0, 1
+	)
+	for count = 0; limit == 0 || count < limit; count++ {
+		// Send the next number in the Fibonacci sequence.
+		stream.Send(&testpb.Num{
+			Num: proto.Int64(x),
+		})
+		x, y = y, x+y
+	}
+	return nil // The RPC library will call stream.CloseSend for us.
+}
+
+func (s *mathServer) Sum(stream testpb.Math_SumServer) error {
+	var sum int64
+	for {
+		m, err := stream.Recv()
+		if err == io.EOF {
+			return stream.SendAndClose(&testpb.Num{Num: &sum})
+		}
+		if err != nil {
+			return err
+		}
+		sum += m.GetNum()
+	}
+}
+
+const tlsDir = "testdata/"
+
+func setUp(useTLS bool, maxStream uint32) (s *rpc.Server, mc testpb.MathClient) {
+	lis, err := net.Listen("tcp", ":0")
+	if err != nil {
+		log.Fatalf("Failed to listen: %v", err)
+	}
+	_, port, err := net.SplitHostPort(lis.Addr().String())
+	if err != nil {
+		log.Fatalf("Failed to parse listener address: %v", err)
+	}
+	if useTLS {
+		creds, err := credentials.NewServerTLSFromFile(tlsDir+"server1.pem", tlsDir+"server1.key")
+		if err != nil {
+			log.Fatalf("Failed to generate credentials %v", err)
+		}
+		s = rpc.NewServer(lis, rpc.MaxConcurrentStreams(maxStream), rpc.WithServerTLS(creds))
+	} else {
+		s = rpc.NewServer(lis, rpc.MaxConcurrentStreams(maxStream))
+	}
+	ms := &mathServer{}
+	testpb.RegisterService(s, ms)
+	go s.Run()
+	addr := "localhost:" + port
+	creds, err := credentials.NewClientTLSFromFile(tlsDir+"ca.pem", "x.test.youtube.com")
+	if err != nil {
+		log.Fatalf("Failed to create credentials %v", err)
+	}
+	conn, err := rpc.Dial(addr, rpc.WithClientTLS(creds))
+	if err != nil {
+		log.Fatalf("Dial(%v) = %v", conn, err)
+	}
+	mc = testpb.NewMathClient(conn)
+	return
+}
+
+func TestFailedRPC(t *testing.T) {
+	s, mc := setUp(true, math.MaxUint32)
+	defer s.Stop()
+	args := &testpb.DivArgs{
+		Dividend: proto.Int64(8),
+		Divisor:  proto.Int64(0),
+	}
+	expectedErr := rpc.Errorf(codes.Unknown, "math: divide by 0")
+	reply, rpcErr := mc.Div(context.Background(), args)
+	if fmt.Sprint(rpcErr) != fmt.Sprint(expectedErr) {
+		t.Fatalf(`mathClient.Div(_, _) = %v, %v; want <nil>, %v`, reply, rpcErr, expectedErr)
+	}
+}
+
+func TestMetadataUnaryRPC(t *testing.T) {
+	s, mc := setUp(true, math.MaxUint32)
+	defer s.Stop()
+	args := &testpb.DivArgs{
+		Dividend: proto.Int64(8),
+		Divisor:  proto.Int64(2),
+	}
+	md := metadata.New(testMetadata)
+	ctx := metadata.NewContext(context.Background(), md)
+	var header, trailer metadata.MD
+	_, err := mc.Div(ctx, args, rpc.Header(&header), rpc.Trailer(&trailer))
+	if err != nil {
+		t.Fatalf("mathClient.Div(%v, _, _, _) = _, %v; want _, <nil>", ctx, err)
+	}
+	if !reflect.DeepEqual(testMetadata, header.Copy()) {
+		t.Fatalf("Received header metadata %v, want %v", header.Copy(), testMetadata)
+	}
+	if !reflect.DeepEqual(testMetadata, trailer.Copy()) {
+		t.Fatalf("Received trailer metadata %v, want %v", trailer.Copy(), testMetadata)
+	}
+}
+
+func performOneRPC(t *testing.T, mc testpb.MathClient, wg *sync.WaitGroup) {
+	args := &testpb.DivArgs{
+		Dividend: proto.Int64(8),
+		Divisor:  proto.Int64(3),
+	}
+	reply, err := mc.Div(context.Background(), args)
+	want := &testpb.DivReply{
+		Quotient:  proto.Int64(2),
+		Remainder: proto.Int64(2),
+	}
+	if err != nil || !proto.Equal(reply, want) {
+		t.Fatalf(`mathClient.Div(_, _) = %v, %v; want %v, <nil>`, reply, err, want)
+	}
+	wg.Done()
+}
+
+// This test mimics a user who sends 1000 RPCs concurrently on a faulty transport.
+// TODO(zhaoq): Refactor to make this clearer and add more cases to test racy
+// and error-prone paths.
+func TestRetry(t *testing.T) {
+	s, mc := setUp(true, math.MaxUint32)
+	defer s.Stop()
+	var wg sync.WaitGroup
+	wg.Add(1)
+	go func() {
+		time.Sleep(1 * time.Second)
+		// The server shuts down the network connection to make a
+		// transport error which will be detected by the client side
+		// code.
+		s.CloseConns()
+		wg.Done()
+	}()
+	// All these RPCs should succeed eventually.
+	for i := 0; i < 1000; i++ {
+		time.Sleep(2 * time.Millisecond)
+		wg.Add(1)
+		go performOneRPC(t, mc, &wg)
+	}
+	wg.Wait()
+}
+
+// TODO(zhaoq): Have a better test coverage of timeout and cancellation mechanism.
+func TestTimeout(t *testing.T) {
+	s, mc := setUp(true, math.MaxUint32)
+	defer s.Stop()
+	args := &testpb.DivArgs{
+		Dividend: proto.Int64(8),
+		Divisor:  proto.Int64(3),
+	}
+	// Performs 100 RPCs with various timeout values so that
+	// the RPCs could timeout on different stages of their lifetime. This
+	// is the best-effort to cover various cases when an rpc gets cancelled.
+	for i := 1; i <= 100; i++ {
+		ctx, _ := context.WithTimeout(context.Background(), time.Duration(i)*time.Microsecond)
+		reply, err := mc.Div(ctx, args)
+		if rpc.Code(err) != codes.DeadlineExceeded {
+			t.Fatalf(`mathClient.Div(_, _) = %v, %v; want <nil>, error code: %d`, reply, err, codes.DeadlineExceeded)
+		}
+	}
+}
+
+func TestCancel(t *testing.T) {
+	s, mc := setUp(true, math.MaxUint32)
+	defer s.Stop()
+	args := &testpb.DivArgs{
+		Dividend: proto.Int64(8),
+		Divisor:  proto.Int64(3),
+	}
+	ctx, cancel := context.WithCancel(context.Background())
+	time.AfterFunc(1*time.Millisecond, cancel)
+	reply, err := mc.Div(ctx, args)
+	if rpc.Code(err) != codes.Canceled {
+		t.Fatalf(`mathClient.Div(_, _) = %v, %v; want <nil>, error code: %d`, reply, err, codes.Canceled)
+	}
+}
+
+// The following tests the gRPC streaming RPC implementations.
+// TODO(zhaoq): Have better coverage on error cases.
+
+func TestBidiStreaming(t *testing.T) {
+	s, mc := setUp(true, math.MaxUint32)
+	defer s.Stop()
+	for _, test := range []struct {
+		// input
+		divs []string
+		// output
+		status error
+	}{
+		{[]string{"1/1", "3/2", "2/3", "1/2"}, io.EOF},
+		{[]string{"2/5", "2/3", "3/0", "5/4"}, rpc.Errorf(codes.Unknown, "math: divide by 0")},
+	} {
+		stream, err := mc.DivMany(context.Background())
+		if err != nil {
+			t.Fatalf("failed to create stream %v", err)
+		}
+		// Start a goroutine to parse and send the args.
+		go func() {
+			for _, args := range parseArgs(test.divs) {
+				if err := stream.Send(args); err != nil {
+					t.Fatal("Send failed: ", err)
+					return
+				}
+			}
+			// Tell the server we're done sending args.
+			stream.CloseSend()
+		}()
+		var rpcStatus error
+		for {
+			_, err := stream.Recv()
+			if err != nil {
+				rpcStatus = err
+				break
+			}
+		}
+		if rpcStatus != test.status {
+			t.Fatalf(`mathClient.DivMany got %v ; want %v`, rpcStatus, test.status)
+		}
+	}
+}
+
+// parseArgs converts a list of "n/d" strings into DivArgs.
+// parseArgs crashes the process on error.
+func parseArgs(divs []string) (args []*testpb.DivArgs) {
+	for _, div := range divs {
+		parts := strings.Split(div, "/")
+		n, err := strconv.ParseInt(parts[0], 10, 64)
+		if err != nil {
+			log.Fatal(err)
+		}
+		d, err := strconv.ParseInt(parts[1], 10, 64)
+		if err != nil {
+			log.Fatal(err)
+		}
+		args = append(args, &testpb.DivArgs{
+			Dividend: &n,
+			Divisor:  &d,
+		})
+	}
+	return
+}
+
+func TestMetadataStreamingRPC(t *testing.T) {
+	s, mc := setUp(true, math.MaxUint32)
+	defer s.Stop()
+	md := metadata.New(testMetadata)
+	ctx := metadata.NewContext(context.Background(), md)
+	stream, err := mc.DivMany(ctx)
+	if err != nil {
+		t.Fatalf("Failed to create stream %v", err)
+	}
+	go func() {
+		headerMD, err := stream.Header()
+		if err != nil || !reflect.DeepEqual(testMetadata, headerMD.Copy()) {
+			t.Fatalf("#1 %v.Header() = %v, %v, want %v, <nil>", stream, headerMD, err, testMetadata)
+		}
+		// test the cached value.
+		headerMD, err = stream.Header()
+		if err != nil || !reflect.DeepEqual(testMetadata, headerMD.Copy()) {
+			t.Fatalf("#2 %v.Header() = %v, %v, want %v, <nil>", stream, headerMD, err, testMetadata)
+		}
+		for _, args := range parseArgs([]string{"1/1", "3/2", "2/3"}) {
+			if err := stream.Send(args); err != nil {
+				t.Fatalf("%v.Send(_) failed: %v", stream, err)
+				return
+			}
+		}
+		// Tell the server we're done sending args.
+		stream.CloseSend()
+	}()
+	for {
+		_, err := stream.Recv()
+		if err != nil {
+			break
+		}
+	}
+	trailerMD := stream.Trailer()
+	if !reflect.DeepEqual(testMetadata, trailerMD.Copy()) {
+		t.Fatalf("%v.Trailer() = %v, want %v", stream, trailerMD, testMetadata)
+	}
+}
+
+func TestServerStreaming(t *testing.T) {
+	s, mc := setUp(true, math.MaxUint32)
+	defer s.Stop()
+
+	args := &testpb.FibArgs{}
+	// Requests the first 10 Fibonnaci numbers.
+	args.Limit = proto.Int64(10)
+
+	// Start the stream and send the args.
+	stream, err := mc.Fib(context.Background(), args)
+	if err != nil {
+		t.Fatalf("failed to create stream %v", err)
+	}
+	var rpcStatus error
+	for {
+		_, err := stream.Recv()
+		if err != nil {
+			rpcStatus = err
+			break
+		}
+	}
+	if rpcStatus != io.EOF {
+		t.Fatalf(`mathClient.Fib got %v ; want <EOF>`, rpcStatus)
+	}
+}
+
+func TestClientStreaming(t *testing.T) {
+	s, mc := setUp(true, math.MaxUint32)
+	defer s.Stop()
+
+	stream, err := mc.Sum(context.Background())
+	if err != nil {
+		t.Fatalf("failed to create stream: %v", err)
+	}
+	for _, n := range []int64{1, -2, 0, 7} {
+		if err := stream.Send(&testpb.Num{Num: &n}); err != nil {
+			t.Fatalf("failed to send requests %v", err)
+		}
+	}
+	if _, err := stream.CloseAndRecv(); err != io.EOF {
+		t.Fatalf("stream.CloseAndRecv() got %v; want <EOF>", err)
+	}
+}
+
+func TestExceedMaxStreamsLimit(t *testing.T) {
+	// Only allows 1 live stream per server transport.
+	s, mc := setUp(true, 1)
+	defer s.Stop()
+	var err error
+	for {
+		time.Sleep(2 * time.Millisecond)
+		_, err = mc.Sum(context.Background())
+		// Loop until the settings of max concurrent streams is
+		// received by the client.
+		if err != nil {
+			break
+		}
+	}
+	if rpc.Code(err) != codes.Unavailable {
+		t.Fatalf("got %v, want error code %d", err, codes.Unavailable)
+	}
+}
diff --git a/test/testdata/ca.pem b/test/testdata/ca.pem
new file mode 100644
index 00000000..999da897
--- /dev/null
+++ b/test/testdata/ca.pem
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICIzCCAYwCCQCFTbF7XNSvvjANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJB
+VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
+cyBQdHkgTHRkMQ8wDQYDVQQDDAZ0ZXN0Y2EwHhcNMTQwNzE3MjMxNzUxWhcNMjQw
+NzE0MjMxNzUxWjBWMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEh
+MB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQ8wDQYDVQQDDAZ0ZXN0
+Y2EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMBA3wVeTGHZR1Rye/i+J8a2
+cu5gXwFV6TnObzGM7bLFCO5i9v4mLo4iFzPsHmWDUxKS3Y8iXbu0eYBlLoNY0lSv
+xDx33O+DuwMmVN+DzSD+Eod9zfvwOWHsazYCZT2PhNxnVWIuJXViY4JAHUGodjx+
+QAi6yCAurUZGvYXGgZSBAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAQoQVD8bwdtWJ
+AniGBwcCfqYyH+/KpA10AcebJVVTyYbYvI9Q8d6RSVu4PZy9OALHR/QrWBdYTAyz
+fNAmc2cmdkSRJzjhIaOstnQy1J+Fk0T9XyvQtq499yFbq9xogUVlEGH62xP6vH0Y
+5ukK//dCPAzA11YuX2rnex0JhuTQfcI=
+-----END CERTIFICATE-----
diff --git a/test/testdata/server1.key b/test/testdata/server1.key
new file mode 100644
index 00000000..ed00cd50
--- /dev/null
+++ b/test/testdata/server1.key
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICWwIBAAKBgQDhwxUnKCwlSaWAwzOB2LSHVegJHv7DDWminTg4wzLLsf+LQ8nZ
+bpjfn5vgIzxCuRh4Rp9QYM5FhfrJX9wcYawP/HTbJ7p7LVQO2QYAP+akMTHxgKuM
+BzVV++3wWToKfVZUjFX8nfTfGMGwWAHJDnlEGnU4tl9UujoCV4ENJtzFoQIDAQAB
+AoGAJ+6hpzNr24yTQZtFWQpDpEyFplddKJMOxDya3S9ppK3vTWrIITV2xNcucw7I
+ceTbdyrGsyjsU0/HdCcIf9ym2jfmGLUwmyhltKVw0QYcFB0XLkc0nI5YvEYoeVDg
+omZIXn1E3EW+sSIWSbkMu9bY2kstKXR2UZmMgWDtmBEPMaECQQD6yT4TAZM5hGBb
+ciBKgMUP6PwOhPhOMPIvijO50Aiu6iuCV88l1QIy38gWVhxjNrq6P346j4IBg+kB
+9alwpCODAkEA5nSnm9k6ykYeQWNS0fNWiRinCdl23A7usDGSuKKlm019iomJ/Rgd
+MKDOp0q/2OostbteOWM2MRFf4jMH3wyVCwJAfAdjJ8szoNKTRSagSbh9vWygnB2v
+IByc6l4TTuZQJRGzCveafz9lovuB3WohCABdQRd9ukCXL2CpsEpqzkafOQJAJUjc
+USedDlq3zGZwYM1Yw8d8RuirBUFZNqJelYai+nRYClDkRVFgb5yksoYycbq5TxGo
+VeqKOvgPpj4RWPHlLwJAGUMk3bqT91xBUCnLRs/vfoCpHpg6eywQTBDAV6xkyz4a
+RH3I7/+yj3ZxR2JoWHgUwZ7lZk1VnhffFye7SBXyag==
+-----END RSA PRIVATE KEY-----
diff --git a/test/testdata/server1.pem b/test/testdata/server1.pem
new file mode 100644
index 00000000..8e582e57
--- /dev/null
+++ b/test/testdata/server1.pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIICmzCCAgSgAwIBAgIBAzANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJBVTET
+MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ
+dHkgTHRkMQ8wDQYDVQQDDAZ0ZXN0Y2EwHhcNMTQwNzIyMDYwMDU3WhcNMjQwNzE5
+MDYwMDU3WjBkMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
+BAcTB0NoaWNhZ28xFDASBgNVBAoTC0dvb2dsZSBJbmMuMRowGAYDVQQDFBEqLnRl
+c3QuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4cMVJygs
+JUmlgMMzgdi0h1XoCR7+ww1pop04OMMyy7H/i0PJ2W6Y35+b4CM8QrkYeEafUGDO
+RYX6yV/cHGGsD/x02ye6ey1UDtkGAD/mpDEx8YCrjAc1Vfvt8Fk6Cn1WVIxV/J30
+3xjBsFgByQ55RBp1OLZfVLo6AleBDSbcxaECAwEAAaNrMGkwCQYDVR0TBAIwADAL
+BgNVHQ8EBAMCBeAwTwYDVR0RBEgwRoIQKi50ZXN0Lmdvb2dsZS5mcoIYd2F0ZXJ6
+b29pLnRlc3QuZ29vZ2xlLmJlghIqLnRlc3QueW91dHViZS5jb22HBMCoAQMwDQYJ
+KoZIhvcNAQEFBQADgYEAM2Ii0LgTGbJ1j4oqX9bxVcxm+/R5Yf8oi0aZqTJlnLYS
+wXcBykxTx181s7WyfJ49WwrYXo78zTDAnf1ma0fPq3e4mpspvyndLh1a+OarHa1e
+aT0DIIYk7qeEa1YcVljx2KyLd0r1BBAfrwyGaEPVeJQVYWaOJRU2we/KD4ojf9s=
+-----END CERTIFICATE-----
diff --git a/test/testdata/test.pb.go b/test/testdata/test.pb.go
new file mode 100755
index 00000000..0477e2be
--- /dev/null
+++ b/test/testdata/test.pb.go
@@ -0,0 +1,182 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+// Code generated by protoc-gen-go.
+// source: net/grpc/go/test/test.proto
+// DO NOT EDIT!
+
+/*
+Package test is a generated protocol buffer package.
+
+It is generated from these files:
+	net/grpc/go/test/test.proto
+
+It has these top-level messages:
+	DivArgs
+	DivReply
+	FibArgs
+	Num
+	FibReply
+*/
+package test
+
+import proto "github.com/golang/protobuf/proto"
+import math "math"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = math.Inf
+
+type DivArgs struct {
+	Dividend         *int64 `protobuf:"varint,1,req,name=dividend" json:"dividend,omitempty"`
+	Divisor          *int64 `protobuf:"varint,2,req,name=divisor" json:"divisor,omitempty"`
+	XXX_unrecognized []byte `json:"-"`
+}
+
+func (m *DivArgs) Reset()                    { *m = DivArgs{} }
+func (m *DivArgs) String() string            { return proto.CompactTextString(m) }
+func (*DivArgs) ProtoMessage()               {}
+func (*DivArgs) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
+
+func (m *DivArgs) GetDividend() int64 {
+	if m != nil && m.Dividend != nil {
+		return *m.Dividend
+	}
+	return 0
+}
+
+func (m *DivArgs) GetDivisor() int64 {
+	if m != nil && m.Divisor != nil {
+		return *m.Divisor
+	}
+	return 0
+}
+
+type DivReply struct {
+	Quotient         *int64 `protobuf:"varint,1,req,name=quotient" json:"quotient,omitempty"`
+	Remainder        *int64 `protobuf:"varint,2,req,name=remainder" json:"remainder,omitempty"`
+	XXX_unrecognized []byte `json:"-"`
+}
+
+func (m *DivReply) Reset()                    { *m = DivReply{} }
+func (m *DivReply) String() string            { return proto.CompactTextString(m) }
+func (*DivReply) ProtoMessage()               {}
+func (*DivReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
+
+func (m *DivReply) GetQuotient() int64 {
+	if m != nil && m.Quotient != nil {
+		return *m.Quotient
+	}
+	return 0
+}
+
+func (m *DivReply) GetRemainder() int64 {
+	if m != nil && m.Remainder != nil {
+		return *m.Remainder
+	}
+	return 0
+}
+
+type FibArgs struct {
+	Limit            *int64 `protobuf:"varint,1,opt,name=limit" json:"limit,omitempty"`
+	XXX_unrecognized []byte `json:"-"`
+}
+
+func (m *FibArgs) Reset()                    { *m = FibArgs{} }
+func (m *FibArgs) String() string            { return proto.CompactTextString(m) }
+func (*FibArgs) ProtoMessage()               {}
+func (*FibArgs) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
+
+func (m *FibArgs) GetLimit() int64 {
+	if m != nil && m.Limit != nil {
+		return *m.Limit
+	}
+	return 0
+}
+
+type Num struct {
+	Num              *int64 `protobuf:"varint,1,req,name=num" json:"num,omitempty"`
+	XXX_unrecognized []byte `json:"-"`
+}
+
+func (m *Num) Reset()                    { *m = Num{} }
+func (m *Num) String() string            { return proto.CompactTextString(m) }
+func (*Num) ProtoMessage()               {}
+func (*Num) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
+
+func (m *Num) GetNum() int64 {
+	if m != nil && m.Num != nil {
+		return *m.Num
+	}
+	return 0
+}
+
+type FibReply struct {
+	Count            *int64 `protobuf:"varint,1,req,name=count" json:"count,omitempty"`
+	XXX_unrecognized []byte `json:"-"`
+}
+
+func (m *FibReply) Reset()                    { *m = FibReply{} }
+func (m *FibReply) String() string            { return proto.CompactTextString(m) }
+func (*FibReply) ProtoMessage()               {}
+func (*FibReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
+
+func (m *FibReply) GetCount() int64 {
+	if m != nil && m.Count != nil {
+		return *m.Count
+	}
+	return 0
+}
+
+func init() {
+}
+
+var fileDescriptor0 = []byte{
+	// 268 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x84, 0x90, 0xbf, 0x4e, 0xc3, 0x30,
+	0x10, 0x87, 0xb9, 0xba, 0x34, 0xe9, 0xa1, 0xf2, 0xc7, 0x53, 0x28, 0x0b, 0xf2, 0x80, 0x3a, 0xa0,
+	0x06, 0x21, 0x5e, 0x00, 0x84, 0xd8, 0xca, 0x00, 0x1b, 0x5b, 0x68, 0xac, 0x60, 0xa9, 0xb1, 0x83,
+	0xe3, 0x54, 0xea, 0xdb, 0x64, 0x64, 0xe4, 0x11, 0x39, 0x3b, 0x09, 0x88, 0xa9, 0x4b, 0x94, 0xbb,
+	0xfb, 0xee, 0xa7, 0xef, 0x8c, 0x17, 0x5a, 0xba, 0xb4, 0xb0, 0xd5, 0x3a, 0x2d, 0x4c, 0xea, 0x64,
+	0xed, 0xc2, 0x67, 0x59, 0x59, 0xe3, 0x0c, 0x1f, 0xfb, 0x7f, 0x71, 0x8d, 0xd1, 0xa3, 0xda, 0xde,
+	0xdb, 0xa2, 0xe6, 0xa7, 0x18, 0xe7, 0x6a, 0xab, 0x72, 0xa9, 0xf3, 0x04, 0x2e, 0x47, 0x0b, 0xc6,
+	0x4f, 0x30, 0xf2, 0x9d, 0xda, 0xd8, 0x64, 0xe4, 0x1b, 0x22, 0xc5, 0x98, 0xe8, 0x17, 0x59, 0x6d,
+	0x76, 0x1e, 0xff, 0x6c, 0x8c, 0x53, 0x52, 0xbb, 0x1e, 0x3f, 0xc3, 0xa9, 0x95, 0x65, 0xa6, 0x74,
+	0x2e, 0x87, 0x85, 0x04, 0xa3, 0x27, 0xf5, 0x1e, 0xe2, 0x67, 0x78, 0xb8, 0x51, 0xa5, 0xf2, 0x30,
+	0xd0, 0x84, 0x23, 0x7b, 0x6e, 0x4a, 0x7e, 0x84, 0x4c, 0x37, 0x65, 0x17, 0x20, 0xce, 0x31, 0x26,
+	0xba, 0x8b, 0x27, 0x7c, 0x6d, 0x9a, 0x21, 0xfb, 0xf6, 0x1b, 0x70, 0xbc, 0xca, 0xdc, 0x07, 0xbf,
+	0x42, 0x46, 0x0a, 0x7c, 0xb6, 0x0c, 0xa7, 0xf4, 0xee, 0xf3, 0xe3, 0xdf, 0x32, 0x6c, 0x8b, 0x03,
+	0x7e, 0x17, 0x0e, 0x5b, 0x65, 0x7a, 0xb7, 0x8f, 0x9d, 0xb4, 0x00, 0x5f, 0x00, 0x0b, 0xb8, 0x01,
+	0x9f, 0x4e, 0x06, 0xc3, 0x46, 0xaf, 0x3e, 0x9f, 0x76, 0x25, 0xf9, 0x0a, 0x46, 0x24, 0x71, 0x02,
+	0xd9, 0x2b, 0xd9, 0xff, 0x0d, 0xfe, 0x31, 0xad, 0x4f, 0x7b, 0x98, 0xbc, 0x85, 0x27, 0xfe, 0x09,
+	0x00, 0x00, 0xff, 0xff, 0x5d, 0x79, 0x02, 0xec, 0x86, 0x01, 0x00, 0x00,
+}
diff --git a/test/testdata/test.proto b/test/testdata/test.proto
new file mode 100644
index 00000000..4e72cf87
--- /dev/null
+++ b/test/testdata/test.proto
@@ -0,0 +1,52 @@
+syntax = "proto2";
+
+package test;
+
+option go_package = "test";
+
+message DivArgs {
+  required int64 dividend = 1;
+  required int64 divisor = 2;
+}
+
+message DivReply {
+  required int64 quotient = 1;
+  required int64 remainder = 2;
+}
+
+message FibArgs {
+  optional int64 limit = 1;
+}
+
+message Num {
+  required int64 num = 1;
+}
+
+message FibReply {
+  required int64 count = 1;
+}
+
+service Math {  // This name leads to "MathServer" and "MathClient".
+  // Div divides args.dividend by args.divisor and returns the quotient and
+  // remainder.
+  rpc Div (DivArgs) returns (DivReply) {
+  }
+
+  // DivMany accepts an arbitrary number of division args from the client stream
+  // and sends back the results in the reply stream.  The stream continues until
+  // the client closes its end; the server does the same after sending all the
+  // replies.  The stream ends immediately if either end aborts.
+  rpc DivMany (stream DivArgs) returns (stream DivReply) {
+  }
+
+  // Fib generates numbers in the Fibonacci sequence.  If args.limit > 0, Fib4
+  // generates up to limit numbers; otherwise it continues until the call is
+  // canceled.  Unlike Fib above, Fib4 has no final FibReply.
+  rpc Fib (FibArgs) returns (stream Num) {
+  }
+
+  // Sum sums a stream of numbers, returning the final result once the stream
+  // is closed.
+  rpc Sum (stream Num) returns (Num) {
+  }
+}
diff --git a/test/testdata/test_grpc.pb.go b/test/testdata/test_grpc.pb.go
new file mode 100755
index 00000000..69d4c1aa
--- /dev/null
+++ b/test/testdata/test_grpc.pb.go
@@ -0,0 +1,292 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package test
+
+import (
+	"fmt"
+	"io"
+	"github.com/google/grpc-go"
+	context "golang.org/x/net/context"
+	proto "github.com/golang/protobuf/proto"
+)
+
+type MathClient interface {
+	Div(ctx context.Context, in *DivArgs, opts ...rpc.CallOption) (*DivReply, error)
+	DivMany(ctx context.Context, opts ...rpc.CallOption) (Math_DivManyClient, error)
+	Fib(ctx context.Context, m *FibArgs, opts ...rpc.CallOption) (Math_FibClient, error)
+	Sum(ctx context.Context, opts ...rpc.CallOption) (Math_SumClient, error)
+}
+
+type mathClient struct {
+	cc *rpc.ClientConn
+}
+
+func NewMathClient(cc *rpc.ClientConn) MathClient {
+	return &mathClient{cc}
+}
+
+func (c *mathClient) Div(ctx context.Context, in *DivArgs, opts ...rpc.CallOption) (*DivReply, error) {
+	out := new(DivReply)
+	err := rpc.Invoke(ctx, "/test.Math/Div", in, out, c.cc, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *mathClient) DivMany(ctx context.Context, opts ...rpc.CallOption) (Math_DivManyClient, error) {
+	stream, err := rpc.NewClientStream(ctx, c.cc, "/test.Math/DivMany", opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &mathDivManyClient{stream}, nil
+}
+
+type Math_DivManyClient interface {
+	Send(*DivArgs) error
+	Recv() (*DivReply, error)
+	rpc.ClientStream
+}
+
+type mathDivManyClient struct {
+	rpc.ClientStream
+}
+
+func (x *mathDivManyClient) Send(m *DivArgs) error {
+	return x.ClientStream.SendProto(m)
+}
+
+func (x *mathDivManyClient) Recv() (*DivReply, error) {
+	m := new(DivReply)
+	if err := x.ClientStream.RecvProto(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func (c *mathClient) Fib(ctx context.Context, m *FibArgs, opts ...rpc.CallOption) (Math_FibClient, error) {
+	stream, err := rpc.NewClientStream(ctx, c.cc, "/test.Math/Fib", opts...)
+	if err != nil {
+		return nil, err
+	}
+	x := &mathFibClient{stream}
+	if err := x.ClientStream.SendProto(m); err != nil {
+		return nil, err
+	}
+	if err := x.ClientStream.CloseSend(); err != nil {
+		return nil, err
+	}
+	return x, nil
+}
+
+type Math_FibClient interface {
+	Recv() (*Num, error)
+	rpc.ClientStream
+}
+
+type mathFibClient struct {
+	rpc.ClientStream
+}
+
+func (x *mathFibClient) Recv() (*Num, error) {
+	m := new(Num)
+	if err := x.ClientStream.RecvProto(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func (c *mathClient) Sum(ctx context.Context, opts ...rpc.CallOption) (Math_SumClient, error) {
+	stream, err := rpc.NewClientStream(ctx, c.cc, "/test.Math/Sum", opts...)
+	if err != nil {
+		return nil, err
+	}
+	return &mathSumClient{stream}, nil
+}
+
+type Math_SumClient interface {
+	Send(*Num) error
+	CloseAndRecv() (*Num, error)
+	rpc.ClientStream
+}
+
+type mathSumClient struct {
+	rpc.ClientStream
+}
+
+func (x *mathSumClient) Send(m *Num) error {
+	return x.ClientStream.SendProto(m)
+}
+
+func (x *mathSumClient) CloseAndRecv() (*Num, error) {
+	if err := x.ClientStream.CloseSend(); err != nil {
+		return nil, err
+	}
+	m := new(Num)
+	if err := x.ClientStream.RecvProto(m); err != nil {
+		return nil, err
+	}
+	// Read EOF.
+	if err := x.ClientStream.RecvProto(m); err == io.EOF {
+		return m, io.EOF
+	}
+	// gRPC protocol violation.
+	return m, fmt.Errorf("Violate gRPC client streaming protocol: no EOF after the response.")
+}
+
+
+type MathServer interface {
+	Div(context.Context, *DivArgs) (*DivReply, error)
+	DivMany(Math_DivManyServer) error
+	Fib(*FibArgs, Math_FibServer) error
+	Sum(Math_SumServer) error
+}
+
+func RegisterService(s *rpc.Server, srv MathServer) {
+	s.RegisterService(&_Math_serviceDesc, srv)
+}
+
+func _Math_Div_Handler(srv interface{}, ctx context.Context, buf []byte) (proto.Message, error) {
+	in := new(DivArgs)
+	if err := proto.Unmarshal(buf, in); err != nil {
+		return nil, err
+	}
+	out, err := srv.(MathServer).Div(ctx, in)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func _Math_DivMany_Handler(srv interface{}, stream rpc.ServerStream) error {
+	return srv.(MathServer).DivMany(&mathDivManyServer{stream})
+}
+
+type Math_DivManyServer interface {
+	Send(*DivReply) error
+	Recv() (*DivArgs, error)
+	rpc.ServerStream
+}
+
+type mathDivManyServer struct {
+	rpc.ServerStream
+}
+
+func (x *mathDivManyServer) Send(m *DivReply) error {
+	return x.ServerStream.SendProto(m)
+}
+
+func (x *mathDivManyServer) Recv() (*DivArgs, error) {
+	m := new(DivArgs)
+	if err := x.ServerStream.RecvProto(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+func _Math_Fib_Handler(srv interface{}, stream rpc.ServerStream) error {
+	m := new(FibArgs)
+	if err := stream.RecvProto(m); err != nil {
+		return err
+	}
+	return srv.(MathServer).Fib(m, &mathFibServer{stream})
+}
+
+type Math_FibServer interface {
+	Send(*Num) error
+	rpc.ServerStream
+}
+
+type mathFibServer struct {
+	rpc.ServerStream
+}
+
+func (x *mathFibServer) Send(m *Num) error {
+	return x.ServerStream.SendProto(m)
+}
+
+func _Math_Sum_Handler(srv interface{}, stream rpc.ServerStream) error {
+	return srv.(MathServer).Sum(&mathSumServer{stream})
+}
+
+type Math_SumServer interface {
+	SendAndClose(*Num) error
+	Recv() (*Num, error)
+	rpc.ServerStream
+}
+
+type mathSumServer struct {
+	rpc.ServerStream
+}
+
+func (x *mathSumServer) SendAndClose(m *Num) error {
+	if err := x.ServerStream.SendProto(m); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (x *mathSumServer) Recv() (*Num, error) {
+	m := new(Num)
+	if err := x.ServerStream.RecvProto(m); err != nil {
+		return nil, err
+	}
+	return m, nil
+}
+
+var _Math_serviceDesc = rpc.ServiceDesc{
+	ServiceName: "test.Math",
+	HandlerType: (*MathServer)(nil),
+	Methods: []rpc.MethodDesc{
+		{
+			MethodName:	"Div",
+			Handler:	_Math_Div_Handler,
+		},
+	},
+	Streams: []rpc.StreamDesc{
+		{
+			StreamName:	"DivMany",
+			Handler:	_Math_DivMany_Handler,
+		},
+		{
+			StreamName:	"Fib",
+			Handler:	_Math_Fib_Handler,
+		},
+		{
+			StreamName:	"Sum",
+			Handler:	_Math_Sum_Handler,
+		},
+	},
+}
+
+
diff --git a/transport/control.go b/transport/control.go
new file mode 100755
index 00000000..28335965
--- /dev/null
+++ b/transport/control.go
@@ -0,0 +1,125 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package transport
+
+import (
+	"sync"
+
+	"github.com/bradfitz/http2"
+)
+
+// TODO(zhaoq): Make the following configurable.
+const (
+	// The initial window size for flow control.
+	initialWindowSize = 65535
+	// Window update is only sent when the inbound quota reaches
+	// this threshold. Used to reduce the flow control traffic.
+	windowUpdateThreshold = 16384
+)
+
+// The following defines various control items which could flow through
+// the control buffer of transport. They represent different aspects of
+// control tasks, e.g., flow control, settings, streaming resetting, etc.
+type windowUpdate struct {
+	streamID  uint32
+	increment uint32
+}
+
+func (windowUpdate) isItem() bool {
+	return true
+}
+
+type settings struct {
+	id  http2.SettingID
+	val uint32
+}
+
+func (settings) isItem() bool {
+	return true
+}
+
+type resetStream struct {
+	streamID uint32
+	code     http2.ErrCode
+}
+
+func (resetStream) isItem() bool {
+	return true
+}
+
+// quotaPool is a pool which accumulates the quota and sends it to acquire()
+// when it is available.
+type quotaPool struct {
+	c chan int
+
+	mu    sync.Mutex
+	quota int
+}
+
+// newQuotaPool creates a quotaPool which has quota q available to consume.
+func newQuotaPool(q int) *quotaPool {
+	qb := &quotaPool{c: make(chan int, 1)}
+	qb.c <- q
+	return qb
+}
+
+// add adds n to the available quota and tries to send it on acquire.
+func (qb *quotaPool) add(n int) {
+	qb.mu.Lock()
+	defer qb.mu.Unlock()
+	qb.quota += n
+	if qb.quota <= 0 {
+		return
+	}
+	select {
+	case qb.c <- qb.quota:
+		qb.quota = 0
+	default:
+	}
+}
+
+// cancel cancels the pending quota sent on acquire, if any.
+func (qb *quotaPool) cancel() {
+	qb.mu.Lock()
+	defer qb.mu.Unlock()
+	select {
+	case n := <-qb.c:
+		qb.quota += n
+	default:
+	}
+}
+
+// acquire returns the channel on which available quota amounts are sent.
+func (qb *quotaPool) acquire() <-chan int {
+	return qb.c
+}
diff --git a/transport/http2_client_transport.go b/transport/http2_client_transport.go
new file mode 100755
index 00000000..b10c7251
--- /dev/null
+++ b/transport/http2_client_transport.go
@@ -0,0 +1,644 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package transport
+
+import (
+	"bytes"
+	"io"
+	"log"
+	"math"
+	"net"
+	"sync"
+	"time"
+
+	"github.com/google/grpc-go/codes"
+	"github.com/google/grpc-go/credentials"
+	"github.com/google/grpc-go/metadata"
+	"golang.org/x/net/context"
+	"github.com/bradfitz/http2/hpack"
+	"github.com/bradfitz/http2"
+)
+
+// http2Client implements the ClientTransport interface with HTTP2.
+type http2Client struct {
+	target string   // server name/addr
+	conn   net.Conn // underlying communication channel
+	nextID uint32   // the next stream ID to be used
+
+	// writableChan synchronizes write access to the transport.
+	// A writer acquires the write lock by sending a value on writableChan
+	// and releases it by receiving from writableChan.
+	writableChan chan int
+	// shutdownChan is closed when Close is called.
+	// Blocking operations should select on shutdownChan to avoid
+	// blocking forever after Close.
+	// TODO(zhaoq): Maybe have a channel context?
+	shutdownChan chan struct{}
+	// errorChan is closed to notify the I/O error to the caller.
+	errorChan chan struct{}
+
+	framer *http2.Framer
+	hBuf   *bytes.Buffer  // the buffer for HPACK encoding
+	hEnc   *hpack.Encoder // HPACK encoder
+
+	// controlBuf delivers all the control related tasks (e.g., window
+	// updates, reset streams, and various settings) to the controller.
+	controlBuf *recvBuffer
+	// sendQuotaPool provides flow control to outbound message.
+	sendQuotaPool *quotaPool
+
+	// The scheme used: https if TLS is on, http otherwise.
+	scheme string
+
+	authCreds []credentials.Credentials
+
+	mu            sync.Mutex     // guard the following variables
+	state         transportState // the state of underlying connection
+	activeStreams map[uint32]*Stream
+	// The max number of concurrent streams
+	maxStreams uint32
+	// Inbound quota for flow control
+	recvQuota int
+}
+
+// newHTTP2Client constructs a connected ClientTransport to addr based on HTTP2
+// and starts to receive messages on it. Non-nil error returns if construction
+// fails.
+func newHTTP2Client(addr string, authOpts []credentials.Credentials) (_ ClientTransport, err error) {
+	var (
+		connErr error
+		conn    net.Conn
+	)
+	scheme := "http"
+	// TODO(zhaoq): Use DialTimeout instead.
+	for _, c := range authOpts {
+		if ccreds, ok := c.(credentials.TransportAuthenticator); ok {
+			scheme = "https"
+			// TODO(zhaoq): Now the first TransportAuthenticator is used if there are
+			// multiple ones provided. Revisit this if it is not appropriate. Probably
+			// place the ClientTransport construction into a separate function to make
+			// things clear.
+			conn, connErr = ccreds.Dial(addr)
+			break
+		}
+	}
+	if scheme == "http" {
+		conn, connErr = net.Dial("tcp", addr)
+	}
+	if connErr != nil {
+		return nil, ConnectionErrorf("%v", connErr)
+	}
+	defer func() {
+		if err != nil {
+			conn.Close()
+		}
+	}()
+	// Send connection preface to server.
+	n, err := conn.Write(clientPreface)
+	if err != nil {
+		return nil, ConnectionErrorf("%v", err)
+	}
+	if n != len(clientPreface) {
+		return nil, ConnectionErrorf("Wrting client preface, wrote %d bytes; want %d", n, len(clientPreface))
+	}
+	framer := http2.NewFramer(conn, conn)
+	if err := framer.WriteSettings(); err != nil {
+		return nil, ConnectionErrorf("%v", err)
+	}
+	var buf bytes.Buffer
+	t := &http2Client{
+		target: addr,
+		conn:   conn,
+		// The client initiated stream id is odd starting from 1.
+		nextID:        1,
+		writableChan:  make(chan int, 1),
+		shutdownChan:  make(chan struct{}),
+		errorChan:     make(chan struct{}),
+		framer:        framer,
+		hBuf:          &buf,
+		hEnc:          hpack.NewEncoder(&buf),
+		controlBuf:    newRecvBuffer(),
+		sendQuotaPool: newQuotaPool(initialWindowSize),
+		scheme:        scheme,
+		state:         reachable,
+		activeStreams: make(map[uint32]*Stream),
+		maxStreams:    math.MaxUint32,
+		authCreds:     authOpts,
+	}
+	go t.controller()
+	t.writableChan <- 0
+	// Start the reader goroutine for incoming message. The threading model
+	// on receiving is that each transport has a dedicated goroutine which
+	// reads HTTP2 frame from network. Then it dispatches the frame to the
+	// corresponding stream entity.
+	go t.reader()
+	return t, nil
+}
+
+func (t *http2Client) newStream(ctx context.Context, callHdr *CallHdr) *Stream {
+	t.mu.Lock()
+	// TODO(zhaoq): Handle uint32 overflow.
+	s := &Stream{
+		id:            t.nextID,
+		method:        callHdr.Method,
+		buf:           newRecvBuffer(),
+		sendQuotaPool: newQuotaPool(initialWindowSize),
+		headerChan:    make(chan struct{}),
+	}
+	s.windowHandler = func(n int) {
+		t.addRecvQuota(s, n)
+	}
+	// Make a stream be able to cancel the pending operations by itself.
+	s.ctx, s.cancel = context.WithCancel(ctx)
+	s.dec = &recvBufferReader{
+		ctx:  s.ctx,
+		recv: s.buf,
+	}
+	t.nextID += 2
+	t.mu.Unlock()
+	return s
+}
+
+// NewStream creates a stream and register it into the transport as "active"
+// streams.
+func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Stream, err error) {
+	if _, err := wait(ctx, t.shutdownChan, t.writableChan); err != nil {
+		return nil, err
+	}
+	defer func() {
+		if _, ok := err.(ConnectionError); !ok {
+			t.writableChan <- 0
+		}
+	}()
+	// HPACK encodes various headers.
+	t.hBuf.Reset()
+	t.hEnc.WriteField(hpack.HeaderField{Name: ":method", Value: "POST"})
+	t.hEnc.WriteField(hpack.HeaderField{Name: ":scheme", Value: t.scheme})
+	t.hEnc.WriteField(hpack.HeaderField{Name: ":path", Value: callHdr.Method})
+	t.hEnc.WriteField(hpack.HeaderField{Name: ":authority", Value: callHdr.Host})
+	t.hEnc.WriteField(hpack.HeaderField{Name: "content-type", Value: "application/grpc"})
+	t.hEnc.WriteField(hpack.HeaderField{Name: "te", Value: "trailers"})
+	for _, c := range t.authCreds {
+		m, err := c.GetRequestMetadata()
+		if err != nil {
+			return nil, StreamErrorf(codes.InvalidArgument, "%v", err)
+		}
+		for k, v := range m {
+			t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: v})
+		}
+	}
+	if dl, ok := ctx.Deadline(); ok {
+		to := dl.Sub(time.Now())
+		if to <= 0 {
+			return nil, ContextErr(context.DeadlineExceeded)
+		}
+		t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-timeout", Value: timeoutEncode(to)})
+	}
+	if md, ok := metadata.FromContext(ctx); ok {
+		for k, v := range md.Copy() {
+			t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: v})
+		}
+	}
+	first := true
+	endHeaders := false
+	// Sends the headers in a single batch even when they span multiple frames.
+	for !endHeaders {
+		size := t.hBuf.Len()
+		if size > http2MaxFrameLen {
+			size = http2MaxFrameLen
+		} else {
+			endHeaders = true
+		}
+		if first {
+			// Sends a HeadersFrame to server to start a new stream.
+			p := http2.HeadersFrameParam{
+				StreamID:      t.nextID,
+				BlockFragment: t.hBuf.Next(size),
+				EndStream:     false,
+				EndHeaders:    endHeaders,
+			}
+			err = t.framer.WriteHeaders(p)
+			first = false
+		} else {
+			// Sends Continuation frames for the leftover headers.
+			err = t.framer.WriteContinuation(t.nextID, endHeaders, t.hBuf.Next(size))
+		}
+		if err != nil {
+			t.notifyError()
+			return nil, ConnectionErrorf("%v", err)
+		}
+	}
+	s := t.newStream(ctx, callHdr)
+	t.mu.Lock()
+	if t.state != reachable {
+		t.mu.Unlock()
+		return nil, ErrConnClosing
+	}
+	if uint32(len(t.activeStreams)) >= t.maxStreams {
+		t.mu.Unlock()
+		return nil, StreamErrorf(codes.Unavailable, "failed to create new stream because the limit has been reached.")
+	}
+	t.activeStreams[s.id] = s
+	t.mu.Unlock()
+	return s, nil
+}
+
+// CloseStream clears the footprint of a stream when the stream is not needed any more.
+// This must not be executed in reader's goroutine.
+func (t *http2Client) CloseStream(s *Stream, err error) {
+	t.mu.Lock()
+	delete(t.activeStreams, s.id)
+	t.mu.Unlock()
+	s.mu.Lock()
+	if s.state == streamDone {
+		s.mu.Unlock()
+		return
+	}
+	if !s.headerDone {
+		close(s.headerChan)
+		s.headerDone = true
+	}
+	s.state = streamDone
+	s.mu.Unlock()
+	// In case stream sending and receiving are invoked in separate
+	// goroutines (e.g., bi-directional streaming), the caller needs
+	// to call cancel on the stream to interrupt the blocking on
+	// other goroutines.
+	s.cancel()
+	if _, ok := err.(StreamError); ok {
+		t.controlBuf.put(&resetStream{s.id, http2.ErrCodeCancel})
+	}
+}
+
+// Close kicks off the shutdown process of the transport. This should be called
+// only once on a transport. Once it is called, the transport should not be
+// accessed any more.
+func (t *http2Client) Close() {
+	t.mu.Lock()
+	t.state = closing
+	t.mu.Unlock()
+	close(t.shutdownChan)
+	t.conn.Close()
+	t.mu.Lock()
+	streams := t.activeStreams
+	t.activeStreams = nil
+	t.mu.Unlock()
+	// Notify all active streams.
+	for _, s := range streams {
+		s.mu.Lock()
+		if !s.headerDone {
+			close(s.headerChan)
+			s.headerDone = true
+		}
+		s.mu.Unlock()
+		s.write(recvMsg{err: ErrConnClosing})
+	}
+}
+
+// Write formats the data into HTTP2 data frame(s) and sends it out. The caller
+// should proceed only if Write returns nil.
+// TODO(zhaoq): opts.Delay is ignored in this implementation. Support it later
+// if it improves the performance.
+func (t *http2Client) Write(s *Stream, data []byte, opts *Options) error {
+	r := bytes.NewBuffer(data)
+	for {
+		var p []byte
+		if r.Len() > 0 {
+			size := http2MaxFrameLen
+			s.sendQuotaPool.add(0)
+			// Wait until the stream has some quota to send the data.
+			sq, err := wait(s.ctx, t.shutdownChan, s.sendQuotaPool.acquire())
+			if err != nil {
+				return err
+			}
+			t.sendQuotaPool.add(0)
+			// Wait until the transport has some quota to send the data.
+			tq, err := wait(s.ctx, t.shutdownChan, t.sendQuotaPool.acquire())
+			if err != nil {
+				if _, ok := err.(StreamError); ok {
+					t.sendQuotaPool.cancel()
+				}
+				return err
+			}
+			if sq < size {
+				size = sq
+			}
+			if tq < size {
+				size = tq
+			}
+			p = r.Next(size)
+			ps := len(p)
+			if ps < sq {
+				// Overbooked stream quota. Return it back.
+				s.sendQuotaPool.add(sq - ps)
+			}
+			if ps < tq {
+				// Overbooked transport quota. Return it back.
+				t.sendQuotaPool.add(tq - ps)
+			}
+		}
+		var endStream bool
+		if opts.Last && r.Len() == 0 {
+			endStream = true
+		}
+		// Got some quota. Try to acquire writing privilege on the transport.
+		if _, err := wait(s.ctx, t.shutdownChan, t.writableChan); err != nil {
+			return err
+		}
+		// If WriteData fails, all the pending streams will be handled
+		// by http2Client.Close(). No explicit CloseStream() needs to be
+		// invoked.
+		if err := t.framer.WriteData(s.id, endStream, p); err != nil {
+			t.notifyError()
+			return ConnectionErrorf("%v", err)
+		}
+		t.writableChan <- 0
+		if r.Len() == 0 {
+			break
+		}
+	}
+	if !opts.Last {
+		return nil
+	}
+	s.mu.Lock()
+	if s.state != streamDone {
+		if s.state == streamReadDone {
+			s.state = streamDone
+		} else {
+			s.state = streamWriteDone
+		}
+	}
+	s.mu.Unlock()
+	return nil
+}
+
+func (t *http2Client) getStream(f http2.Frame) (*Stream, bool) {
+	t.mu.Lock()
+	defer t.mu.Unlock()
+	if t.activeStreams == nil {
+		// The transport is closing.
+		return nil, false
+	}
+	if s, ok := t.activeStreams[f.Header().StreamID]; ok {
+		return s, true
+	}
+	return nil, false
+}
+
+// addRecvQuota adjusts the inbound quota for the stream and the transport.
+// Window updates will deliver to the controller for sending when
+// the cumulative quota exceeds windowUpdateThreshold.
+func (t *http2Client) addRecvQuota(s *Stream, n int) {
+	t.mu.Lock()
+	t.recvQuota += n
+	if t.recvQuota >= windowUpdateThreshold {
+		t.controlBuf.put(&windowUpdate{0, uint32(t.recvQuota)})
+		t.recvQuota = 0
+	}
+	t.mu.Unlock()
+
+	s.recvQuota += n
+	if s.recvQuota >= windowUpdateThreshold {
+		t.controlBuf.put(&windowUpdate{s.id, uint32(s.recvQuota)})
+		s.recvQuota = 0
+	}
+}
+
+func (t *http2Client) handleData(f *http2.DataFrame) {
+	// Select the right stream to dispatch.
+	s, ok := t.getStream(f)
+	if !ok {
+		return
+	}
+	// TODO(bradfitz, zhaoq): A copy is required here because there is no
+	// guarantee f.Data() is consumed before the arrival of next frame.
+	// Can this copy be eliminated?
+	data := make([]byte, len(f.Data()))
+	copy(data, f.Data())
+	s.write(recvMsg{data: data})
+}
+
+func (t *http2Client) handleRSTStream(f *http2.RSTStreamFrame) {
+	s, ok := t.getStream(f)
+	if !ok {
+		return
+	}
+	s.mu.Lock()
+	if s.state == streamDone {
+		s.mu.Unlock()
+		return
+	}
+	s.state = streamDone
+	s.statusCode, ok = http2RSTErrConvTab[http2.ErrCode(f.ErrCode)]
+	if !ok {
+		log.Println("No gRPC status found for http2 error ", f.ErrCode)
+	}
+	s.mu.Unlock()
+	s.write(recvMsg{err: io.EOF})
+}
+
+func (t *http2Client) handleSettings(f *http2.SettingsFrame) {
+	if v, ok := f.Value(http2.SettingMaxConcurrentStreams); ok {
+		t.mu.Lock()
+		t.maxStreams = v
+		t.mu.Unlock()
+	}
+}
+
+func (t *http2Client) handlePing(f *http2.PingFrame) {
+	log.Println("PingFrame handler to be implemented")
+}
+
+func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) {
+	log.Println("GoAwayFrame handler to be implemented")
+}
+
+func (t *http2Client) handleWindowUpdate(f *http2.WindowUpdateFrame) {
+	id := f.Header().StreamID
+	incr := f.Increment
+	if id == 0 {
+		t.sendQuotaPool.add(int(incr))
+		return
+	}
+	if s, ok := t.getStream(f); ok {
+		s.sendQuotaPool.add(int(incr))
+	}
+}
+
+// operateHeader takes action on the decoded headers. It returns the current
+// stream if there are remaining headers on the wire (in the following
+// Continuation frame).
+func (t *http2Client) operateHeaders(hDec *hpackDecoder, s *Stream, frame headerFrame, endStream bool) (pendingStream *Stream) {
+	defer func() {
+		if pendingStream == nil {
+			hDec.state = decodeState{}
+		}
+	}()
+	endHeaders, err := hDec.decodeClientHTTP2Headers(s, frame)
+	if err != nil {
+		s.write(recvMsg{err: err})
+		// Something wrong. Stops reading even when there is remaining.
+		return nil
+	}
+	if !endHeaders {
+		return s
+	}
+
+	s.mu.Lock()
+	if !s.headerDone {
+		if !endStream && len(hDec.state.mdata) > 0 {
+			s.header = hDec.state.mdata
+		}
+		close(s.headerChan)
+		s.headerDone = true
+	}
+	if !endStream || s.state == streamDone {
+		s.mu.Unlock()
+		return nil
+	}
+
+	if len(hDec.state.mdata) > 0 {
+		s.trailer = hDec.state.mdata
+	}
+	s.state = streamDone
+	s.statusCode = hDec.state.statusCode
+	s.statusDesc = hDec.state.statusDesc
+	s.mu.Unlock()
+
+	s.write(recvMsg{err: io.EOF})
+	return nil
+}
+
+// reader runs as a separate goroutine in charge of reading data from network
+// connection.
+//
+// TODO(zhaoq): currently one reader per transport. Investigate whether this is
+// optimal.
+// TODO(zhaoq): Check the validity of the incoming frame sequence.
+func (t *http2Client) reader() {
+	// Check the validity of server preface.
+	frame, err := t.framer.ReadFrame()
+	if err != nil {
+		t.notifyError()
+		return
+	}
+	sf, ok := frame.(*http2.SettingsFrame)
+	if !ok {
+		t.notifyError()
+		return
+	}
+	t.handleSettings(sf)
+
+	hDec := newHPACKDecoder()
+	var curStream *Stream
+	// loop to keep reading incoming messages on this transport.
+	for {
+		frame, err := t.framer.ReadFrame()
+		if err != nil {
+			t.notifyError()
+			return
+		}
+		switch frame := frame.(type) {
+		case *http2.HeadersFrame:
+			var ok bool
+			if curStream, ok = t.getStream(frame); !ok {
+				continue
+			}
+			endStream := frame.Header().Flags.Has(http2.FlagHeadersEndStream)
+			curStream = t.operateHeaders(hDec, curStream, frame, endStream)
+		case *http2.ContinuationFrame:
+			if curStream == nil {
+				continue
+			}
+			curStream = t.operateHeaders(hDec, curStream, frame, false)
+		case *http2.DataFrame:
+			t.handleData(frame)
+		case *http2.RSTStreamFrame:
+			t.handleRSTStream(frame)
+		case *http2.SettingsFrame:
+			t.handleSettings(frame)
+		case *http2.PingFrame:
+			t.handlePing(frame)
+		case *http2.GoAwayFrame:
+			t.handleGoAway(frame)
+		case *http2.WindowUpdateFrame:
+			t.handleWindowUpdate(frame)
+		default:
+			log.Printf("http2Client: unhandled frame type %v.", frame)
+		}
+	}
+}
+
+// controller running in a separate goroutine takes charge of sending control
+// frames (e.g., window update, reset stream, setting, etc.) to the server.
+func (t *http2Client) controller() {
+	for {
+		select {
+		case i := <-t.controlBuf.get():
+			t.controlBuf.load()
+			select {
+			case <-t.writableChan:
+				switch i := i.(type) {
+				case *windowUpdate:
+					t.framer.WriteWindowUpdate(i.streamID, i.increment)
+				case *settings:
+					t.framer.WriteSettings(http2.Setting{i.id, i.val})
+				case *resetStream:
+					t.framer.WriteRSTStream(i.streamID, i.code)
+				default:
+					log.Printf("http2Client.controller got unexpected item type %v\n", i)
+				}
+				t.writableChan <- 0
+				continue
+			case <-t.shutdownChan:
+				return
+			}
+		case <-t.shutdownChan:
+			return
+		}
+	}
+}
+
+func (t *http2Client) Error() <-chan struct{} {
+	return t.errorChan
+}
+
+func (t *http2Client) notifyError() {
+	t.mu.Lock()
+	defer t.mu.Unlock()
+	// make sure t.errorChan is closed only once.
+	if t.state == reachable {
+		t.state = unreachable
+		close(t.errorChan)
+	}
+}
diff --git a/transport/http2_server_transport.go b/transport/http2_server_transport.go
new file mode 100755
index 00000000..e29e709a
--- /dev/null
+++ b/transport/http2_server_transport.go
@@ -0,0 +1,598 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package transport
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"log"
+	"math"
+	"net"
+	"strconv"
+	"sync"
+
+	"github.com/google/grpc-go/codes"
+	"github.com/google/grpc-go/metadata"
+	"golang.org/x/net/context"
+	"github.com/bradfitz/http2/hpack"
+	"github.com/bradfitz/http2"
+)
+
+// http2Server implements the ServerTransport interface with HTTP2.
+type http2Server struct {
+	conn        net.Conn
+	maxStreamID uint32 // max stream ID ever seen
+	// writableChan synchronizes write access to the transport.
+	// A writer acquires the write lock by sending a value on writableChan
+	// and releases it by receiving from writableChan.
+	writableChan chan int
+	// shutdownChan is closed when Close is called.
+	// Blocking operations should select on shutdownChan to avoid
+	// blocking forever after Close.
+	// TODO(zhaoq): Maybe have a channel context?
+	shutdownChan chan struct{}
+	framer       *http2.Framer
+	hBuf         *bytes.Buffer  // the buffer for HPACK encoding
+	hEnc         *hpack.Encoder // HPACK encoder
+
+	// The max number of concurrent streams.
+	maxStreams uint32
+	// controlBuf delivers all the control related tasks (e.g., window
+	// updates, reset streams, and various settings) to the controller.
+	controlBuf *recvBuffer
+	// sendQuotaPool provides flow control to outbound message.
+	sendQuotaPool *quotaPool
+
+	mu            sync.Mutex
+	state         transportState
+	activeStreams map[uint32]*Stream
+	// Inbound quota for flow control
+	recvQuota int
+}
+
+// newHTTP2Server constructs a ServerTransport based on HTTP2. ConnectionError is
+// returned if something goes wrong.
+func newHTTP2Server(conn net.Conn, maxStreams uint32) (_ ServerTransport, err error) {
+	framer := http2.NewFramer(conn, conn)
+	// Send initial settings as connection preface to client.
+	// TODO(zhaoq): Have a better way to signal "no limit" because 0 is
+	// permitted in the HTTP2 spec.
+	if maxStreams == 0 {
+		err = framer.WriteSettings()
+		maxStreams = math.MaxUint32
+	} else {
+		err = framer.WriteSettings(http2.Setting{http2.SettingMaxConcurrentStreams, maxStreams})
+	}
+	if err != nil {
+		return
+	}
+	var buf bytes.Buffer
+	t := &http2Server{
+		conn:          conn,
+		framer:        framer,
+		hBuf:          &buf,
+		hEnc:          hpack.NewEncoder(&buf),
+		maxStreams:    maxStreams,
+		controlBuf:    newRecvBuffer(),
+		sendQuotaPool: newQuotaPool(initialWindowSize),
+		state:         reachable,
+		writableChan:  make(chan int, 1),
+		shutdownChan:  make(chan struct{}),
+		activeStreams: make(map[uint32]*Stream),
+	}
+	go t.controller()
+	t.writableChan <- 0
+	return t, nil
+}
+
+// operateHeader takes action on the decoded headers. It returns the current
+// stream if there are remaining headers on the wire (in the following
+// Continuation frame).
+func (t *http2Server) operateHeaders(hDec *hpackDecoder, s *Stream, frame headerFrame, endStream bool, handle func(*Stream), wg *sync.WaitGroup) (pendingStream *Stream) {
+	defer func() {
+		if pendingStream == nil {
+			hDec.state = decodeState{}
+		}
+	}()
+	endHeaders, err := hDec.decodeServerHTTP2Headers(s, frame)
+	if err != nil {
+		log.Print(err)
+		if se, ok := err.(StreamError); ok {
+			t.controlBuf.put(&resetStream{s.id, statusCodeConvTab[se.Code]})
+		}
+		return nil
+	}
+	if endStream {
+		// s is just created by the caller. No lock needed.
+		s.state = streamReadDone
+	}
+	if !endHeaders {
+		return s
+	}
+	t.mu.Lock()
+	if t.state != reachable {
+		t.mu.Unlock()
+		return nil
+	}
+	if uint32(len(t.activeStreams)) >= t.maxStreams {
+		t.mu.Unlock()
+		t.controlBuf.put(&resetStream{s.id, http2.ErrCodeRefusedStream})
+		return nil
+	}
+	t.activeStreams[s.id] = s
+	t.mu.Unlock()
+	s.windowHandler = func(n int) {
+		t.addRecvQuota(s, n)
+	}
+	if hDec.state.timeout > 0 {
+		s.ctx, s.cancel = context.WithTimeout(context.TODO(), hDec.state.timeout)
+	} else {
+		s.ctx, s.cancel = context.WithCancel(context.TODO())
+	}
+	// Cache the current stream to the context so that the server application
+	// can find out. Required when the server wants to send some metadata
+	// back to the client (unary call only).
+	s.ctx = newContextWithStream(s.ctx, s)
+	// Attach the received metadata to the context.
+	if len(hDec.state.mdata) > 0 {
+		s.ctx = metadata.NewContext(s.ctx, metadata.New(hDec.state.mdata))
+	}
+
+	s.dec = &recvBufferReader{
+		ctx:  s.ctx,
+		recv: s.buf,
+	}
+	s.method = hDec.state.method
+
+	wg.Add(1)
+	go func() {
+		handle(s)
+		wg.Done()
+	}()
+	return nil
+}
+
+// HandleStreams receives incoming streams using the given handler. This is
+// typically run in a separate goroutine.
+func (t *http2Server) HandleStreams(handle func(*Stream)) {
+	// Check the validity of client preface.
+	preface := make([]byte, len(clientPreface))
+	if _, err := io.ReadFull(t.conn, preface); err != nil {
+		log.Printf("failed to receive the preface from client: %v", err)
+		t.Close()
+		return
+	}
+	if !bytes.Equal(preface, clientPreface) {
+		log.Printf("received bogus greeting from client: %q", preface)
+		t.Close()
+		return
+	}
+
+	frame, err := t.framer.ReadFrame()
+	if err != nil {
+		t.Close()
+		return
+	}
+	sf, ok := frame.(*http2.SettingsFrame)
+	if !ok {
+		log.Printf("invalid preface type %T from client", frame)
+		t.Close()
+		return
+	}
+	t.handleSettings(sf)
+
+	hDec := newHPACKDecoder()
+	var curStream *Stream
+	var wg sync.WaitGroup
+	defer wg.Wait()
+	for {
+		frame, err := t.framer.ReadFrame()
+		if err != nil {
+			t.Close()
+			return
+		}
+		switch frame := frame.(type) {
+		case *http2.HeadersFrame:
+			id := frame.Header().StreamID
+			if id%2 != 1 || id <= t.maxStreamID {
+				// illegal gRPC stream id.
+				log.Println("http2Server: received an illegal stream id: ", id)
+				t.Close()
+				break
+			}
+			t.maxStreamID = id
+			buf := newRecvBuffer()
+			curStream = &Stream{
+				id:            frame.Header().StreamID,
+				st:            t,
+				buf:           buf,
+				sendQuotaPool: newQuotaPool(initialWindowSize),
+			}
+			endStream := frame.Header().Flags.Has(http2.FlagHeadersEndStream)
+			curStream = t.operateHeaders(hDec, curStream, frame, endStream, handle, &wg)
+		case *http2.ContinuationFrame:
+			if curStream == nil {
+				continue
+			}
+			curStream = t.operateHeaders(hDec, curStream, frame, false, handle, &wg)
+		case *http2.DataFrame:
+			t.handleData(frame)
+		case *http2.RSTStreamFrame:
+			t.handleRSTStream(frame)
+		case *http2.SettingsFrame:
+			t.handleSettings(frame)
+		case *http2.PingFrame:
+			t.handlePing(frame)
+		case *http2.WindowUpdateFrame:
+			t.handleWindowUpdate(frame)
+		default:
+			log.Printf("http2Server: unhandled frame type %v.", frame)
+		}
+	}
+}
+
+func (t *http2Server) getStream(f http2.Frame) (*Stream, bool) {
+	t.mu.Lock()
+	defer t.mu.Unlock()
+	if t.activeStreams == nil {
+		// The transport is closing.
+		return nil, false
+	}
+	s, ok := t.activeStreams[f.Header().StreamID]
+	if !ok {
+		// The stream is already done.
+		return nil, false
+	}
+	return s, true
+}
+
+// addRecvQuota adjusts the inbound quota for the stream and the transport.
+// Window updates will deliver to the controller for sending when
+// the cumulative quota exceeds windowUpdateThreshold.
+func (t *http2Server) addRecvQuota(s *Stream, n int) {
+	t.mu.Lock()
+	t.recvQuota += n
+	if t.recvQuota >= windowUpdateThreshold {
+		t.controlBuf.put(&windowUpdate{0, uint32(t.recvQuota)})
+		t.recvQuota = 0
+	}
+	t.mu.Unlock()
+
+	s.recvQuota += n
+	if s.recvQuota >= windowUpdateThreshold {
+		t.controlBuf.put(&windowUpdate{s.id, uint32(s.recvQuota)})
+		s.recvQuota = 0
+	}
+}
+
+func (t *http2Server) handleData(f *http2.DataFrame) {
+	// Select the right stream to dispatch.
+	s, ok := t.getStream(f)
+	if !ok {
+		return
+	}
+	// TODO(bradfitz, zhaoq): A copy is required here because there is no
+	// guarantee f.Data() is consumed before the arrival of next frame.
+	// Can this copy be eliminated?
+	data := make([]byte, len(f.Data()))
+	copy(data, f.Data())
+	s.write(recvMsg{data: data})
+	if f.Header().Flags.Has(http2.FlagDataEndStream) {
+		// Received the end of stream from the client.
+		s.mu.Lock()
+		if s.state != streamDone {
+			if s.state == streamWriteDone {
+				s.state = streamDone
+			} else {
+				s.state = streamReadDone
+			}
+		}
+		s.mu.Unlock()
+		s.write(recvMsg{err: io.EOF})
+	}
+}
+
+func (t *http2Server) handleRSTStream(f *http2.RSTStreamFrame) {
+	s, ok := t.getStream(f)
+	if !ok {
+		return
+	}
+	s.mu.Lock()
+	// Sets the stream state to avoid sending RSTStreamFrame to client
+	// unnecessarily.
+	s.state = streamDone
+	s.mu.Unlock()
+	t.closeStream(s)
+}
+
+func (t *http2Server) handleSettings(f *http2.SettingsFrame) {
+	// TODO(zhaoq): Handle the useful settings from client.
+}
+
+func (t *http2Server) handlePing(f *http2.PingFrame) {
+	log.Println("PingFrame handler to be implemented")
+}
+
+func (t *http2Server) handleWindowUpdate(f *http2.WindowUpdateFrame) {
+	id := f.Header().StreamID
+	incr := f.Increment
+	if id == 0 {
+		t.sendQuotaPool.add(int(incr))
+		return
+	}
+	if s, ok := t.getStream(f); ok {
+		s.sendQuotaPool.add(int(incr))
+	}
+}
+
+func (t *http2Server) writeHeaders(s *Stream, b *bytes.Buffer, endStream bool) error {
+	first := true
+	endHeaders := false
+	var err error
+	// Sends the headers in a single batch.
+	for !endHeaders {
+		size := t.hBuf.Len()
+		if size > http2MaxFrameLen {
+			size = http2MaxFrameLen
+		} else {
+			endHeaders = true
+		}
+		if first {
+			p := http2.HeadersFrameParam{
+				StreamID:      s.id,
+				BlockFragment: b.Next(size),
+				EndStream:     endStream,
+				EndHeaders:    endHeaders,
+			}
+			err = t.framer.WriteHeaders(p)
+			first = false
+		} else {
+			err = t.framer.WriteContinuation(s.id, endHeaders, b.Next(size))
+		}
+		if err != nil {
+			t.Close()
+			return ConnectionErrorf("%v", err)
+		}
+	}
+	return nil
+}
+
+// WriteHeader sends the header metedata md back to the client.
+func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error {
+	s.mu.Lock()
+	if s.headerOk || s.state == streamDone {
+		s.mu.Unlock()
+		return fmt.Errorf("transport: the stream is done or WriteHeader was already called")
+	}
+	s.headerOk = true
+	s.mu.Unlock()
+	if _, err := wait(s.ctx, t.shutdownChan, t.writableChan); err != nil {
+		return err
+	}
+	t.hBuf.Reset()
+	t.hEnc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
+	t.hEnc.WriteField(hpack.HeaderField{Name: "content-type", Value: "application/grpc"})
+	for k, v := range md.Copy() {
+		t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: v})
+	}
+	if err := t.writeHeaders(s, t.hBuf, false); err != nil {
+		return err
+	}
+	t.writableChan <- 0
+	return nil
+}
+
+// WriteStatus sends stream status to the client and terminates the stream.
+// There is no further I/O operations being able to perform on this stream.
+// TODO(zhaoq): Now it indicates the end of entire stream. Revisit if early
+// OK is adopted.
+func (t *http2Server) WriteStatus(s *Stream, statusCode codes.Code, statusDesc string) error {
+	s.mu.RLock()
+	if s.state == streamDone {
+		s.mu.RUnlock()
+		return nil
+	}
+	s.mu.RUnlock()
+	if _, err := wait(s.ctx, t.shutdownChan, t.writableChan); err != nil {
+		return err
+	}
+	t.hBuf.Reset()
+	t.hEnc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
+	t.hEnc.WriteField(
+		hpack.HeaderField{
+			Name:  "grpc-status",
+			Value: strconv.Itoa(int(statusCode)),
+		})
+	t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-message", Value: statusDesc})
+	// Attach the trailer metadata.
+	for k, v := range s.trailer {
+		t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: v})
+	}
+	if err := t.writeHeaders(s, t.hBuf, true); err != nil {
+		return err
+	}
+	t.closeStream(s)
+	t.writableChan <- 0
+	return nil
+}
+
+// Write converts the data into HTTP2 data frame and sends it out. Non-nil error
+// is returns if it fails (e.g., framing error, transport error).
+func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error {
+	// TODO(zhaoq): Support multi-writers for a single stream.
+	var writeHeaderFrame bool
+	s.mu.Lock()
+	if !s.headerOk {
+		writeHeaderFrame = true
+		s.headerOk = true
+	}
+	s.mu.Unlock()
+	if writeHeaderFrame {
+		if _, err := wait(s.ctx, t.shutdownChan, t.writableChan); err != nil {
+			return err
+		}
+		t.hBuf.Reset()
+		t.hEnc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
+		t.hEnc.WriteField(hpack.HeaderField{Name: "content-type", Value: "application/grpc"})
+		p := http2.HeadersFrameParam{
+			StreamID:      s.id,
+			BlockFragment: t.hBuf.Bytes(),
+			EndHeaders:    true,
+		}
+		if err := t.framer.WriteHeaders(p); err != nil {
+			t.Close()
+			return ConnectionErrorf("%v", err)
+		}
+		t.writableChan <- 0
+	}
+	r := bytes.NewBuffer(data)
+	for {
+		if r.Len() == 0 {
+			return nil
+		}
+		size := http2MaxFrameLen
+		s.sendQuotaPool.add(0)
+		// Wait until the stream has some quota to send the data.
+		sq, err := wait(s.ctx, t.shutdownChan, s.sendQuotaPool.acquire())
+		if err != nil {
+			return err
+		}
+		t.sendQuotaPool.add(0)
+		// Wait until the transport has some quota to send the data.
+		tq, err := wait(s.ctx, t.shutdownChan, t.sendQuotaPool.acquire())
+		if err != nil {
+			if _, ok := err.(StreamError); ok {
+				t.sendQuotaPool.cancel()
+			}
+			return err
+		}
+		if sq < size {
+			size = sq
+		}
+		if tq < size {
+			size = tq
+		}
+		p := r.Next(size)
+		ps := len(p)
+		if ps < sq {
+			// Overbooked stream quota. Return it back.
+			s.sendQuotaPool.add(sq - ps)
+		}
+		if ps < tq {
+			// Overbooked transport quota. Return it back.
+			t.sendQuotaPool.add(tq - ps)
+		}
+		// Got some quota. Try to acquire writing privilege on the
+		// transport.
+		if _, err := wait(s.ctx, t.shutdownChan, t.writableChan); err != nil {
+			return err
+		}
+		if err := t.framer.WriteData(s.id, false, p); err != nil {
+			t.Close()
+			return ConnectionErrorf("%v", err)
+		}
+		t.writableChan <- 0
+	}
+
+}
+
+// controller running in a separate goroutine takes charge of sending control
+// frames (e.g., window update, reset stream, setting, etc.) to the server.
+func (t *http2Server) controller() {
+	for {
+		select {
+		case i := <-t.controlBuf.get():
+			t.controlBuf.load()
+			select {
+			case <-t.writableChan:
+				switch i := i.(type) {
+				case *windowUpdate:
+					t.framer.WriteWindowUpdate(i.streamID, i.increment)
+				case *settings:
+					t.framer.WriteSettings(http2.Setting{i.id, i.val})
+				case *resetStream:
+					t.framer.WriteRSTStream(i.streamID, i.code)
+				default:
+					log.Printf("http2Server.controller got unexpected item type %v\n", i)
+				}
+				t.writableChan <- 0
+				continue
+			case <-t.shutdownChan:
+				return
+			}
+		case <-t.shutdownChan:
+			return
+		}
+	}
+}
+
+// Close starts shutting down the http2Server transport.
+// TODO(zhaoq): Now the destruction is not blocked on any pending streams. This
+// could cause some resource issue. Revisit this later.
+func (t *http2Server) Close() {
+	t.mu.Lock()
+	if t.state == closing {
+		t.mu.Unlock()
+		return
+	}
+	t.state = closing
+	streams := t.activeStreams
+	t.activeStreams = nil
+	t.mu.Unlock()
+	close(t.shutdownChan)
+	t.conn.Close()
+	// Notify all active streams.
+	for _, s := range streams {
+		s.write(recvMsg{err: ErrConnClosing})
+	}
+}
+
+// closeStream clears the footprint of a stream when the stream is not needed
+// any more.
+func (t *http2Server) closeStream(s *Stream) {
+	t.mu.Lock()
+	delete(t.activeStreams, s.id)
+	t.mu.Unlock()
+	s.mu.Lock()
+	if s.state == streamDone {
+		return
+	}
+	s.state = streamDone
+	s.mu.Unlock()
+	// In case stream sending and receiving are invoked in separate
+	// goroutines (e.g., bi-directional streaming), the caller needs
+	// to call cancel on the stream to interrupt the blocking on
+	// other goroutines.
+	s.cancel()
+}
diff --git a/transport/http_util.go b/transport/http_util.go
new file mode 100755
index 00000000..ad7f0fc6
--- /dev/null
+++ b/transport/http_util.go
@@ -0,0 +1,288 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package transport
+
+import (
+	"fmt"
+	"log"
+	"strconv"
+	"time"
+
+	"github.com/google/grpc-go/codes"
+	"github.com/google/grpc-go/metadata"
+	"github.com/bradfitz/http2/hpack"
+	"github.com/bradfitz/http2"
+)
+
+const (
+	// http2MaxFrameLen specifies the max length of a HTTP2 frame.
+	http2MaxFrameLen = 16384 // 16KB frame
+	// http://http2.github.io/http2-spec/#SettingValues
+	http2InitHeaderTableSize = 4096
+)
+
+var (
+	clientPreface = []byte(http2.ClientPreface)
+)
+
+var http2RSTErrConvTab = map[http2.ErrCode]codes.Code{
+	http2.ErrCodeNo:                 codes.Internal,
+	http2.ErrCodeProtocol:           codes.Internal,
+	http2.ErrCodeInternal:           codes.Internal,
+	http2.ErrCodeFlowControl:        codes.Internal,
+	http2.ErrCodeSettingsTimeout:    codes.Internal,
+	http2.ErrCodeFrameSize:          codes.Internal,
+	http2.ErrCodeRefusedStream:      codes.Unavailable,
+	http2.ErrCodeCancel:             codes.Canceled,
+	http2.ErrCodeCompression:        codes.Internal,
+	http2.ErrCodeConnect:            codes.Internal,
+	http2.ErrCodeEnhanceYourCalm:    codes.ResourceExhausted,
+	http2.ErrCodeInadequateSecurity: codes.PermissionDenied,
+}
+
+var statusCodeConvTab = map[codes.Code]http2.ErrCode{
+	codes.Internal:          http2.ErrCodeInternal, // pick an arbitrary one which is matched.
+	codes.Canceled:          http2.ErrCodeCancel,
+	codes.Unavailable:       http2.ErrCodeRefusedStream,
+	codes.ResourceExhausted: http2.ErrCodeEnhanceYourCalm,
+	codes.PermissionDenied:  http2.ErrCodeInadequateSecurity,
+}
+
+// Records the states during HPACK decoding. Must be reset once the
+// decoding of the entire headers are finished.
+type decodeState struct {
+	// statusCode caches the stream status received from the trailer
+	// the server sent. Client side only.
+	statusCode codes.Code
+	statusDesc string
+	// Server side only fields.
+	timeout time.Duration
+	method  string
+	// key-value metadata map from the peer.
+	mdata map[string]string
+}
+
+// An hpackDecoder decodes HTTP2 headers which may span multiple frames.
+type hpackDecoder struct {
+	h     *hpack.Decoder
+	state decodeState
+	err   error // The err when decoding
+}
+
+// A headerFrame is either a http2.HeaderFrame or http2.ContinuationFrame.
+type headerFrame interface {
+	Header() http2.FrameHeader
+	HeaderBlockFragment() []byte
+	HeadersEnded() bool
+}
+
+// isReservedHeader checks whether hdr belongs to HTTP2 headers
+// reserved by gRPC protocol. Any other headers are classified as the
+// user-specified metadata.
+func isReservedHeader(hdr string) bool {
+	if hdr[0] == ':' {
+		return true
+	}
+	switch hdr {
+	case "authority",
+		"content-type",
+		"grpc-message-type",
+		"grpc-encoding",
+		"grpc-message",
+		"grpc-status",
+		"grpc-timeout",
+		"te",
+		"user-agent":
+		return true
+	default:
+		return false
+	}
+}
+
+func newHPACKDecoder() *hpackDecoder {
+	d := &hpackDecoder{}
+	d.h = hpack.NewDecoder(http2InitHeaderTableSize, func(f hpack.HeaderField) {
+		switch f.Name {
+		case "grpc-status":
+			code, err := strconv.Atoi(f.Value)
+			if err != nil {
+				d.err = StreamErrorf(codes.Internal, "malformed grpc-status: %v", err)
+				return
+			}
+			d.state.statusCode = codes.Code(code)
+		case "grpc-message":
+			d.state.statusDesc = f.Value
+		case "grpc-timeout":
+			var err error
+			d.state.timeout, err = timeoutDecode(f.Value)
+			if err != nil {
+				d.err = StreamErrorf(codes.Internal, "malformed time-out: %v", err)
+				return
+			}
+		case ":path":
+			d.state.method = f.Value
+		default:
+			if !isReservedHeader(f.Name) {
+				if d.state.mdata == nil {
+					d.state.mdata = make(map[string]string)
+				}
+				k, v, err := metadata.DecodeKeyValue(f.Name, f.Value)
+				if err != nil {
+					log.Printf("Failed to decode (%q, %q): %v", f.Name, f.Value, err)
+					return
+				}
+				d.state.mdata[k] = v
+			}
+		}
+	})
+	return d
+}
+
+func (d *hpackDecoder) decodeClientHTTP2Headers(s *Stream, frame headerFrame) (endHeaders bool, err error) {
+	d.err = nil
+	_, err = d.h.Write(frame.HeaderBlockFragment())
+	if err != nil {
+		err = StreamErrorf(codes.Internal, "HPACK header decode error: %v", err)
+	}
+
+	if frame.HeadersEnded() {
+		if closeErr := d.h.Close(); closeErr != nil && err == nil {
+			err = StreamErrorf(codes.Internal, "HPACK decoder close error: %v", closeErr)
+		}
+		endHeaders = true
+	}
+
+	if err == nil && d.err != nil {
+		err = d.err
+	}
+	return
+}
+
+func (d *hpackDecoder) decodeServerHTTP2Headers(s *Stream, frame headerFrame) (endHeaders bool, err error) {
+	d.err = nil
+	_, err = d.h.Write(frame.HeaderBlockFragment())
+	if err != nil {
+		err = StreamErrorf(codes.Internal, "HPACK header decode error: %v", err)
+	}
+
+	if frame.HeadersEnded() {
+		if closeErr := d.h.Close(); closeErr != nil && err == nil {
+			err = StreamErrorf(codes.Internal, "HPACK decoder close error: %v", closeErr)
+		}
+		endHeaders = true
+	}
+
+	if err == nil && d.err != nil {
+		err = d.err
+	}
+	return
+}
+
+type timeoutUnit uint8
+
+const (
+	hour        timeoutUnit = 'H'
+	minute      timeoutUnit = 'M'
+	second      timeoutUnit = 'S'
+	millisecond timeoutUnit = 'm'
+	microsecond timeoutUnit = 'u'
+	nanosecond  timeoutUnit = 'n'
+)
+
+func timeoutUnitToDuration(u timeoutUnit) (d time.Duration, ok bool) {
+	switch u {
+	case hour:
+		return time.Hour, true
+	case minute:
+		return time.Minute, true
+	case second:
+		return time.Second, true
+	case millisecond:
+		return time.Millisecond, true
+	case microsecond:
+		return time.Microsecond, true
+	case nanosecond:
+		return time.Nanosecond, true
+	default:
+	}
+	return
+}
+
+const maxTimeoutValue int64 = 100000000 - 1
+
+// div does integer division and round-up the result. Note that this is
+// equivalent to (d+r-1)/r but has less chance to overflow.
+func div(d, r time.Duration) int64 {
+	if m := d % r; m > 0 {
+		return int64(d/r + 1)
+	}
+	return int64(d / r)
+}
+
+// TODO(zhaoq): It is the simplistic and not bandwidth efficient. Improve it.
+func timeoutEncode(t time.Duration) string {
+	if d := div(t, time.Nanosecond); d <= maxTimeoutValue {
+		return strconv.FormatInt(d, 10) + "n"
+	}
+	if d := div(t, time.Microsecond); d <= maxTimeoutValue {
+		return strconv.FormatInt(d, 10) + "u"
+	}
+	if d := div(t, time.Millisecond); d <= maxTimeoutValue {
+		return strconv.FormatInt(d, 10) + "m"
+	}
+	if d := div(t, time.Second); d <= maxTimeoutValue {
+		return strconv.FormatInt(d, 10) + "S"
+	}
+	if d := div(t, time.Minute); d <= maxTimeoutValue {
+		return strconv.FormatInt(d, 10) + "M"
+	}
+	// Note that maxTimeoutValue * time.Hour > MaxInt64.
+	return strconv.FormatInt(div(t, time.Hour), 10) + "H"
+}
+
+func timeoutDecode(s string) (time.Duration, error) {
+	size := len(s)
+	if size < 2 {
+		return 0, fmt.Errorf("timeout string is too short: %q", s)
+	}
+	unit := timeoutUnit(s[size-1])
+	d, ok := timeoutUnitToDuration(unit)
+	if !ok {
+		return 0, fmt.Errorf("timeout unit is not recognized: %q", s)
+	}
+	t, err := strconv.ParseInt(s[:size-1], 10, 64)
+	if err != nil {
+		return 0, err
+	}
+	return d * time.Duration(t), nil
+}
diff --git a/transport/http_util_test.go b/transport/http_util_test.go
new file mode 100755
index 00000000..4f763f65
--- /dev/null
+++ b/transport/http_util_test.go
@@ -0,0 +1,86 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package transport
+
+import (
+	"fmt"
+	"testing"
+	"time"
+)
+
+func TestTimeoutEncode(t *testing.T) {
+	for _, test := range []struct {
+		in  string
+		out string
+	}{
+		{"12345678ns", "12345678n"},
+		{"123456789ns", "123457u"},
+		{"12345678us", "12345678u"},
+		{"123456789us", "123457m"},
+		{"12345678ms", "12345678m"},
+		{"123456789ms", "123457S"},
+		{"12345678s", "12345678S"},
+		{"123456789s", "2057614M"},
+		{"12345678m", "12345678M"},
+		{"123456789m", "2057614H"},
+	} {
+		d, err := time.ParseDuration(test.in)
+		if err != nil {
+			t.Fatalf("failed to parse duration string %s: %v", test.in, err)
+		}
+		out := timeoutEncode(d)
+		if out != test.out {
+			t.Fatalf("timeoutEncode(%s) = %s, want %s", test.in, out, test.out)
+		}
+	}
+}
+
+func TestTimeoutDecode(t *testing.T) {
+	for _, test := range []struct {
+		// input
+		s string
+		// output
+		d   time.Duration
+		err error
+	}{
+		{"1234S", time.Second * 1234, nil},
+		{"1234x", 0, fmt.Errorf("timeout unit is not recognized: %q", "1234x")},
+		{"1", 0, fmt.Errorf("timeout string is too short: %q", "1")},
+		{"", 0, fmt.Errorf("timeout string is too short: %q", "")},
+	} {
+		d, err := timeoutDecode(test.s)
+		if d != test.d || fmt.Sprint(err) != fmt.Sprint(test.err) {
+			t.Fatalf("timeoutDecode(%q) = %d, %v, want %d, %v", test.s, int64(d), err, int64(test.d), test.err)
+		}
+	}
+}
diff --git a/transport/testdata/ca.pem b/transport/testdata/ca.pem
new file mode 100644
index 00000000..999da897
--- /dev/null
+++ b/transport/testdata/ca.pem
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICIzCCAYwCCQCFTbF7XNSvvjANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJB
+VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
+cyBQdHkgTHRkMQ8wDQYDVQQDDAZ0ZXN0Y2EwHhcNMTQwNzE3MjMxNzUxWhcNMjQw
+NzE0MjMxNzUxWjBWMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEh
+MB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQ8wDQYDVQQDDAZ0ZXN0
+Y2EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMBA3wVeTGHZR1Rye/i+J8a2
+cu5gXwFV6TnObzGM7bLFCO5i9v4mLo4iFzPsHmWDUxKS3Y8iXbu0eYBlLoNY0lSv
+xDx33O+DuwMmVN+DzSD+Eod9zfvwOWHsazYCZT2PhNxnVWIuJXViY4JAHUGodjx+
+QAi6yCAurUZGvYXGgZSBAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAQoQVD8bwdtWJ
+AniGBwcCfqYyH+/KpA10AcebJVVTyYbYvI9Q8d6RSVu4PZy9OALHR/QrWBdYTAyz
+fNAmc2cmdkSRJzjhIaOstnQy1J+Fk0T9XyvQtq499yFbq9xogUVlEGH62xP6vH0Y
+5ukK//dCPAzA11YuX2rnex0JhuTQfcI=
+-----END CERTIFICATE-----
diff --git a/transport/testdata/server1.key b/transport/testdata/server1.key
new file mode 100644
index 00000000..ed00cd50
--- /dev/null
+++ b/transport/testdata/server1.key
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICWwIBAAKBgQDhwxUnKCwlSaWAwzOB2LSHVegJHv7DDWminTg4wzLLsf+LQ8nZ
+bpjfn5vgIzxCuRh4Rp9QYM5FhfrJX9wcYawP/HTbJ7p7LVQO2QYAP+akMTHxgKuM
+BzVV++3wWToKfVZUjFX8nfTfGMGwWAHJDnlEGnU4tl9UujoCV4ENJtzFoQIDAQAB
+AoGAJ+6hpzNr24yTQZtFWQpDpEyFplddKJMOxDya3S9ppK3vTWrIITV2xNcucw7I
+ceTbdyrGsyjsU0/HdCcIf9ym2jfmGLUwmyhltKVw0QYcFB0XLkc0nI5YvEYoeVDg
+omZIXn1E3EW+sSIWSbkMu9bY2kstKXR2UZmMgWDtmBEPMaECQQD6yT4TAZM5hGBb
+ciBKgMUP6PwOhPhOMPIvijO50Aiu6iuCV88l1QIy38gWVhxjNrq6P346j4IBg+kB
+9alwpCODAkEA5nSnm9k6ykYeQWNS0fNWiRinCdl23A7usDGSuKKlm019iomJ/Rgd
+MKDOp0q/2OostbteOWM2MRFf4jMH3wyVCwJAfAdjJ8szoNKTRSagSbh9vWygnB2v
+IByc6l4TTuZQJRGzCveafz9lovuB3WohCABdQRd9ukCXL2CpsEpqzkafOQJAJUjc
+USedDlq3zGZwYM1Yw8d8RuirBUFZNqJelYai+nRYClDkRVFgb5yksoYycbq5TxGo
+VeqKOvgPpj4RWPHlLwJAGUMk3bqT91xBUCnLRs/vfoCpHpg6eywQTBDAV6xkyz4a
+RH3I7/+yj3ZxR2JoWHgUwZ7lZk1VnhffFye7SBXyag==
+-----END RSA PRIVATE KEY-----
diff --git a/transport/testdata/server1.pem b/transport/testdata/server1.pem
new file mode 100644
index 00000000..8e582e57
--- /dev/null
+++ b/transport/testdata/server1.pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIICmzCCAgSgAwIBAgIBAzANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJBVTET
+MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ
+dHkgTHRkMQ8wDQYDVQQDDAZ0ZXN0Y2EwHhcNMTQwNzIyMDYwMDU3WhcNMjQwNzE5
+MDYwMDU3WjBkMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
+BAcTB0NoaWNhZ28xFDASBgNVBAoTC0dvb2dsZSBJbmMuMRowGAYDVQQDFBEqLnRl
+c3QuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4cMVJygs
+JUmlgMMzgdi0h1XoCR7+ww1pop04OMMyy7H/i0PJ2W6Y35+b4CM8QrkYeEafUGDO
+RYX6yV/cHGGsD/x02ye6ey1UDtkGAD/mpDEx8YCrjAc1Vfvt8Fk6Cn1WVIxV/J30
+3xjBsFgByQ55RBp1OLZfVLo6AleBDSbcxaECAwEAAaNrMGkwCQYDVR0TBAIwADAL
+BgNVHQ8EBAMCBeAwTwYDVR0RBEgwRoIQKi50ZXN0Lmdvb2dsZS5mcoIYd2F0ZXJ6
+b29pLnRlc3QuZ29vZ2xlLmJlghIqLnRlc3QueW91dHViZS5jb22HBMCoAQMwDQYJ
+KoZIhvcNAQEFBQADgYEAM2Ii0LgTGbJ1j4oqX9bxVcxm+/R5Yf8oi0aZqTJlnLYS
+wXcBykxTx181s7WyfJ49WwrYXo78zTDAnf1ma0fPq3e4mpspvyndLh1a+OarHa1e
+aT0DIIYk7qeEa1YcVljx2KyLd0r1BBAfrwyGaEPVeJQVYWaOJRU2we/KD4ojf9s=
+-----END CERTIFICATE-----
diff --git a/transport/transport.go b/transport/transport.go
new file mode 100755
index 00000000..2b648265
--- /dev/null
+++ b/transport/transport.go
@@ -0,0 +1,437 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/*
+Package transport defines and implements message oriented communication channel
+to complete various transactions (e.g., an RPC).
+*/
+package transport
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"net"
+	"sync"
+
+	"github.com/google/grpc-go/codes"
+	"github.com/google/grpc-go/credentials"
+	"github.com/google/grpc-go/metadata"
+	"golang.org/x/net/context"
+)
+
+// recvMsg represents the received msg from the transport. All transport
+// protocol specific info has been removed.
+type recvMsg struct {
+	data []byte
+	// nil: received some data
+	// io.EOF: stream is completed. data is nil.
+	// other non-nil error: transport failure. data is nil.
+	err error
+}
+
+func (recvMsg) isItem() bool {
+	return true
+}
+
+// All items in an out of a recvBuffer should be the same type.
+type item interface {
+	isItem() bool
+}
+
+// recvBuffer is an unbounded channel of item.
+type recvBuffer struct {
+	c       chan item
+	mu      sync.Mutex
+	backlog []item
+}
+
+func newRecvBuffer() *recvBuffer {
+	b := &recvBuffer{
+		c: make(chan item, 1),
+	}
+	return b
+}
+
+func (b *recvBuffer) put(r item) {
+	b.mu.Lock()
+	defer b.mu.Unlock()
+	b.backlog = append(b.backlog, r)
+	select {
+	case b.c <- b.backlog[0]:
+		b.backlog = b.backlog[1:]
+	default:
+	}
+}
+
+func (b *recvBuffer) load() {
+	b.mu.Lock()
+	defer b.mu.Unlock()
+	if len(b.backlog) > 0 {
+		select {
+		case b.c <- b.backlog[0]:
+			b.backlog = b.backlog[1:]
+		default:
+		}
+	}
+}
+
+// get returns the channel that receives an item in the buffer.
+//
+// Upon receipt of an item, the caller should call load to send another
+// item onto the channel if there is any.
+func (b *recvBuffer) get() <-chan item {
+	return b.c
+}
+
+// recvBufferReader implements io.Reader interface to read the data from
+// recvBuffer.
+type recvBufferReader struct {
+	ctx  context.Context
+	recv *recvBuffer
+	last *bytes.Reader // Stores the remaining data in the previous calls.
+	err  error
+}
+
+// Read reads the next len(p) bytes from last. If last is drained, it tries to
+// read additional data from recv. It blocks if there no additional data available
+// in recv. If Read returns any non-nil error, it will continue to return that error.
+func (r *recvBufferReader) Read(p []byte) (n int, err error) {
+	if r.err != nil {
+		return 0, r.err
+	}
+	defer func() { r.err = err }()
+	if r.last != nil && r.last.Len() > 0 {
+		// Read remaining data left in last call.
+		return r.last.Read(p)
+	}
+	select {
+	case <-r.ctx.Done():
+		return 0, ContextErr(r.ctx.Err())
+	case i := <-r.recv.get():
+		r.recv.load()
+		m := i.(*recvMsg)
+		if m.err != nil {
+			return 0, m.err
+		}
+		r.last = bytes.NewReader(m.data)
+		return r.last.Read(p)
+	}
+}
+
+type streamState uint8
+
+const (
+	streamActive    streamState = iota
+	streamWriteDone             // EndStream sent
+	streamReadDone              // EndStream received
+	streamDone                  // sendDone and recvDone or RSTStreamFrame is sent or received.
+)
+
+// Stream represents an RPC in the transport layer.
+type Stream struct {
+	id uint32
+	// nil for client side Stream.
+	st ServerTransport
+	// ctx is the associated context of the stream.
+	ctx    context.Context
+	cancel context.CancelFunc
+	// method records the associated RPC method of the stream.
+	method string
+	buf    *recvBuffer
+	dec    io.Reader
+
+	// Inbound quota for flow control
+	recvQuota int
+	// The handler to control the window update procedure for both this
+	// particular stream and the associated transport.
+	windowHandler func(int)
+
+	sendQuotaPool *quotaPool
+	// Close headerChan to indicate the end of reception of header metadata.
+	headerChan chan struct{}
+	// header caches the received header metadata.
+	header map[string]string
+	// The key-value map of trailer metadata.
+	trailer map[string]string
+
+	mu sync.RWMutex
+	// headerOK becomes true from the first header is about to send.
+	headerOk bool
+	state    streamState
+	// true iff headerChan is closed. Used to avoid closing headerChan
+	// multiple times.
+	headerDone bool
+	// the status received from the server.
+	statusCode codes.Code
+	statusDesc string
+}
+
+// Header acquires the key-value pairs of header metadata once it
+// is available. It blocks until i) the metadata is ready or ii) there is no
+// header metadata or iii) the stream is cancelled/expired.
+func (s *Stream) Header() (map[string]string, error) {
+	select {
+	case <-s.ctx.Done():
+		return nil, ContextErr(s.ctx.Err())
+	case <-s.headerChan:
+		return s.header, nil
+	}
+}
+
+// Trailer returns the cached trailer metedata. Note that if it is not called
+// after the entire stream is done, it could return an empty MD. Client
+// side only.
+func (s *Stream) Trailer() metadata.MD {
+	s.mu.RLock()
+	defer s.mu.RUnlock()
+	return metadata.New(s.trailer)
+}
+
+// ServerTransport returns the underlying ServerTransport for the stream.
+// The client side stream always returns nil.
+func (s *Stream) ServerTransport() ServerTransport {
+	return s.st
+}
+
+// Context returns the context of the stream.
+func (s *Stream) Context() context.Context {
+	return s.ctx
+}
+
+// Method returns the method for the stream.
+func (s *Stream) Method() string {
+	return s.method
+}
+
+// StatusCode returns statusCode received from the server.
+func (s *Stream) StatusCode() codes.Code {
+	return s.statusCode
+}
+
+// StatusDesc returns statusDesc received from the server.
+func (s *Stream) StatusDesc() string {
+	return s.statusDesc
+}
+
+// SetTrailer sets the trailer metadata which will be sent with the RPC status
+// by the server. This can only be called at most once. Server side only.
+func (s *Stream) SetTrailer(md metadata.MD) error {
+	s.mu.Lock()
+	defer s.mu.Unlock()
+	if s.trailer != nil {
+		return fmt.Errorf("transport: Trailer has been set")
+	}
+	s.trailer = md.Copy()
+	return nil
+}
+
+func (s *Stream) write(m recvMsg) {
+	s.buf.put(&m)
+}
+
+// Read reads all the data available for this Stream from the transport and
+// passes them into the decoder, which converts them into a gRPC message stream.
+// The error is io.EOF when the stream is done or another non-nil error if
+// the stream broke.
+func (s *Stream) Read(p []byte) (n int, err error) {
+	n, err = s.dec.Read(p)
+	if err != nil {
+		return
+	}
+	s.windowHandler(n)
+	return
+}
+
+type key int
+
+// The key to save transport.Stream in the context.
+const streamKey = key(0)
+
+// newContextWithStream creates a new context from ctx and attaches stream
+// to it.
+func newContextWithStream(ctx context.Context, stream *Stream) context.Context {
+	return context.WithValue(ctx, streamKey, stream)
+}
+
+// StreamFromContext returns the stream saved in ctx.
+func StreamFromContext(ctx context.Context) (s *Stream, ok bool) {
+	s, ok = ctx.Value(streamKey).(*Stream)
+	return
+}
+
+// state of transport
+type transportState int
+
+const (
+	reachable transportState = iota
+	unreachable
+	closing
+)
+
+// NewServerTransport creates a ServerTransport with conn or non-nil error
+// if it fails.
+func NewServerTransport(protocol string, conn net.Conn, maxStreams uint32) (ServerTransport, error) {
+	return newHTTP2Server(conn, maxStreams)
+}
+
+// NewClientTransport establishes the transport with the required protocol
+// and returns it to the caller.
+func NewClientTransport(protocol, target string, authOpts []credentials.Credentials) (ClientTransport, error) {
+	return newHTTP2Client(target, authOpts)
+}
+
+// Options provides additional hints and information for message
+// transmission.
+type Options struct {
+	// Indicate whether it is the last piece for this stream.
+	Last bool
+	// The hint to transport impl whether the data could be buffered for
+	// batching write. Transport impl can feel free to ignore it.
+	Delay bool
+}
+
+// CallHdr carries the metadata from client to server.
+type CallHdr struct {
+	Host   string // peer host
+	Method string // the operation to perform on the specified host
+}
+
+// ClientTransport is the common interface for all gRPC client side transport
+// implementations.
+type ClientTransport interface {
+	// Close tears down this transport. Once it returns, the transport
+	// should not be accessed any more. The caller must make sure this
+	// is called only once.
+	Close()
+
+	// Write sends the data for the given stream. A nil stream indicates
+	// the write is to be performed on the transport as a whole.
+	Write(s *Stream, data []byte, opts *Options) error
+
+	// NewStream creates a Stream for an RPC.
+	NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, error)
+
+	// CloseStream clears the footprint of a stream when the stream is
+	// not needed any more. The err indicates the error incurred when
+	// CloseStream is called. Must be called when a stream is finished
+	// unless the associated transport is closing.
+	CloseStream(stream *Stream, err error)
+
+	// Error returns a channel that is closed when some I/O error
+	// happens. Typically the caller should have a goroutine to monitor
+	// this in order to take action (e.g., close the current transport
+	// and create a new one) in error case. It should not return nil
+	// once the transport is initiated.
+	Error() <-chan struct{}
+}
+
+// ServerTransport is the common interface for all gRPC server side transport
+// implementations.
+type ServerTransport interface {
+	// WriteStatus sends the status of a stream to the client.
+	WriteStatus(s *Stream, statusCode codes.Code, statusDesc string) error
+	// Write sends the data for the given stream.
+	Write(s *Stream, data []byte, opts *Options) error
+	// WriteHeader sends the header metedata for the given stream.
+	WriteHeader(s *Stream, md metadata.MD) error
+	// HandleStreams receives incoming streams using the given handler.
+	HandleStreams(func(*Stream))
+	// Close tears down the transport. Once it is called, the transport
+	// should not be accessed any more. All the pending streams and their
+	// handlers will be terminated asynchronously.
+	Close()
+}
+
+// StreamErrorf creates an StreamError with the specified error code and description.
+func StreamErrorf(c codes.Code, format string, a ...interface{}) StreamError {
+	return StreamError{
+		Code: c,
+		Desc: fmt.Sprintf(format, a...),
+	}
+}
+
+// ConnectionErrorf creates an ConnectionError with the specified error description.
+func ConnectionErrorf(format string, a ...interface{}) ConnectionError {
+	return ConnectionError{
+		Desc: fmt.Sprintf(format, a...),
+	}
+}
+
+// ConnectionError is an error that results in the termination of the
+// entire connection and the retry of all the active streams.
+type ConnectionError struct {
+	Desc string
+}
+
+func (e ConnectionError) Error() string {
+	return fmt.Sprintf("connection error: desc = %q", e.Desc)
+}
+
+// Define some common ConnectionErrors.
+var ErrConnClosing = ConnectionError{Desc: "transport is closing"}
+
+// StreamError is an error that only affects one stream within a connection.
+type StreamError struct {
+	Code codes.Code
+	Desc string
+}
+
+func (e StreamError) Error() string {
+	return fmt.Sprintf("stream error: code = %d desc = %q", e.Code, e.Desc)
+}
+
+// ContextErr converts the error from context package into a StreamError.
+func ContextErr(err error) StreamError {
+	switch err {
+	case context.DeadlineExceeded:
+		return StreamErrorf(codes.DeadlineExceeded, "%v", err)
+	case context.Canceled:
+		return StreamErrorf(codes.Canceled, "%v", err)
+	}
+	panic(fmt.Sprintf("Unexpected error from context packet: %v", err))
+}
+
+// wait blocks until it can receive from ctx.Done, closing, or proceed.
+// If it receives from ctx.Done, it returns 0, the StreamError for ctx.Err.
+// If it receives from closing, it returns 0, ErrConnClosing.
+// If it receives from proceed, it returns the received integer, nil.
+func wait(ctx context.Context, closing <-chan struct{}, proceed <-chan int) (int, error) {
+	select {
+	case <-ctx.Done():
+		return 0, ContextErr(ctx.Err())
+	case <-closing:
+		return 0, ErrConnClosing
+	case i := <-proceed:
+		return i, nil
+	}
+}
diff --git a/transport/transport_test.go b/transport/transport_test.go
new file mode 100755
index 00000000..2f4d70d6
--- /dev/null
+++ b/transport/transport_test.go
@@ -0,0 +1,407 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+package transport
+
+import (
+	"bytes"
+	"io"
+	"log"
+	"math"
+	"net"
+	"reflect"
+	"strconv"
+	"sync"
+	"testing"
+	"time"
+
+	"github.com/google/grpc-go/codes"
+	"github.com/google/grpc-go/credentials"
+	"golang.org/x/net/context"
+)
+
+type server struct {
+	lis  net.Listener
+	port string
+	// channel to signal server is ready to serve.
+	readyChan chan bool
+	mu        sync.Mutex
+	conns     map[ServerTransport]bool
+}
+
+var (
+	tlsDir                = "testdata/"
+	expectedRequest       = []byte("ping")
+	expectedResponse      = []byte("pong")
+	expectedRequestLarge  = make([]byte, initialWindowSize*2)
+	expectedResponseLarge = make([]byte, initialWindowSize*2)
+)
+
+type testStreamHandler struct {
+	t ServerTransport
+}
+
+func (h *testStreamHandler) handleStream(s *Stream) {
+	req := expectedRequest
+	resp := expectedResponse
+	if s.Method() == "foo.Large" {
+		req = expectedRequestLarge
+		resp = expectedResponseLarge
+	}
+	p := make([]byte, len(req))
+	_, err := io.ReadFull(s, p)
+	if err != nil || !bytes.Equal(p, req) {
+		if err == ErrConnClosing {
+			return
+		}
+		log.Fatalf("handleStream got error: %v, want <nil>; result: %v, want %v", err, p, req)
+	}
+	// send a response back to the client.
+	h.t.Write(s, resp, &Options{})
+	// send the trailer to end the stream.
+	h.t.WriteStatus(s, codes.OK, "")
+}
+
+// handleStreamSuspension blocks until s.ctx is canceled.
+func (h *testStreamHandler) handleStreamSuspension(s *Stream) {
+	<-s.ctx.Done()
+}
+
+func (s *server) Start(useTLS bool, port int, maxStreams uint32, suspend bool) {
+	var err error
+	if port == 0 {
+		s.lis, err = net.Listen("tcp", ":0")
+	} else {
+		s.lis, err = net.Listen("tcp", ":"+strconv.Itoa(port))
+	}
+	if err != nil {
+		log.Fatalf("failed to listen: %v", err)
+	}
+	if useTLS {
+		creds, err := credentials.NewServerTLSFromFile(tlsDir+"server1.pem", tlsDir+"server1.key")
+		if err != nil {
+			log.Fatalf("Failed to generate credentials %v", err)
+		}
+		s.lis = creds.NewListener(s.lis)
+	}
+	_, p, err := net.SplitHostPort(s.lis.Addr().String())
+	if err != nil {
+		log.Fatalf("failed to parse listener address: %v", err)
+	}
+	s.port = p
+	if s.readyChan != nil {
+		close(s.readyChan)
+	}
+	s.conns = make(map[ServerTransport]bool)
+	for {
+		conn, err := s.lis.Accept()
+		if err != nil {
+			return
+		}
+		t, err := NewServerTransport("http2", conn, maxStreams)
+		if err != nil {
+			return
+		}
+		s.mu.Lock()
+		if s.conns == nil {
+			s.mu.Unlock()
+			t.Close()
+			return
+		}
+		s.conns[t] = true
+		s.mu.Unlock()
+		h := &testStreamHandler{t}
+		if suspend {
+			go t.HandleStreams(h.handleStreamSuspension)
+		} else {
+			go t.HandleStreams(h.handleStream)
+		}
+	}
+}
+
+func (s *server) Wait(t *testing.T, timeout time.Duration) {
+	select {
+	case <-s.readyChan:
+	case <-time.After(timeout):
+		t.Fatalf("Timed out after %v waiting for server to be ready", timeout)
+	}
+}
+
+func (s *server) Close() {
+	s.lis.Close()
+	s.mu.Lock()
+	for c := range s.conns {
+		c.Close()
+	}
+	s.conns = nil
+	s.mu.Unlock()
+}
+
+func setUp(t *testing.T, useTLS bool, port int, maxStreams uint32, suspend bool) (*server, ClientTransport) {
+	server := &server{readyChan: make(chan bool)}
+	go server.Start(useTLS, port, maxStreams, suspend)
+	server.Wait(t, 2*time.Second)
+	addr := "localhost:" + server.port
+	var (
+		ct      ClientTransport
+		connErr error
+	)
+	if useTLS {
+		creds, err := credentials.NewClientTLSFromFile(tlsDir+"ca.pem", "x.test.youtube.com")
+		if err != nil {
+			t.Fatalf("Failed to create credentials %v", err)
+		}
+		ct, connErr = NewClientTransport("http2", addr, []credentials.Credentials{creds})
+	} else {
+		ct, connErr = NewClientTransport("http2", addr, nil)
+	}
+	if connErr != nil {
+		t.Fatalf("failed to create transport: %v", connErr)
+	}
+	return server, ct
+}
+
+func TestClientSendAndReceive(t *testing.T) {
+	server, ct := setUp(t, true, 0, math.MaxUint32, false)
+	callHdr := &CallHdr{
+		Host:   "localhost",
+		Method: "foo.Small",
+	}
+	s1, err1 := ct.NewStream(context.Background(), callHdr)
+	if err1 != nil {
+		t.Fatalf("failed to open stream: %v", err1)
+	}
+	if s1.id != 1 {
+		t.Fatalf("wrong stream id: %d", s1.id)
+	}
+	s2, err2 := ct.NewStream(context.Background(), callHdr)
+	if err2 != nil {
+		t.Fatalf("failed to open stream: %v", err2)
+	}
+	if s2.id != 3 {
+		t.Fatalf("wrong stream id: %d", s2.id)
+	}
+	opts := Options{
+		Last:  true,
+		Delay: false,
+	}
+	if err := ct.Write(s1, expectedRequest, &opts); err != nil {
+		t.Fatalf("failed to send data: %v", err)
+	}
+	p := make([]byte, len(expectedResponse))
+	_, recvErr := io.ReadFull(s1, p)
+	if recvErr != nil || !bytes.Equal(p, expectedResponse) {
+		t.Fatalf("Error: %v, want <nil>; Result: %v, want %v", recvErr, p, expectedResponse)
+	}
+	_, recvErr = io.ReadFull(s1, p)
+	if recvErr != io.EOF {
+		t.Fatalf("Error: %v; want <EOF>", recvErr)
+	}
+	ct.Close()
+	server.Close()
+}
+
+func TestClientErrorNotify(t *testing.T) {
+	server, ct := setUp(t, true, 0, math.MaxUint32, false)
+	callHdr := &CallHdr{
+		Host:   "localhost",
+		Method: "foo.Small",
+	}
+	s, err := ct.NewStream(context.Background(), callHdr)
+	if err != nil {
+		t.Fatalf("failed to open stream: %v", err)
+	}
+	if s.id != 1 {
+		t.Fatalf("wrong stream id: %d", s.id)
+	}
+	// Tear down the server.
+	go server.Close()
+	// ct.reader should detect the error and activate ct.Error().
+	<-ct.Error()
+	ct.Close()
+}
+
+func performOneRPC(ct ClientTransport) {
+	callHdr := &CallHdr{
+		Host:   "localhost",
+		Method: "foo.Small",
+	}
+	s, err := ct.NewStream(context.Background(), callHdr)
+	if err != nil {
+		log.Printf("failed to open stream: %v", err)
+		return
+	}
+	opts := Options{
+		Last:  true,
+		Delay: false,
+	}
+	if err := ct.Write(s, expectedRequest, &opts); err == nil {
+		time.Sleep(5 * time.Millisecond)
+		// The following s.Recv()'s could error out because the
+		// underlying transport is gone.
+		//
+		// Read response
+		p := make([]byte, len(expectedResponse))
+		io.ReadFull(s, p)
+		// Read io.EOF
+		io.ReadFull(s, p)
+	}
+}
+
+func TestClientMix(t *testing.T) {
+	s, ct := setUp(t, true, 0, math.MaxUint32, false)
+	go func(s *server) {
+		time.Sleep(5 * time.Second)
+		s.Close()
+	}(s)
+	go func(t ClientTransport) {
+		<-ct.Error()
+		ct.Close()
+	}(ct)
+	for i := 0; i < 1000; i++ {
+		time.Sleep(10 * time.Millisecond)
+		go performOneRPC(ct)
+	}
+}
+
+func TestExceedMaxStreamsLimit(t *testing.T) {
+	server, ct := setUp(t, true, 0, 1, false)
+	defer func() {
+		ct.Close()
+		server.Close()
+	}()
+	callHdr := &CallHdr{
+		Host:   "localhost",
+		Method: "foo.Small",
+	}
+	// Creates the 1st stream and keep it alive.
+	_, err1 := ct.NewStream(context.Background(), callHdr)
+	if err1 != nil {
+		t.Fatalf("failed to open stream: %v", err1)
+	}
+	// Creates the 2nd stream. It has chance to succeed when the settings
+	// frame from the server has not received at the client.
+	s, err2 := ct.NewStream(context.Background(), callHdr)
+	if err2 != nil {
+		se, ok := err2.(StreamError)
+		if !ok {
+			t.Fatalf("Received unexpected error %v", err2)
+		}
+		if se.Code != codes.Unavailable {
+			t.Fatalf("Got error code: %d, want: %d", se.Code, codes.Unavailable)
+		}
+		return
+	}
+	// If the 2nd stream is created successfully, sends the request.
+	if err := ct.Write(s, expectedRequest, &Options{Last: true, Delay: false}); err != nil {
+		t.Fatalf("failed to send data: %v", err)
+	}
+	// The 2nd stream was rejected by the server via a reset.
+	p := make([]byte, len(expectedResponse))
+	_, recvErr := io.ReadFull(s, p)
+	if recvErr != io.EOF || s.StatusCode() != codes.Unavailable {
+		t.Fatalf("Error: %v, StatusCode: %d; want <EOF>, %d", recvErr, s.StatusCode(), codes.Unavailable)
+	}
+	// Server's setting has been received. From now on, new stream will be rejected instantly.
+	_, err3 := ct.NewStream(context.Background(), callHdr)
+	if err3 == nil {
+		t.Fatalf("Received unexpected <nil>, want an error with code %d", codes.Unavailable)
+	}
+	if se, ok := err3.(StreamError); !ok || se.Code != codes.Unavailable {
+		t.Fatalf("Got: %v, want a StreamError with error code %d", err3, codes.Unavailable)
+	}
+}
+
+func TestLargeMessage(t *testing.T) {
+	server, ct := setUp(t, true, 0, math.MaxUint32, false)
+	callHdr := &CallHdr{
+		Host:   "localhost",
+		Method: "foo.Large",
+	}
+	var wg sync.WaitGroup
+	for i := 0; i < 2; i++ {
+		wg.Add(1)
+		go func() {
+			s, err := ct.NewStream(context.Background(), callHdr)
+			if err != nil {
+				t.Fatalf("failed to open stream: %v", err)
+			}
+			if err := ct.Write(s, expectedRequestLarge, &Options{Last: true, Delay: false}); err != nil {
+				t.Fatalf("failed to send data: %v", err)
+			}
+			p := make([]byte, len(expectedResponseLarge))
+			_, recvErr := io.ReadFull(s, p)
+			if recvErr != nil || !bytes.Equal(p, expectedResponseLarge) {
+				t.Fatalf("Error: %v, want <nil>; Result len: %d, want len %d", recvErr, len(p), len(expectedResponseLarge))
+			}
+			_, recvErr = io.ReadFull(s, p)
+			if recvErr != io.EOF {
+				t.Fatalf("Error: %v; want <EOF>", recvErr)
+			}
+			wg.Done()
+		}()
+	}
+	wg.Wait()
+	ct.Close()
+	server.Close()
+}
+
+func TestLargeMessageSuspension(t *testing.T) {
+	server, ct := setUp(t, true, 0, math.MaxUint32, true)
+	callHdr := &CallHdr{
+		Host:   "localhost",
+		Method: "foo.Large",
+	}
+	// Set a long enough timeout for writing a large message out.
+	ctx, _ := context.WithTimeout(context.Background(), time.Second)
+	s, err := ct.NewStream(ctx, callHdr)
+	if err != nil {
+		t.Fatalf("failed to open stream: %v", err)
+	}
+	// Write should not be done successfully due to flow control.
+	err = ct.Write(s, expectedRequestLarge, &Options{Last: true, Delay: false})
+	expectedErr := StreamErrorf(codes.DeadlineExceeded, "%v", context.DeadlineExceeded)
+	if err == nil || err != expectedErr {
+		t.Fatalf("Write got %v, want %v", err, expectedErr)
+	}
+	ct.Close()
+	server.Close()
+}
+
+func TestStreamContext(t *testing.T) {
+	expectedStream := Stream{}
+	ctx := newContextWithStream(context.Background(), &expectedStream)
+	s, ok := StreamFromContext(ctx)
+	if !ok || !reflect.DeepEqual(expectedStream, *s) {
+		t.Fatalf("GetStreamFromContext(%v) = %v, %t, want: %v, true", ctx, *s, ok, expectedStream)
+	}
+}

From 7e77699bea4463aa21096248fa47e5cec79a076c Mon Sep 17 00:00:00 2001
From: Qi Zhao <toqizhao@gmail.com>
Date: Fri, 16 Jan 2015 17:41:59 -0800
Subject: [PATCH 03/44] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 32968848..e6d7bcc1 100644
--- a/README.md
+++ b/README.md
@@ -1 +1 @@
-This is the README
+gRPC-Go: The Google opensource RPC library in golang.

From 55563713b20e51dd2e08c719eb5819e0a6d270ce Mon Sep 17 00:00:00 2001
From: Qi Zhao <toqizhao@gmail.com>
Date: Mon, 19 Jan 2015 17:06:15 -0800
Subject: [PATCH 04/44] add installation instruction to README.md

---
 README.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/README.md b/README.md
index e6d7bcc1..d3e372f5 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,5 @@
 gRPC-Go: The Google opensource RPC library in golang.
+
+To install this package, you need to install Go 1.4 and setup your Go worksapce on your computer. The simplest way to install the grpc package is to run:
+
+go get github.com/google/grpc-go

From cafb588ebe286779f5372922f7f4f66a3d71b7d9 Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Wed, 21 Jan 2015 16:00:47 -0800
Subject: [PATCH 05/44] Added grpc codegen

---
 compiler/Makefile        |  18 ++
 compiler/gen.sh          |  10 +
 compiler/go_generator.cc | 531 +++++++++++++++++++++++++++++++++++++++
 compiler/go_generator.h  |  51 ++++
 compiler/go_plugin.cc    |  84 +++++++
 5 files changed, 694 insertions(+)
 create mode 100644 compiler/Makefile
 create mode 100755 compiler/gen.sh
 create mode 100644 compiler/go_generator.cc
 create mode 100644 compiler/go_generator.h
 create mode 100644 compiler/go_plugin.cc

diff --git a/compiler/Makefile b/compiler/Makefile
new file mode 100644
index 00000000..b07ecdb6
--- /dev/null
+++ b/compiler/Makefile
@@ -0,0 +1,18 @@
+CC=g++
+CFLAGS=-c -Wall `pkg-config --cflags protobuf` -std=c++11
+LDFLAGS=-g
+LDLIBS=`pkg-config --libs protobuf` -lprotoc
+SOURCES=go_generator.cc go_plugin.cc
+OBJECTS=$(SOURCES:.cc=.o)
+EXECUTABLE=go_plugin
+
+all: $(EXECUTABLE)
+
+$(EXECUTABLE): $(OBJECTS)
+	$(CC) $(LDFLAGS) $(OBJECTS) -o $@ $(LDLIBS)
+
+.cc.o:
+	$(CC) $(CFLAGS) $< -o $@
+
+clean:
+	$(RM) $(OBJECTS) $(EXECUTABLE)
diff --git a/compiler/gen.sh b/compiler/gen.sh
new file mode 100755
index 00000000..13fc58b4
--- /dev/null
+++ b/compiler/gen.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+# Please run this under the same directory where the input proto stays. The
+# output will stay in the same directory. If this is not the behavior you want,
+# feel free to make your own scripts.
+locProtocGenGo=$1
+locGoPlugIn=$2
+proto=$3
+protoc --plugin=protoc-gen-go=$locProtocGenGo --go_out=. $proto
+protoc --plugin=protoc-gen-gogrpc=$locGoPlugIn --gogrpc_out=. $proto
diff --git a/compiler/go_generator.cc b/compiler/go_generator.cc
new file mode 100644
index 00000000..1f990c5b
--- /dev/null
+++ b/compiler/go_generator.cc
@@ -0,0 +1,531 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "./go_generator.h"
+
+#include <cctype>
+
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor.h>
+
+using namespace std;
+
+namespace grpc_go_generator {
+
+bool NoStreaming(const google::protobuf::MethodDescriptor* method) {
+  return !method->client_streaming() && !method->server_streaming();
+}
+
+bool ClientOnlyStreaming(const google::protobuf::MethodDescriptor* method) {
+  return method->client_streaming() && !method->server_streaming();
+}
+
+bool ServerOnlyStreaming(const google::protobuf::MethodDescriptor* method) {
+  return !method->client_streaming() && method->server_streaming();
+}
+
+bool BidiStreaming(const google::protobuf::MethodDescriptor* method) {
+  return method->client_streaming() && method->server_streaming();
+}
+
+bool HasClientOnlyStreaming(const google::protobuf::FileDescriptor* file) {
+  for (int i = 0; i < file->service_count(); i++) {
+    for (int j = 0; j < file->service(i)->method_count(); j++) {
+      if (ClientOnlyStreaming(file->service(i)->method(j))) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+string LowerCaseService(const string& service) {
+  string ret = service;
+  if (!ret.empty() && ret[0] >= 'A' && ret[0] <= 'Z') {
+    ret[0] = ret[0] - 'A' + 'a';
+  }
+  return ret;
+}
+
+void PrintClientMethodDef(google::protobuf::io::Printer* printer,
+                          const google::protobuf::MethodDescriptor* method,
+                          map<string, string>* vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type()->name();
+  (*vars)["Response"] = method->output_type()->name();
+  if (NoStreaming(method)) {
+    printer->Print(*vars,
+                   "\t$Method$(ctx context.Context, in *$Request$, opts "
+                   "...rpc.CallOption) "
+                   "(*$Response$, error)\n");
+  } else if (BidiStreaming(method)) {
+    printer->Print(*vars,
+                   "\t$Method$(ctx context.Context, opts ...rpc.CallOption) "
+                   "($Service$_$Method$Client, error)\n");
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "\t$Method$(ctx context.Context, m *$Request$, opts ...rpc.CallOption) "
+        "($Service$_$Method$Client, error)\n");
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(*vars,
+                   "\t$Method$(ctx context.Context, opts ...rpc.CallOption) "
+                   "($Service$_$Method$Client, error)\n");
+  }
+}
+
+void PrintClientMethodImpl(google::protobuf::io::Printer* printer,
+                           const google::protobuf::MethodDescriptor* method,
+                           map<string, string>* vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type()->name();
+  (*vars)["Response"] = method->output_type()->name();
+
+  if (NoStreaming(method)) {
+    printer->Print(
+        *vars,
+        "func (c *$ServiceStruct$Client) $Method$(ctx context.Context, "
+        "in *$Request$, opts ...rpc.CallOption) (*$Response$, error) {\n");
+    printer->Print(*vars, "\tout := new($Response$)\n");
+    printer->Print(*vars,
+                   "\terr := rpc.Invoke(ctx, \"/$Package$$Service$/$Method$\", "
+                   "in, out, c.cc, opts...)\n");
+    printer->Print("\tif err != nil {\n");
+    printer->Print("\t\treturn nil, err\n");
+    printer->Print("\t}\n");
+    printer->Print("\treturn out, nil\n");
+    printer->Print("}\n\n");
+  } else if (BidiStreaming(method)) {
+    printer->Print(
+        *vars,
+        "func (c *$ServiceStruct$Client) $Method$(ctx context.Context, opts "
+        "...rpc.CallOption) ($Service$_$Method$Client, error) {\n"
+        "\tstream, err := rpc.NewClientStream(ctx, c.cc, "
+        "\"/$Package$$Service$/$Method$\", opts...)\n"
+        "\tif err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\treturn &$ServiceStruct$$Method$Client{stream}, nil\n"
+        "}\n\n");
+    printer->Print(*vars,
+                   "type $Service$_$Method$Client interface {\n"
+                   "\tSend(*$Request$) error\n"
+                   "\tRecv() (*$Response$, error)\n"
+                   "\trpc.ClientStream\n"
+                   "}\n\n");
+    printer->Print(*vars,
+                   "type $ServiceStruct$$Method$Client struct {\n"
+                   "\trpc.ClientStream\n"
+                   "}\n\n");
+    printer->Print(
+        *vars,
+        "func (x *$ServiceStruct$$Method$Client) Send(m *$Request$) error {\n"
+        "\treturn x.ClientStream.SendProto(m)\n"
+        "}\n\n");
+    printer->Print(
+        *vars,
+        "func (x *$ServiceStruct$$Method$Client) Recv() (*$Response$, error) "
+        "{\n"
+        "\tm := new($Response$)\n"
+        "\tif err := x.ClientStream.RecvProto(m); err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\treturn m, nil\n"
+        "}\n\n");
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "func (c *$ServiceStruct$Client) $Method$(ctx context.Context, m "
+        "*$Request$, "
+        "opts ...rpc.CallOption) ($Service$_$Method$Client, error) {\n"
+        "\tstream, err := rpc.NewClientStream(ctx, c.cc, "
+        "\"/$Package$$Service$/$Method$\", opts...)\n"
+        "\tif err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\tx := &$ServiceStruct$$Method$Client{stream}\n"
+        "\tif err := x.ClientStream.SendProto(m); err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\tif err := x.ClientStream.CloseSend(); err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\treturn x, nil\n"
+        "}\n\n");
+    printer->Print(*vars,
+                   "type $Service$_$Method$Client interface {\n"
+                   "\tRecv() (*$Response$, error)\n"
+                   "\trpc.ClientStream\n"
+                   "}\n\n");
+    printer->Print(*vars,
+                   "type $ServiceStruct$$Method$Client struct {\n"
+                   "\trpc.ClientStream\n"
+                   "}\n\n");
+    printer->Print(
+        *vars,
+        "func (x *$ServiceStruct$$Method$Client) Recv() (*$Response$, error) "
+        "{\n"
+        "\tm := new($Response$)\n"
+        "\tif err := x.ClientStream.RecvProto(m); err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\treturn m, nil\n"
+        "}\n\n");
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "func (c *$ServiceStruct$Client) $Method$(ctx context.Context, opts "
+        "...rpc.CallOption) ($Service$_$Method$Client, error) {\n"
+        "\tstream, err := rpc.NewClientStream(ctx, c.cc, "
+        "\"/$Package$$Service$/$Method$\", opts...)\n"
+        "\tif err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\treturn &$ServiceStruct$$Method$Client{stream}, nil\n"
+        "}\n\n");
+    printer->Print(*vars,
+                   "type $Service$_$Method$Client interface {\n"
+                   "\tSend(*$Request$) error\n"
+                   "\tCloseAndRecv() (*$Response$, error)\n"
+                   "\trpc.ClientStream\n"
+                   "}\n\n");
+    printer->Print(*vars,
+                   "type $ServiceStruct$$Method$Client struct {\n"
+                   "\trpc.ClientStream\n"
+                   "}\n\n");
+    printer->Print(
+        *vars,
+        "func (x *$ServiceStruct$$Method$Client) Send(m *$Request$) error {\n"
+        "\treturn x.ClientStream.SendProto(m)\n"
+        "}\n\n");
+    printer->Print(
+        *vars,
+        "func (x *$ServiceStruct$$Method$Client) CloseAndRecv() (*$Response$, "
+        "error) {\n"
+        "\tif err := x.ClientStream.CloseSend(); err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\tm := new($Response$)\n"
+        "\tif err := x.ClientStream.RecvProto(m); err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\t// Read EOF.\n"
+        "\tif err := x.ClientStream.RecvProto(m); err == io.EOF {\n"
+        "\t\treturn m, io.EOF\n"
+        "\t}\n"
+        "\t// gRPC protocol violation.\n"
+        "\treturn m, fmt.Errorf(\"Violate gRPC client streaming protocol: no "
+        "EOF after the response.\")\n"
+        "}\n\n");
+  }
+}
+
+void PrintClient(google::protobuf::io::Printer* printer,
+                 const google::protobuf::ServiceDescriptor* service,
+                 map<string, string>* vars) {
+  (*vars)["Service"] = service->name();
+  (*vars)["ServiceStruct"] = LowerCaseService(service->name());
+  printer->Print(*vars, "type $Service$Client interface {\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintClientMethodDef(printer, service->method(i), vars);
+  }
+  printer->Print("}\n\n");
+
+  printer->Print(*vars,
+                 "type $ServiceStruct$Client struct {\n"
+                 "\tcc *rpc.ClientConn\n"
+                 "}\n\n");
+  printer->Print(
+      *vars,
+      "func New$Service$Client(cc *rpc.ClientConn) $Service$Client {\n"
+      "\treturn &$ServiceStruct$Client{cc}\n"
+      "}\n\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintClientMethodImpl(printer, service->method(i), vars);
+  }
+}
+
+void PrintServerMethodDef(google::protobuf::io::Printer* printer,
+                          const google::protobuf::MethodDescriptor* method,
+                          map<string, string>* vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type()->name();
+  (*vars)["Response"] = method->output_type()->name();
+  if (NoStreaming(method)) {
+    printer->Print(
+        *vars,
+        "\t$Method$(context.Context, *$Request$) (*$Response$, error)\n");
+  } else if (BidiStreaming(method)) {
+    printer->Print(*vars, "\t$Method$($Service$_$Method$Server) error\n");
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(*vars,
+                   "\t$Method$(*$Request$, $Service$_$Method$Server) error\n");
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(*vars, "\t$Method$($Service$_$Method$Server) error\n");
+  }
+}
+
+void PrintServerHandler(google::protobuf::io::Printer* printer,
+                        const google::protobuf::MethodDescriptor* method,
+                        map<string, string>* vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type()->name();
+  (*vars)["Response"] = method->output_type()->name();
+  if (NoStreaming(method)) {
+    printer->Print(
+        *vars,
+        "func _$Service$_$Method$_Handler(srv interface{}, ctx context.Context,"
+        " buf []byte) (proto.Message, error) {\n");
+    printer->Print(*vars, "\tin := new($Request$)\n");
+    printer->Print("\tif err := proto.Unmarshal(buf, in); err != nil {\n");
+    printer->Print("\t\treturn nil, err\n");
+    printer->Print("\t}\n");
+    printer->Print(*vars,
+                   "\tout, err := srv.($Service$Server).$Method$(ctx, in)\n");
+    printer->Print("\tif err != nil {\n");
+    printer->Print("\t\treturn nil, err\n");
+    printer->Print("\t}\n");
+    printer->Print("\treturn out, nil\n");
+    printer->Print("}\n\n");
+  } else if (BidiStreaming(method)) {
+    printer->Print(
+        *vars,
+        "func _$Service$_$Method$_Handler(srv interface{}, stream rpc.ServerStream) "
+        "error {\n"
+        "\treturn srv.($Service$Server).$Method$(&$ServiceStruct$$Method$Server"
+        "{stream})\n"
+        "}\n\n");
+    printer->Print(*vars,
+                   "type $Service$_$Method$Server interface {\n"
+                   "\tSend(*$Response$) error\n"
+                   "\tRecv() (*$Request$, error)\n"
+                   "\trpc.ServerStream\n"
+                   "}\n\n");
+    printer->Print(*vars,
+                   "type $ServiceStruct$$Method$Server struct {\n"
+                   "\trpc.ServerStream\n"
+                   "}\n\n");
+    printer->Print(
+        *vars,
+        "func (x *$ServiceStruct$$Method$Server) Send(m *$Response$) error {\n"
+        "\treturn x.ServerStream.SendProto(m)\n"
+        "}\n\n");
+    printer->Print(
+        *vars,
+        "func (x *$ServiceStruct$$Method$Server) Recv() (*$Request$, error) "
+        "{\n"
+        "\tm := new($Request$)\n"
+        "\tif err := x.ServerStream.RecvProto(m); err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\treturn m, nil\n"
+        "}\n\n");
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "func _$Service$_$Method$_Handler(srv interface{}, stream rpc.ServerStream) "
+        "error {\n"
+        "\tm := new($Request$)\n"
+        "\tif err := stream.RecvProto(m); err != nil {\n"
+        "\t\treturn err\n"
+        "\t}\n"
+        "\treturn srv.($Service$Server).$Method$(m, "
+        "&$ServiceStruct$$Method$Server{stream})\n"
+        "}\n\n");
+    printer->Print(*vars,
+                   "type $Service$_$Method$Server interface {\n"
+                   "\tSend(*$Response$) error\n"
+                   "\trpc.ServerStream\n"
+                   "}\n\n");
+    printer->Print(*vars,
+                   "type $ServiceStruct$$Method$Server struct {\n"
+                   "\trpc.ServerStream\n"
+                   "}\n\n");
+    printer->Print(
+        *vars,
+        "func (x *$ServiceStruct$$Method$Server) Send(m *$Response$) error {\n"
+        "\treturn x.ServerStream.SendProto(m)\n"
+        "}\n\n");
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "func _$Service$_$Method$_Handler(srv interface{}, stream rpc.ServerStream) "
+        "error {\n"
+        "\treturn srv.($Service$Server).$Method$(&$ServiceStruct$$Method$Server"
+        "{stream})\n"
+        "}\n\n");
+    printer->Print(*vars,
+                   "type $Service$_$Method$Server interface {\n"
+                   "\tSendAndClose(*$Response$) error\n"
+                   "\tRecv() (*$Request$, error)\n"
+                   "\trpc.ServerStream\n"
+                   "}\n\n");
+    printer->Print(*vars,
+                   "type $ServiceStruct$$Method$Server struct {\n"
+                   "\trpc.ServerStream\n"
+                   "}\n\n");
+    printer->Print(
+        *vars,
+        "func (x *$ServiceStruct$$Method$Server) SendAndClose(m *$Response$) "
+        "error {\n"
+        "\tif err := x.ServerStream.SendProto(m); err != nil {\n"
+        "\t\treturn err\n"
+        "\t}\n"
+        "\treturn nil\n"
+        "}\n\n");
+    printer->Print(
+        *vars,
+        "func (x *$ServiceStruct$$Method$Server) Recv() (*$Request$, error) {\n"
+        "\tm := new($Request$)\n"
+        "\tif err := x.ServerStream.RecvProto(m); err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\treturn m, nil\n"
+        "}\n\n");
+  }
+}
+
+void PrintServerMethodDesc(google::protobuf::io::Printer* printer,
+                           const google::protobuf::MethodDescriptor* method,
+                           map<string, string>* vars) {
+  (*vars)["Method"] = method->name();
+  printer->Print("\t\t{\n");
+  printer->Print(*vars, "\t\t\tMethodName:\t\"$Method$\",\n");
+  printer->Print(*vars, "\t\t\tHandler:\t_$Service$_$Method$_Handler,\n");
+  printer->Print("\t\t},\n");
+}
+
+void PrintServerStreamingMethodDesc(
+    google::protobuf::io::Printer* printer,
+    const google::protobuf::MethodDescriptor* method,
+    map<string, string>* vars) {
+  (*vars)["Method"] = method->name();
+  printer->Print("\t\t{\n");
+  printer->Print(*vars, "\t\t\tStreamName:\t\"$Method$\",\n");
+  printer->Print(*vars, "\t\t\tHandler:\t_$Service$_$Method$_Handler,\n");
+  printer->Print("\t\t},\n");
+}
+
+void PrintServer(google::protobuf::io::Printer* printer,
+                 const google::protobuf::ServiceDescriptor* service,
+                 map<string, string>* vars) {
+  (*vars)["Service"] = service->name();
+  printer->Print(*vars, "type $Service$Server interface {\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintServerMethodDef(printer, service->method(i), vars);
+  }
+  printer->Print("}\n\n");
+
+  printer->Print(*vars,
+                 "func RegisterService(s *rpc.Server, srv $Service$Server) {\n"
+                 "\ts.RegisterService(&_$Service$_serviceDesc, srv)\n"
+                 "}\n\n");
+
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintServerHandler(printer, service->method(i), vars);
+  }
+
+  printer->Print(*vars,
+                 "var _$Service$_serviceDesc = rpc.ServiceDesc{\n"
+                 "\tServiceName: \"$Package$$Service$\",\n"
+                 "\tHandlerType: (*$Service$Server)(nil),\n"
+                 "\tMethods: []rpc.MethodDesc{\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    if (NoStreaming(service->method(i))) {
+      PrintServerMethodDesc(printer, service->method(i), vars);
+    }
+  }
+  printer->Print("\t},\n");
+
+  printer->Print("\tStreams: []rpc.StreamDesc{\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    if (!NoStreaming(service->method(i))) {
+      PrintServerStreamingMethodDesc(printer, service->method(i), vars);
+    }
+  }
+  printer->Print(
+      "\t},\n"
+      "}\n\n");
+}
+
+std::string BadToUnderscore(std::string str) {
+  for (unsigned i = 0; i < str.size(); ++i) {
+    if (!std::isalnum(str[i])) {
+      str[i] = '_';
+    }
+  }
+  return str;
+}
+
+string GetServices(const google::protobuf::FileDescriptor* file) {
+  string output;
+  google::protobuf::io::StringOutputStream output_stream(&output);
+  google::protobuf::io::Printer printer(&output_stream, '$');
+  map<string, string> vars;
+
+  string package_name = !file->options().go_package().empty()
+                            ? file->options().go_package()
+                            : file->package();
+  vars["PackageName"] = BadToUnderscore(package_name);
+  printer.Print(vars, "package $PackageName$\n\n");
+  printer.Print("import (\n");
+  if (HasClientOnlyStreaming(file)) {
+    printer.Print(
+        "\t\"fmt\"\n"
+        "\t\"io\"\n");
+  }
+  printer.Print(
+      "\t\"github.com/google/grpc-go\"\n"
+      "\tcontext \"golang.org/x/net/context\"\n"
+      "\tproto \"github.com/golang/protobuf/proto\"\n"
+      ")\n\n");
+
+  // $Package$ is used to fully qualify method names.
+  vars["Package"] = file->package();
+  if (!file->package().empty()) {
+    vars["Package"].append(".");
+  }
+
+  for (int i = 0; i < file->service_count(); ++i) {
+    PrintClient(&printer, file->service(0), &vars);
+    printer.Print("\n");
+    PrintServer(&printer, file->service(0), &vars);
+    printer.Print("\n");
+  }
+  return output;
+}
+
+}  // namespace grpc_go_generator
+
diff --git a/compiler/go_generator.h b/compiler/go_generator.h
new file mode 100644
index 00000000..5744345b
--- /dev/null
+++ b/compiler/go_generator.h
@@ -0,0 +1,51 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NET_GRPC_COMPILER_GO_GENERATOR_H_
+#define NET_GRPC_COMPILER_GO_GENERATOR_H_
+
+#include <string>
+
+namespace google {
+namespace protobuf {
+class FileDescriptor;
+}  // namespace protobuf
+}  // namespace google
+
+namespace grpc_go_generator {
+
+std::string GetServices(const google::protobuf::FileDescriptor* file);
+
+}  // namespace grpc_go_generator
+
+#endif  // NET_GRPC_COMPILER_GO_GENERATOR_H_
diff --git a/compiler/go_plugin.cc b/compiler/go_plugin.cc
new file mode 100644
index 00000000..bcd637d2
--- /dev/null
+++ b/compiler/go_plugin.cc
@@ -0,0 +1,84 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+// Generates go gRPC service interface out of Protobuf IDL.
+//
+// This is a Proto2 compiler plugin.  See net/proto2/compiler/proto/plugin.proto
+// and net/proto2/compiler/public/plugin.h for more information on plugins.
+
+#include <fstream>
+#include <memory>
+#include <string>
+
+#include "./go_generator.h"
+#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/compiler/plugin.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/descriptor.h>
+
+using namespace std;
+
+class GoGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
+ public:
+  GoGrpcGenerator() {}
+  virtual ~GoGrpcGenerator() {}
+
+  virtual bool Generate(const google::protobuf::FileDescriptor* file,
+                        const string& parameter,
+                        google::protobuf::compiler::GeneratorContext* context,
+                        string* error) const {
+    // Get output file name.
+    string file_name;
+    if (file->name().size() > 6 &&
+        file->name().find_last_of(".proto") == file->name().size() - 1) {
+      file_name =
+          file->name().substr(0, file->name().size() - 6) + "_grpc.pb.go";
+    } else {
+      *error = "Invalid proto file name. Proto file must end with .proto";
+      return false;
+    }
+
+    unique_ptr<google::protobuf::io::ZeroCopyOutputStream> output(
+        context->Open(file_name));
+    google::protobuf::io::CodedOutputStream coded_out(output.get());
+    string code = grpc_go_generator::GetServices(file);
+    coded_out.WriteRaw(code.data(), code.size());
+    return true;
+  }
+};
+
+int main(int argc, char* argv[]) {
+  GoGrpcGenerator generator;
+  return google::protobuf::compiler::PluginMain(argc, argv, &generator);
+}

From c7a2188d49454203cf90a38097a196a338c532aa Mon Sep 17 00:00:00 2001
From: Qi Zhao <toqizhao@gmail.com>
Date: Wed, 21 Jan 2015 16:14:11 -0800
Subject: [PATCH 06/44] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index d3e372f5..761ec90f 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
 gRPC-Go: The Google opensource RPC library in golang.
 
-To install this package, you need to install Go 1.4 and setup your Go worksapce on your computer. The simplest way to install the grpc package is to run:
+To install this package, you need to install Go 1.4 and setup your Go workspace on your computer. The simplest way to install the grpc package is to run:
 
 go get github.com/google/grpc-go

From 065d08016932324fa3850ab3771123f3a9ae138b Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Wed, 21 Jan 2015 17:29:20 -0800
Subject: [PATCH 07/44] chmod *.go files

---
 call.go                                |  0
 clientconn.go                          |  0
 codes/codes.go                         |  0
 credentials/credentials.go             |  0
 interop/client/client.go               |  0
 interop/server/server.go               |  0
 interop/testdata/test_proto.pb.go      |  0
 interop/testdata/test_proto_grpc.pb.go |  0
 metadata/metadata.go                   |  0
 metadata/metadata_test.go              |  0
 rpc_util.go                            |  0
 rpc_util_test.go                       |  0
 server.go                              |  0
 stream.go                              |  0
 test/end2end_test.go                   |  0
 test/testdata/test.pb.go               | 92 +++++---------------------
 test/testdata/test_grpc.pb.go          | 32 ---------
 transport/control.go                   |  0
 transport/http2_client_transport.go    |  0
 transport/http2_server_transport.go    |  0
 transport/http_util.go                 |  0
 transport/http_util_test.go            |  0
 transport/transport.go                 |  0
 transport/transport_test.go            |  0
 24 files changed, 17 insertions(+), 107 deletions(-)
 mode change 100755 => 100644 call.go
 mode change 100755 => 100644 clientconn.go
 mode change 100755 => 100644 codes/codes.go
 mode change 100755 => 100644 credentials/credentials.go
 mode change 100755 => 100644 interop/client/client.go
 mode change 100755 => 100644 interop/server/server.go
 mode change 100755 => 100644 interop/testdata/test_proto.pb.go
 mode change 100755 => 100644 interop/testdata/test_proto_grpc.pb.go
 mode change 100755 => 100644 metadata/metadata.go
 mode change 100755 => 100644 metadata/metadata_test.go
 mode change 100755 => 100644 rpc_util.go
 mode change 100755 => 100644 rpc_util_test.go
 mode change 100755 => 100644 server.go
 mode change 100755 => 100644 stream.go
 mode change 100755 => 100644 test/end2end_test.go
 mode change 100755 => 100644 test/testdata/test.pb.go
 mode change 100755 => 100644 test/testdata/test_grpc.pb.go
 mode change 100755 => 100644 transport/control.go
 mode change 100755 => 100644 transport/http2_client_transport.go
 mode change 100755 => 100644 transport/http2_server_transport.go
 mode change 100755 => 100644 transport/http_util.go
 mode change 100755 => 100644 transport/http_util_test.go
 mode change 100755 => 100644 transport/transport.go
 mode change 100755 => 100644 transport/transport_test.go

diff --git a/call.go b/call.go
old mode 100755
new mode 100644
diff --git a/clientconn.go b/clientconn.go
old mode 100755
new mode 100644
diff --git a/codes/codes.go b/codes/codes.go
old mode 100755
new mode 100644
diff --git a/credentials/credentials.go b/credentials/credentials.go
old mode 100755
new mode 100644
diff --git a/interop/client/client.go b/interop/client/client.go
old mode 100755
new mode 100644
diff --git a/interop/server/server.go b/interop/server/server.go
old mode 100755
new mode 100644
diff --git a/interop/testdata/test_proto.pb.go b/interop/testdata/test_proto.pb.go
old mode 100755
new mode 100644
diff --git a/interop/testdata/test_proto_grpc.pb.go b/interop/testdata/test_proto_grpc.pb.go
old mode 100755
new mode 100644
diff --git a/metadata/metadata.go b/metadata/metadata.go
old mode 100755
new mode 100644
diff --git a/metadata/metadata_test.go b/metadata/metadata_test.go
old mode 100755
new mode 100644
diff --git a/rpc_util.go b/rpc_util.go
old mode 100755
new mode 100644
diff --git a/rpc_util_test.go b/rpc_util_test.go
old mode 100755
new mode 100644
diff --git a/server.go b/server.go
old mode 100755
new mode 100644
diff --git a/stream.go b/stream.go
old mode 100755
new mode 100644
diff --git a/test/end2end_test.go b/test/end2end_test.go
old mode 100755
new mode 100644
diff --git a/test/testdata/test.pb.go b/test/testdata/test.pb.go
old mode 100755
new mode 100644
index 0477e2be..a2d3dc16
--- a/test/testdata/test.pb.go
+++ b/test/testdata/test.pb.go
@@ -1,44 +1,12 @@
-/*
- *
- * Copyright 2014, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
 // Code generated by protoc-gen-go.
-// source: net/grpc/go/test/test.proto
+// source: test.proto
 // DO NOT EDIT!
 
 /*
 Package test is a generated protocol buffer package.
 
 It is generated from these files:
-	net/grpc/go/test/test.proto
+	test.proto
 
 It has these top-level messages:
 	DivArgs
@@ -62,10 +30,9 @@ type DivArgs struct {
 	XXX_unrecognized []byte `json:"-"`
 }
 
-func (m *DivArgs) Reset()                    { *m = DivArgs{} }
-func (m *DivArgs) String() string            { return proto.CompactTextString(m) }
-func (*DivArgs) ProtoMessage()               {}
-func (*DivArgs) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
+func (m *DivArgs) Reset()         { *m = DivArgs{} }
+func (m *DivArgs) String() string { return proto.CompactTextString(m) }
+func (*DivArgs) ProtoMessage()    {}
 
 func (m *DivArgs) GetDividend() int64 {
 	if m != nil && m.Dividend != nil {
@@ -87,10 +54,9 @@ type DivReply struct {
 	XXX_unrecognized []byte `json:"-"`
 }
 
-func (m *DivReply) Reset()                    { *m = DivReply{} }
-func (m *DivReply) String() string            { return proto.CompactTextString(m) }
-func (*DivReply) ProtoMessage()               {}
-func (*DivReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
+func (m *DivReply) Reset()         { *m = DivReply{} }
+func (m *DivReply) String() string { return proto.CompactTextString(m) }
+func (*DivReply) ProtoMessage()    {}
 
 func (m *DivReply) GetQuotient() int64 {
 	if m != nil && m.Quotient != nil {
@@ -111,10 +77,9 @@ type FibArgs struct {
 	XXX_unrecognized []byte `json:"-"`
 }
 
-func (m *FibArgs) Reset()                    { *m = FibArgs{} }
-func (m *FibArgs) String() string            { return proto.CompactTextString(m) }
-func (*FibArgs) ProtoMessage()               {}
-func (*FibArgs) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
+func (m *FibArgs) Reset()         { *m = FibArgs{} }
+func (m *FibArgs) String() string { return proto.CompactTextString(m) }
+func (*FibArgs) ProtoMessage()    {}
 
 func (m *FibArgs) GetLimit() int64 {
 	if m != nil && m.Limit != nil {
@@ -128,10 +93,9 @@ type Num struct {
 	XXX_unrecognized []byte `json:"-"`
 }
 
-func (m *Num) Reset()                    { *m = Num{} }
-func (m *Num) String() string            { return proto.CompactTextString(m) }
-func (*Num) ProtoMessage()               {}
-func (*Num) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
+func (m *Num) Reset()         { *m = Num{} }
+func (m *Num) String() string { return proto.CompactTextString(m) }
+func (*Num) ProtoMessage()    {}
 
 func (m *Num) GetNum() int64 {
 	if m != nil && m.Num != nil {
@@ -145,10 +109,9 @@ type FibReply struct {
 	XXX_unrecognized []byte `json:"-"`
 }
 
-func (m *FibReply) Reset()                    { *m = FibReply{} }
-func (m *FibReply) String() string            { return proto.CompactTextString(m) }
-func (*FibReply) ProtoMessage()               {}
-func (*FibReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
+func (m *FibReply) Reset()         { *m = FibReply{} }
+func (m *FibReply) String() string { return proto.CompactTextString(m) }
+func (*FibReply) ProtoMessage()    {}
 
 func (m *FibReply) GetCount() int64 {
 	if m != nil && m.Count != nil {
@@ -159,24 +122,3 @@ func (m *FibReply) GetCount() int64 {
 
 func init() {
 }
-
-var fileDescriptor0 = []byte{
-	// 268 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x84, 0x90, 0xbf, 0x4e, 0xc3, 0x30,
-	0x10, 0x87, 0xb9, 0xba, 0x34, 0xe9, 0xa1, 0xf2, 0xc7, 0x53, 0x28, 0x0b, 0xf2, 0x80, 0x3a, 0xa0,
-	0x06, 0x21, 0x5e, 0x00, 0x84, 0xd8, 0xca, 0x00, 0x1b, 0x5b, 0x68, 0xac, 0x60, 0xa9, 0xb1, 0x83,
-	0xe3, 0x54, 0xea, 0xdb, 0x64, 0x64, 0xe4, 0x11, 0x39, 0x3b, 0x09, 0x88, 0xa9, 0x4b, 0x94, 0xbb,
-	0xfb, 0xee, 0xa7, 0xef, 0x8c, 0x17, 0x5a, 0xba, 0xb4, 0xb0, 0xd5, 0x3a, 0x2d, 0x4c, 0xea, 0x64,
-	0xed, 0xc2, 0x67, 0x59, 0x59, 0xe3, 0x0c, 0x1f, 0xfb, 0x7f, 0x71, 0x8d, 0xd1, 0xa3, 0xda, 0xde,
-	0xdb, 0xa2, 0xe6, 0xa7, 0x18, 0xe7, 0x6a, 0xab, 0x72, 0xa9, 0xf3, 0x04, 0x2e, 0x47, 0x0b, 0xc6,
-	0x4f, 0x30, 0xf2, 0x9d, 0xda, 0xd8, 0x64, 0xe4, 0x1b, 0x22, 0xc5, 0x98, 0xe8, 0x17, 0x59, 0x6d,
-	0x76, 0x1e, 0xff, 0x6c, 0x8c, 0x53, 0x52, 0xbb, 0x1e, 0x3f, 0xc3, 0xa9, 0x95, 0x65, 0xa6, 0x74,
-	0x2e, 0x87, 0x85, 0x04, 0xa3, 0x27, 0xf5, 0x1e, 0xe2, 0x67, 0x78, 0xb8, 0x51, 0xa5, 0xf2, 0x30,
-	0xd0, 0x84, 0x23, 0x7b, 0x6e, 0x4a, 0x7e, 0x84, 0x4c, 0x37, 0x65, 0x17, 0x20, 0xce, 0x31, 0x26,
-	0xba, 0x8b, 0x27, 0x7c, 0x6d, 0x9a, 0x21, 0xfb, 0xf6, 0x1b, 0x70, 0xbc, 0xca, 0xdc, 0x07, 0xbf,
-	0x42, 0x46, 0x0a, 0x7c, 0xb6, 0x0c, 0xa7, 0xf4, 0xee, 0xf3, 0xe3, 0xdf, 0x32, 0x6c, 0x8b, 0x03,
-	0x7e, 0x17, 0x0e, 0x5b, 0x65, 0x7a, 0xb7, 0x8f, 0x9d, 0xb4, 0x00, 0x5f, 0x00, 0x0b, 0xb8, 0x01,
-	0x9f, 0x4e, 0x06, 0xc3, 0x46, 0xaf, 0x3e, 0x9f, 0x76, 0x25, 0xf9, 0x0a, 0x46, 0x24, 0x71, 0x02,
-	0xd9, 0x2b, 0xd9, 0xff, 0x0d, 0xfe, 0x31, 0xad, 0x4f, 0x7b, 0x98, 0xbc, 0x85, 0x27, 0xfe, 0x09,
-	0x00, 0x00, 0xff, 0xff, 0x5d, 0x79, 0x02, 0xec, 0x86, 0x01, 0x00, 0x00,
-}
diff --git a/test/testdata/test_grpc.pb.go b/test/testdata/test_grpc.pb.go
old mode 100755
new mode 100644
index 69d4c1aa..01c73d98
--- a/test/testdata/test_grpc.pb.go
+++ b/test/testdata/test_grpc.pb.go
@@ -1,35 +1,3 @@
-/*
- *
- * Copyright 2014, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
 package test
 
 import (
diff --git a/transport/control.go b/transport/control.go
old mode 100755
new mode 100644
diff --git a/transport/http2_client_transport.go b/transport/http2_client_transport.go
old mode 100755
new mode 100644
diff --git a/transport/http2_server_transport.go b/transport/http2_server_transport.go
old mode 100755
new mode 100644
diff --git a/transport/http_util.go b/transport/http_util.go
old mode 100755
new mode 100644
diff --git a/transport/http_util_test.go b/transport/http_util_test.go
old mode 100755
new mode 100644
diff --git a/transport/transport.go b/transport/transport.go
old mode 100755
new mode 100644
diff --git a/transport/transport_test.go b/transport/transport_test.go
old mode 100755
new mode 100644

From b34454ce9283d9c491aecfa93bf11d63629b389a Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Wed, 21 Jan 2015 17:38:14 -0800
Subject: [PATCH 08/44] added the missing license

---
 test/testdata/test.pb.go      | 32 ++++++++++++++++++++++++++++++++
 test/testdata/test_grpc.pb.go | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 64 insertions(+)

diff --git a/test/testdata/test.pb.go b/test/testdata/test.pb.go
index a2d3dc16..f9d22977 100644
--- a/test/testdata/test.pb.go
+++ b/test/testdata/test.pb.go
@@ -1,3 +1,35 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
 // Code generated by protoc-gen-go.
 // source: test.proto
 // DO NOT EDIT!
diff --git a/test/testdata/test_grpc.pb.go b/test/testdata/test_grpc.pb.go
index 01c73d98..69d4c1aa 100644
--- a/test/testdata/test_grpc.pb.go
+++ b/test/testdata/test_grpc.pb.go
@@ -1,3 +1,35 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
 package test
 
 import (

From d831caea821ccb3b02dfeab3dc363c31e15527f1 Mon Sep 17 00:00:00 2001
From: Qi Zhao <toqizhao@gmail.com>
Date: Thu, 22 Jan 2015 13:34:54 -0800
Subject: [PATCH 09/44] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 761ec90f..bc0d14e2 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-gRPC-Go: The Google opensource RPC library in golang.
+gRPC-Go: a Go implementation of gRPC, Google's RPC library
 
 To install this package, you need to install Go 1.4 and setup your Go workspace on your computer. The simplest way to install the grpc package is to run:
 

From 7bfd879f7c73980cea0a9ce306431223c0d6dc3a Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Thu, 22 Jan 2015 14:36:50 -0800
Subject: [PATCH 10/44] i) make interop client supports all test case; ii) make
 interop client flexible to accept server name override for tls handshake
 verification; iii) fix interop server error format.

---
 interop/client/client.go | 27 +++++++++++++++++++--------
 interop/server/server.go |  6 +++---
 2 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/interop/client/client.go b/interop/client/client.go
index 9ab97532..20ecdca1 100644
--- a/interop/client/client.go
+++ b/interop/client/client.go
@@ -39,19 +39,20 @@ import (
 	"net"
 	"strconv"
 
+	"github.com/golang/protobuf/proto"
+	"github.com/google/grpc-go"
 	"github.com/google/grpc-go/credentials"
 	testpb "github.com/google/grpc-go/interop/testdata"
-	"github.com/google/grpc-go"
-	"github.com/golang/protobuf/proto"
 	"golang.org/x/net/context"
 )
 
 var (
-	useTLS     = flag.Bool("use_tls", false, "Connection uses TLS if true, else plain TCP")
-	caFile     = flag.String("tls_ca_file", "testdata/ca.pem", "The file containning the CA root cert file")
-	serverHost = flag.String("server_host", "127.0.0.1", "The server host name")
-	serverPort = flag.Int("server_port", 10000, "The server port number")
-	testCase   = flag.String("test_case", "large_unary", "The RPC method to be tested: large_unary|empty_unary|client_streaming|server_streaming|ping_pong")
+	useTLS        = flag.Bool("use_tls", false, "Connection uses TLS if true, else plain TCP")
+	caFile        = flag.String("tls_ca_file", "testdata/ca.pem", "The file containning the CA root cert file")
+	serverHost    = flag.String("server_host", "127.0.0.1", "The server host name")
+	serverPort    = flag.Int("server_port", 10000, "The server port number")
+	tlsServerName = flag.String("tls_server_name", "x.test.youtube.com", "The server name use to verify the hostname returned by TLS handshake")
+	testCase      = flag.String("test_case", "large_unary", "The RPC method to be tested: large_unary|empty_unary|client_streaming|server_streaming|ping_pong|all")
 )
 
 var (
@@ -225,7 +226,11 @@ func main() {
 	serverAddr := net.JoinHostPort(*serverHost, strconv.Itoa(*serverPort))
 	var opts []rpc.DialOption
 	if *useTLS {
-		creds, err := credentials.NewClientTLSFromFile(*caFile, "x.test.youtube.com")
+		sn := *serverHost
+		if *tlsServerName != "" {
+			sn = *tlsServerName
+		}
+		creds, err := credentials.NewClientTLSFromFile(*caFile, sn)
 		if err != nil {
 			log.Fatalf("Failed to create credentials %v", err)
 		}
@@ -248,6 +253,12 @@ func main() {
 		doServerStreaming(tc)
 	case "ping_pong":
 		doPingPong(tc)
+	case "all":
+		doEmptyUnaryCall(tc)
+		doLargeUnaryCall(tc)
+		doClientStreaming(tc)
+		doServerStreaming(tc)
+		doPingPong(tc)
 	default:
 		log.Fatal("Unsupported test case: ", *testCase)
 	}
diff --git a/interop/server/server.go b/interop/server/server.go
index de3c6028..6801660a 100644
--- a/interop/server/server.go
+++ b/interop/server/server.go
@@ -64,15 +64,15 @@ func (s *testServer) EmptyCall(ctx context.Context, in *testpb.Empty) (*testpb.E
 
 func newPayload(t testpb.PayloadType, size int32) (*testpb.Payload, error) {
 	if size < 0 {
-		return nil, fmt.Errorf("Requested a response with invalid length %d", size)
+		return nil, fmt.Errorf("requested a response with invalid length %d", size)
 	}
 	body := make([]byte, size)
 	switch t {
 	case testpb.PayloadType_COMPRESSABLE:
 	case testpb.PayloadType_UNCOMPRESSABLE:
-		return nil, fmt.Errorf("PayloadType UNCOMPRESSABLE is not supported")
+		return nil, fmt.Errorf("payloadType UNCOMPRESSABLE is not supported")
 	default:
-		return nil, fmt.Errorf("Unsupported payload type: %d", t)
+		return nil, fmt.Errorf("unsupported payload type: %d", t)
 	}
 	return &testpb.Payload{
 		Type: t.Enum(),

From ba40de08ecbf4f7b838189b86cee78db804b3611 Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Thu, 22 Jan 2015 15:54:20 -0800
Subject: [PATCH 11/44] Insert a newline after license text

---
 call.go                                | 1 +
 clientconn.go                          | 1 +
 codes/codes.go                         | 1 +
 credentials/credentials.go             | 1 +
 interop/client/client.go               | 1 +
 interop/server/server.go               | 1 +
 interop/testdata/test_proto.pb.go      | 1 +
 interop/testdata/test_proto_grpc.pb.go | 1 +
 metadata/metadata.go                   | 1 +
 metadata/metadata_test.go              | 1 +
 rpc_util.go                            | 1 +
 rpc_util_test.go                       | 1 +
 server.go                              | 1 +
 stream.go                              | 1 +
 test/end2end_test.go                   | 1 +
 test/testdata/test.pb.go               | 1 +
 test/testdata/test_grpc.pb.go          | 1 +
 transport/control.go                   | 1 +
 transport/http2_client_transport.go    | 1 +
 transport/http2_server_transport.go    | 1 +
 transport/http_util.go                 | 1 +
 transport/http_util_test.go            | 1 +
 transport/transport.go                 | 1 +
 transport/transport_test.go            | 1 +
 24 files changed, 24 insertions(+)

diff --git a/call.go b/call.go
index 7d8f2f6b..f6b2e79b 100644
--- a/call.go
+++ b/call.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 package rpc
 
 import (
diff --git a/clientconn.go b/clientconn.go
index dda5e433..66d6f264 100644
--- a/clientconn.go
+++ b/clientconn.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 /*
 Package rpc implements various components to perform RPC on top of transport package.
 */
diff --git a/codes/codes.go b/codes/codes.go
index 636cd022..c1018b44 100644
--- a/codes/codes.go
+++ b/codes/codes.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 // Package codes defines the canonical error codes used by gRPC. It is
 // consistent across various languages.
 package codes
diff --git a/credentials/credentials.go b/credentials/credentials.go
index e4554db3..a1ed107a 100644
--- a/credentials/credentials.go
+++ b/credentials/credentials.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 // Package credentials implements various credentials supported by gRPC library.
 package credentials
 
diff --git a/interop/client/client.go b/interop/client/client.go
index 20ecdca1..fa62e07a 100644
--- a/interop/client/client.go
+++ b/interop/client/client.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 package main
 
 import (
diff --git a/interop/server/server.go b/interop/server/server.go
index 6801660a..89ee3469 100644
--- a/interop/server/server.go
+++ b/interop/server/server.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 package main
 
 import (
diff --git a/interop/testdata/test_proto.pb.go b/interop/testdata/test_proto.pb.go
index a7a532dc..43157917 100644
--- a/interop/testdata/test_proto.pb.go
+++ b/interop/testdata/test_proto.pb.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 // Code generated by protoc-gen-go.
 // source: net/grpc/go/interop/test.proto
 // DO NOT EDIT!
diff --git a/interop/testdata/test_proto_grpc.pb.go b/interop/testdata/test_proto_grpc.pb.go
index e99885d5..b9e1a033 100644
--- a/interop/testdata/test_proto_grpc.pb.go
+++ b/interop/testdata/test_proto_grpc.pb.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 package grpc_testing
 
 import (
diff --git a/metadata/metadata.go b/metadata/metadata.go
index ece53874..79be970d 100644
--- a/metadata/metadata.go
+++ b/metadata/metadata.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 // Package metadata define the structure of the metadata supported by gRPC library.
 package metadata
 
diff --git a/metadata/metadata_test.go b/metadata/metadata_test.go
index 00d4dca5..ef3a1b8c 100644
--- a/metadata/metadata_test.go
+++ b/metadata/metadata_test.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 package metadata
 
 import (
diff --git a/rpc_util.go b/rpc_util.go
index 9b7449f6..8bbe0a89 100644
--- a/rpc_util.go
+++ b/rpc_util.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 package rpc
 
 import (
diff --git a/rpc_util_test.go b/rpc_util_test.go
index 62dc2e1f..2bc304d0 100644
--- a/rpc_util_test.go
+++ b/rpc_util_test.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 package rpc
 
 import (
diff --git a/server.go b/server.go
index ecf91d5d..dd0bae79 100644
--- a/server.go
+++ b/server.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 package rpc
 
 import (
diff --git a/stream.go b/stream.go
index db05bf57..ec63801a 100644
--- a/stream.go
+++ b/stream.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 package rpc
 
 import (
diff --git a/test/end2end_test.go b/test/end2end_test.go
index 33441290..ea3c7e53 100644
--- a/test/end2end_test.go
+++ b/test/end2end_test.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 package grpc_test
 
 import (
diff --git a/test/testdata/test.pb.go b/test/testdata/test.pb.go
index f9d22977..46fa1d3f 100644
--- a/test/testdata/test.pb.go
+++ b/test/testdata/test.pb.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 // Code generated by protoc-gen-go.
 // source: test.proto
 // DO NOT EDIT!
diff --git a/test/testdata/test_grpc.pb.go b/test/testdata/test_grpc.pb.go
index 69d4c1aa..960ea866 100644
--- a/test/testdata/test_grpc.pb.go
+++ b/test/testdata/test_grpc.pb.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 package test
 
 import (
diff --git a/transport/control.go b/transport/control.go
index 28335965..e734ed30 100644
--- a/transport/control.go
+++ b/transport/control.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 package transport
 
 import (
diff --git a/transport/http2_client_transport.go b/transport/http2_client_transport.go
index b10c7251..328e77db 100644
--- a/transport/http2_client_transport.go
+++ b/transport/http2_client_transport.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 package transport
 
 import (
diff --git a/transport/http2_server_transport.go b/transport/http2_server_transport.go
index e29e709a..e63633e6 100644
--- a/transport/http2_server_transport.go
+++ b/transport/http2_server_transport.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 package transport
 
 import (
diff --git a/transport/http_util.go b/transport/http_util.go
index ad7f0fc6..0c7b0e04 100644
--- a/transport/http_util.go
+++ b/transport/http_util.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 package transport
 
 import (
diff --git a/transport/http_util_test.go b/transport/http_util_test.go
index 4f763f65..e90e4116 100644
--- a/transport/http_util_test.go
+++ b/transport/http_util_test.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 package transport
 
 import (
diff --git a/transport/transport.go b/transport/transport.go
index 2b648265..c9cb5e47 100644
--- a/transport/transport.go
+++ b/transport/transport.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 /*
 Package transport defines and implements message oriented communication channel
 to complete various transactions (e.g., an RPC).
diff --git a/transport/transport_test.go b/transport/transport_test.go
index 2f4d70d6..2d6638e1 100644
--- a/transport/transport_test.go
+++ b/transport/transport_test.go
@@ -30,6 +30,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
 package transport
 
 import (

From 8310928c9b334e43c3d26e3ed489655b65ae1ad9 Mon Sep 17 00:00:00 2001
From: Qi Zhao <toqizhao@gmail.com>
Date: Thu, 22 Jan 2015 15:57:15 -0800
Subject: [PATCH 12/44] Update README.md

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index bc0d14e2..2d7948a7 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
 gRPC-Go: a Go implementation of gRPC, Google's RPC library
 
-To install this package, you need to install Go 1.4 and setup your Go workspace on your computer. The simplest way to install the grpc package is to run:
+To install this package, you need to install Go 1.4 and setup your Go workspace on your computer. The simplest way to install the library is to run:
 
 go get github.com/google/grpc-go

From 3ca141a6ab2ae1d02224d43677fc5983555aac01 Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Thu, 22 Jan 2015 18:04:06 -0800
Subject: [PATCH 13/44] Restructure the directory so that the basename of the
 import path matches the Go package name.

---
 README.md                                               | 2 +-
 replace.sh                                              | 8 ++++++++
 call.go => rpc/call.go                                  | 6 +++---
 clientconn.go => rpc/clientconn.go                      | 4 ++--
 {codes => rpc/codes}/codes.go                           | 0
 {compiler => rpc/compiler}/Makefile                     | 0
 {compiler => rpc/compiler}/gen.sh                       | 0
 {compiler => rpc/compiler}/go_generator.cc              | 0
 {compiler => rpc/compiler}/go_generator.h               | 0
 {compiler => rpc/compiler}/go_plugin.cc                 | 0
 {credentials => rpc/credentials}/credentials.go         | 0
 {interop => rpc/interop}/client/client.go               | 4 ++--
 {interop => rpc/interop}/client/testdata/ca.pem         | 0
 {interop => rpc/interop}/client/testdata/server1.key    | 0
 {interop => rpc/interop}/client/testdata/server1.pem    | 0
 {interop => rpc/interop}/server/server.go               | 4 ++--
 {interop => rpc/interop}/server/testdata/ca.pem         | 0
 {interop => rpc/interop}/server/testdata/server1.key    | 0
 {interop => rpc/interop}/server/testdata/server1.pem    | 0
 {interop => rpc/interop}/testdata/messages.proto        | 0
 {interop => rpc/interop}/testdata/test.proto            | 0
 {interop => rpc/interop}/testdata/test_proto.pb.go      | 0
 {interop => rpc/interop}/testdata/test_proto_grpc.pb.go | 2 +-
 {metadata => rpc/metadata}/metadata.go                  | 0
 {metadata => rpc/metadata}/metadata_test.go             | 0
 rpc_util.go => rpc/rpc_util.go                          | 6 +++---
 rpc_util_test.go => rpc/rpc_util_test.go                | 4 ++--
 server.go => rpc/server.go                              | 8 ++++----
 stream.go => rpc/stream.go                              | 6 +++---
 {test => rpc/test}/end2end_test.go                      | 8 ++++----
 {test => rpc/test}/testdata/ca.pem                      | 0
 {test => rpc/test}/testdata/server1.key                 | 0
 {test => rpc/test}/testdata/server1.pem                 | 0
 {test => rpc/test}/testdata/test.pb.go                  | 0
 {test => rpc/test}/testdata/test.proto                  | 0
 {test => rpc/test}/testdata/test_grpc.pb.go             | 2 +-
 {transport => rpc/transport}/control.go                 | 0
 {transport => rpc/transport}/http2_client_transport.go  | 6 +++---
 {transport => rpc/transport}/http2_server_transport.go  | 4 ++--
 {transport => rpc/transport}/http_util.go               | 4 ++--
 {transport => rpc/transport}/http_util_test.go          | 0
 {transport => rpc/transport}/testdata/ca.pem            | 0
 {transport => rpc/transport}/testdata/server1.key       | 0
 {transport => rpc/transport}/testdata/server1.pem       | 0
 {transport => rpc/transport}/transport.go               | 6 +++---
 {transport => rpc/transport}/transport_test.go          | 4 ++--
 46 files changed, 48 insertions(+), 40 deletions(-)
 create mode 100755 replace.sh
 rename call.go => rpc/call.go (97%)
 rename clientconn.go => rpc/clientconn.go (98%)
 rename {codes => rpc/codes}/codes.go (100%)
 rename {compiler => rpc/compiler}/Makefile (100%)
 rename {compiler => rpc/compiler}/gen.sh (100%)
 rename {compiler => rpc/compiler}/go_generator.cc (100%)
 rename {compiler => rpc/compiler}/go_generator.h (100%)
 rename {compiler => rpc/compiler}/go_plugin.cc (100%)
 rename {credentials => rpc/credentials}/credentials.go (100%)
 rename {interop => rpc/interop}/client/client.go (99%)
 rename {interop => rpc/interop}/client/testdata/ca.pem (100%)
 rename {interop => rpc/interop}/client/testdata/server1.key (100%)
 rename {interop => rpc/interop}/client/testdata/server1.pem (100%)
 rename {interop => rpc/interop}/server/server.go (98%)
 rename {interop => rpc/interop}/server/testdata/ca.pem (100%)
 rename {interop => rpc/interop}/server/testdata/server1.key (100%)
 rename {interop => rpc/interop}/server/testdata/server1.pem (100%)
 rename {interop => rpc/interop}/testdata/messages.proto (100%)
 rename {interop => rpc/interop}/testdata/test.proto (100%)
 rename {interop => rpc/interop}/testdata/test_proto.pb.go (100%)
 rename {interop => rpc/interop}/testdata/test_proto_grpc.pb.go (99%)
 rename {metadata => rpc/metadata}/metadata.go (100%)
 rename {metadata => rpc/metadata}/metadata_test.go (100%)
 rename rpc_util.go => rpc/rpc_util.go (98%)
 rename rpc_util_test.go => rpc/rpc_util_test.go (98%)
 rename server.go => rpc/server.go (98%)
 rename stream.go => rpc/stream.go (98%)
 rename {test => rpc/test}/end2end_test.go (98%)
 rename {test => rpc/test}/testdata/ca.pem (100%)
 rename {test => rpc/test}/testdata/server1.key (100%)
 rename {test => rpc/test}/testdata/server1.pem (100%)
 rename {test => rpc/test}/testdata/test.pb.go (100%)
 rename {test => rpc/test}/testdata/test.proto (100%)
 rename {test => rpc/test}/testdata/test_grpc.pb.go (99%)
 rename {transport => rpc/transport}/control.go (100%)
 rename {transport => rpc/transport}/http2_client_transport.go (99%)
 rename {transport => rpc/transport}/http2_server_transport.go (99%)
 rename {transport => rpc/transport}/http_util.go (99%)
 rename {transport => rpc/transport}/http_util_test.go (100%)
 rename {transport => rpc/transport}/testdata/ca.pem (100%)
 rename {transport => rpc/transport}/testdata/server1.key (100%)
 rename {transport => rpc/transport}/testdata/server1.pem (100%)
 rename {transport => rpc/transport}/transport.go (99%)
 rename {transport => rpc/transport}/transport_test.go (99%)

diff --git a/README.md b/README.md
index bc0d14e2..c64b107b 100644
--- a/README.md
+++ b/README.md
@@ -2,4 +2,4 @@ gRPC-Go: a Go implementation of gRPC, Google's RPC library
 
 To install this package, you need to install Go 1.4 and setup your Go workspace on your computer. The simplest way to install the grpc package is to run:
 
-go get github.com/google/grpc-go
+go get github.com/google/grpc-go/rpc
diff --git a/replace.sh b/replace.sh
new file mode 100755
index 00000000..8e18923e
--- /dev/null
+++ b/replace.sh
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+shopt -s globstar
+
+origin='github.com/google/grpc-go/metadata'
+replace='github.com/google/grpc-go/rpc/metadata'
+sed -i "s%$origin%$replace%g" **/*.go
+
diff --git a/call.go b/rpc/call.go
similarity index 97%
rename from call.go
rename to rpc/call.go
index f6b2e79b..cf52316b 100644
--- a/call.go
+++ b/rpc/call.go
@@ -36,9 +36,9 @@ package rpc
 import (
 	"io"
 
-	"github.com/google/grpc-go/codes"
-	"github.com/google/grpc-go/metadata"
-	"github.com/google/grpc-go/transport"
+	"github.com/google/grpc-go/rpc/codes"
+	"github.com/google/grpc-go/rpc/metadata"
+	"github.com/google/grpc-go/rpc/transport"
 	"github.com/golang/protobuf/proto"
 	"golang.org/x/net/context"
 )
diff --git a/clientconn.go b/rpc/clientconn.go
similarity index 98%
rename from clientconn.go
rename to rpc/clientconn.go
index 66d6f264..ff50312d 100644
--- a/clientconn.go
+++ b/rpc/clientconn.go
@@ -41,8 +41,8 @@ import (
 	"sync"
 	"time"
 
-	"github.com/google/grpc-go/credentials"
-	"github.com/google/grpc-go/transport"
+	"github.com/google/grpc-go/rpc/credentials"
+	"github.com/google/grpc-go/rpc/transport"
 	"golang.org/x/net/context"
 )
 
diff --git a/codes/codes.go b/rpc/codes/codes.go
similarity index 100%
rename from codes/codes.go
rename to rpc/codes/codes.go
diff --git a/compiler/Makefile b/rpc/compiler/Makefile
similarity index 100%
rename from compiler/Makefile
rename to rpc/compiler/Makefile
diff --git a/compiler/gen.sh b/rpc/compiler/gen.sh
similarity index 100%
rename from compiler/gen.sh
rename to rpc/compiler/gen.sh
diff --git a/compiler/go_generator.cc b/rpc/compiler/go_generator.cc
similarity index 100%
rename from compiler/go_generator.cc
rename to rpc/compiler/go_generator.cc
diff --git a/compiler/go_generator.h b/rpc/compiler/go_generator.h
similarity index 100%
rename from compiler/go_generator.h
rename to rpc/compiler/go_generator.h
diff --git a/compiler/go_plugin.cc b/rpc/compiler/go_plugin.cc
similarity index 100%
rename from compiler/go_plugin.cc
rename to rpc/compiler/go_plugin.cc
diff --git a/credentials/credentials.go b/rpc/credentials/credentials.go
similarity index 100%
rename from credentials/credentials.go
rename to rpc/credentials/credentials.go
diff --git a/interop/client/client.go b/rpc/interop/client/client.go
similarity index 99%
rename from interop/client/client.go
rename to rpc/interop/client/client.go
index fa62e07a..caf7c1e4 100644
--- a/interop/client/client.go
+++ b/rpc/interop/client/client.go
@@ -41,8 +41,8 @@ import (
 	"strconv"
 
 	"github.com/golang/protobuf/proto"
-	"github.com/google/grpc-go"
-	"github.com/google/grpc-go/credentials"
+	"github.com/google/grpc-go/go"
+	"github.com/google/grpc-go/rpc/credentials"
 	testpb "github.com/google/grpc-go/interop/testdata"
 	"golang.org/x/net/context"
 )
diff --git a/interop/client/testdata/ca.pem b/rpc/interop/client/testdata/ca.pem
similarity index 100%
rename from interop/client/testdata/ca.pem
rename to rpc/interop/client/testdata/ca.pem
diff --git a/interop/client/testdata/server1.key b/rpc/interop/client/testdata/server1.key
similarity index 100%
rename from interop/client/testdata/server1.key
rename to rpc/interop/client/testdata/server1.key
diff --git a/interop/client/testdata/server1.pem b/rpc/interop/client/testdata/server1.pem
similarity index 100%
rename from interop/client/testdata/server1.pem
rename to rpc/interop/client/testdata/server1.pem
diff --git a/interop/server/server.go b/rpc/interop/server/server.go
similarity index 98%
rename from interop/server/server.go
rename to rpc/interop/server/server.go
index 89ee3469..4305f015 100644
--- a/interop/server/server.go
+++ b/rpc/interop/server/server.go
@@ -42,9 +42,9 @@ import (
 	"strconv"
 	"time"
 
-	"github.com/google/grpc-go/credentials"
+	"github.com/google/grpc-go/rpc/credentials"
 	testpb "github.com/google/grpc-go/interop/testdata"
-	"github.com/google/grpc-go"
+	"github.com/google/grpc-go/rpc"
 	"github.com/golang/protobuf/proto"
 	"golang.org/x/net/context"
 )
diff --git a/interop/server/testdata/ca.pem b/rpc/interop/server/testdata/ca.pem
similarity index 100%
rename from interop/server/testdata/ca.pem
rename to rpc/interop/server/testdata/ca.pem
diff --git a/interop/server/testdata/server1.key b/rpc/interop/server/testdata/server1.key
similarity index 100%
rename from interop/server/testdata/server1.key
rename to rpc/interop/server/testdata/server1.key
diff --git a/interop/server/testdata/server1.pem b/rpc/interop/server/testdata/server1.pem
similarity index 100%
rename from interop/server/testdata/server1.pem
rename to rpc/interop/server/testdata/server1.pem
diff --git a/interop/testdata/messages.proto b/rpc/interop/testdata/messages.proto
similarity index 100%
rename from interop/testdata/messages.proto
rename to rpc/interop/testdata/messages.proto
diff --git a/interop/testdata/test.proto b/rpc/interop/testdata/test.proto
similarity index 100%
rename from interop/testdata/test.proto
rename to rpc/interop/testdata/test.proto
diff --git a/interop/testdata/test_proto.pb.go b/rpc/interop/testdata/test_proto.pb.go
similarity index 100%
rename from interop/testdata/test_proto.pb.go
rename to rpc/interop/testdata/test_proto.pb.go
diff --git a/interop/testdata/test_proto_grpc.pb.go b/rpc/interop/testdata/test_proto_grpc.pb.go
similarity index 99%
rename from interop/testdata/test_proto_grpc.pb.go
rename to rpc/interop/testdata/test_proto_grpc.pb.go
index b9e1a033..303e1735 100644
--- a/interop/testdata/test_proto_grpc.pb.go
+++ b/rpc/interop/testdata/test_proto_grpc.pb.go
@@ -35,7 +35,7 @@ package grpc_testing
 
 import (
 	"fmt"
-	"github.com/google/grpc-go"
+	"github.com/google/grpc-go/rpc"
 	proto "github.com/golang/protobuf/proto"
 	context "golang.org/x/net/context"
 	"io"
diff --git a/metadata/metadata.go b/rpc/metadata/metadata.go
similarity index 100%
rename from metadata/metadata.go
rename to rpc/metadata/metadata.go
diff --git a/metadata/metadata_test.go b/rpc/metadata/metadata_test.go
similarity index 100%
rename from metadata/metadata_test.go
rename to rpc/metadata/metadata_test.go
diff --git a/rpc_util.go b/rpc/rpc_util.go
similarity index 98%
rename from rpc_util.go
rename to rpc/rpc_util.go
index 8bbe0a89..b38ef701 100644
--- a/rpc_util.go
+++ b/rpc/rpc_util.go
@@ -42,9 +42,9 @@ import (
 	"os"
 	"time"
 
-	"github.com/google/grpc-go/codes"
-	"github.com/google/grpc-go/metadata"
-	"github.com/google/grpc-go/transport"
+	"github.com/google/grpc-go/rpc/codes"
+	"github.com/google/grpc-go/rpc/metadata"
+	"github.com/google/grpc-go/rpc/transport"
 	"github.com/golang/protobuf/proto"
 	"golang.org/x/net/context"
 )
diff --git a/rpc_util_test.go b/rpc/rpc_util_test.go
similarity index 98%
rename from rpc_util_test.go
rename to rpc/rpc_util_test.go
index 2bc304d0..4c08c602 100644
--- a/rpc_util_test.go
+++ b/rpc/rpc_util_test.go
@@ -41,8 +41,8 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/grpc-go/codes"
-	"github.com/google/grpc-go/transport"
+	"github.com/google/grpc-go/rpc/codes"
+	"github.com/google/grpc-go/rpc/transport"
 	"github.com/golang/protobuf/proto"
 	"golang.org/x/net/context"
 )
diff --git a/server.go b/rpc/server.go
similarity index 98%
rename from server.go
rename to rpc/server.go
index dd0bae79..2dcd4ff3 100644
--- a/server.go
+++ b/rpc/server.go
@@ -42,10 +42,10 @@ import (
 	"strings"
 	"sync"
 
-	"github.com/google/grpc-go/codes"
-	"github.com/google/grpc-go/credentials"
-	"github.com/google/grpc-go/metadata"
-	"github.com/google/grpc-go/transport"
+	"github.com/google/grpc-go/rpc/codes"
+	"github.com/google/grpc-go/rpc/credentials"
+	"github.com/google/grpc-go/rpc/metadata"
+	"github.com/google/grpc-go/rpc/transport"
 	"github.com/golang/protobuf/proto"
 	"golang.org/x/net/context"
 )
diff --git a/stream.go b/rpc/stream.go
similarity index 98%
rename from stream.go
rename to rpc/stream.go
index ec63801a..13a96216 100644
--- a/stream.go
+++ b/rpc/stream.go
@@ -36,9 +36,9 @@ package rpc
 import (
 	"io"
 
-	"github.com/google/grpc-go/codes"
-	"github.com/google/grpc-go/metadata"
-	"github.com/google/grpc-go/transport"
+	"github.com/google/grpc-go/rpc/codes"
+	"github.com/google/grpc-go/rpc/metadata"
+	"github.com/google/grpc-go/rpc/transport"
 	"github.com/golang/protobuf/proto"
 	"golang.org/x/net/context"
 )
diff --git a/test/end2end_test.go b/rpc/test/end2end_test.go
similarity index 98%
rename from test/end2end_test.go
rename to rpc/test/end2end_test.go
index ea3c7e53..05abbfaf 100644
--- a/test/end2end_test.go
+++ b/rpc/test/end2end_test.go
@@ -46,10 +46,10 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/grpc-go/codes"
-	"github.com/google/grpc-go/credentials"
-	"github.com/google/grpc-go/metadata"
-	"github.com/google/grpc-go"
+	"github.com/google/grpc-go/rpc/codes"
+	"github.com/google/grpc-go/rpc/credentials"
+	"github.com/google/grpc-go/rpc/metadata"
+	"github.com/google/grpc-go/rpc"
 	testpb "github.com/google/grpc-go/test/testdata"
 	"github.com/golang/protobuf/proto"
 	"golang.org/x/net/context"
diff --git a/test/testdata/ca.pem b/rpc/test/testdata/ca.pem
similarity index 100%
rename from test/testdata/ca.pem
rename to rpc/test/testdata/ca.pem
diff --git a/test/testdata/server1.key b/rpc/test/testdata/server1.key
similarity index 100%
rename from test/testdata/server1.key
rename to rpc/test/testdata/server1.key
diff --git a/test/testdata/server1.pem b/rpc/test/testdata/server1.pem
similarity index 100%
rename from test/testdata/server1.pem
rename to rpc/test/testdata/server1.pem
diff --git a/test/testdata/test.pb.go b/rpc/test/testdata/test.pb.go
similarity index 100%
rename from test/testdata/test.pb.go
rename to rpc/test/testdata/test.pb.go
diff --git a/test/testdata/test.proto b/rpc/test/testdata/test.proto
similarity index 100%
rename from test/testdata/test.proto
rename to rpc/test/testdata/test.proto
diff --git a/test/testdata/test_grpc.pb.go b/rpc/test/testdata/test_grpc.pb.go
similarity index 99%
rename from test/testdata/test_grpc.pb.go
rename to rpc/test/testdata/test_grpc.pb.go
index 960ea866..6dc16a59 100644
--- a/test/testdata/test_grpc.pb.go
+++ b/rpc/test/testdata/test_grpc.pb.go
@@ -36,7 +36,7 @@ package test
 import (
 	"fmt"
 	"io"
-	"github.com/google/grpc-go"
+	"github.com/google/grpc-go/rpc"
 	context "golang.org/x/net/context"
 	proto "github.com/golang/protobuf/proto"
 )
diff --git a/transport/control.go b/rpc/transport/control.go
similarity index 100%
rename from transport/control.go
rename to rpc/transport/control.go
diff --git a/transport/http2_client_transport.go b/rpc/transport/http2_client_transport.go
similarity index 99%
rename from transport/http2_client_transport.go
rename to rpc/transport/http2_client_transport.go
index 328e77db..af7347b4 100644
--- a/transport/http2_client_transport.go
+++ b/rpc/transport/http2_client_transport.go
@@ -42,9 +42,9 @@ import (
 	"sync"
 	"time"
 
-	"github.com/google/grpc-go/codes"
-	"github.com/google/grpc-go/credentials"
-	"github.com/google/grpc-go/metadata"
+	"github.com/google/grpc-go/rpc/codes"
+	"github.com/google/grpc-go/rpc/credentials"
+	"github.com/google/grpc-go/rpc/metadata"
 	"golang.org/x/net/context"
 	"github.com/bradfitz/http2/hpack"
 	"github.com/bradfitz/http2"
diff --git a/transport/http2_server_transport.go b/rpc/transport/http2_server_transport.go
similarity index 99%
rename from transport/http2_server_transport.go
rename to rpc/transport/http2_server_transport.go
index e63633e6..d486e0b8 100644
--- a/transport/http2_server_transport.go
+++ b/rpc/transport/http2_server_transport.go
@@ -43,8 +43,8 @@ import (
 	"strconv"
 	"sync"
 
-	"github.com/google/grpc-go/codes"
-	"github.com/google/grpc-go/metadata"
+	"github.com/google/grpc-go/rpc/codes"
+	"github.com/google/grpc-go/rpc/metadata"
 	"golang.org/x/net/context"
 	"github.com/bradfitz/http2/hpack"
 	"github.com/bradfitz/http2"
diff --git a/transport/http_util.go b/rpc/transport/http_util.go
similarity index 99%
rename from transport/http_util.go
rename to rpc/transport/http_util.go
index 0c7b0e04..5d1a871a 100644
--- a/transport/http_util.go
+++ b/rpc/transport/http_util.go
@@ -39,8 +39,8 @@ import (
 	"strconv"
 	"time"
 
-	"github.com/google/grpc-go/codes"
-	"github.com/google/grpc-go/metadata"
+	"github.com/google/grpc-go/rpc/codes"
+	"github.com/google/grpc-go/rpc/metadata"
 	"github.com/bradfitz/http2/hpack"
 	"github.com/bradfitz/http2"
 )
diff --git a/transport/http_util_test.go b/rpc/transport/http_util_test.go
similarity index 100%
rename from transport/http_util_test.go
rename to rpc/transport/http_util_test.go
diff --git a/transport/testdata/ca.pem b/rpc/transport/testdata/ca.pem
similarity index 100%
rename from transport/testdata/ca.pem
rename to rpc/transport/testdata/ca.pem
diff --git a/transport/testdata/server1.key b/rpc/transport/testdata/server1.key
similarity index 100%
rename from transport/testdata/server1.key
rename to rpc/transport/testdata/server1.key
diff --git a/transport/testdata/server1.pem b/rpc/transport/testdata/server1.pem
similarity index 100%
rename from transport/testdata/server1.pem
rename to rpc/transport/testdata/server1.pem
diff --git a/transport/transport.go b/rpc/transport/transport.go
similarity index 99%
rename from transport/transport.go
rename to rpc/transport/transport.go
index c9cb5e47..5c3ceee1 100644
--- a/transport/transport.go
+++ b/rpc/transport/transport.go
@@ -44,9 +44,9 @@ import (
 	"net"
 	"sync"
 
-	"github.com/google/grpc-go/codes"
-	"github.com/google/grpc-go/credentials"
-	"github.com/google/grpc-go/metadata"
+	"github.com/google/grpc-go/rpc/codes"
+	"github.com/google/grpc-go/rpc/credentials"
+	"github.com/google/grpc-go/rpc/metadata"
 	"golang.org/x/net/context"
 )
 
diff --git a/transport/transport_test.go b/rpc/transport/transport_test.go
similarity index 99%
rename from transport/transport_test.go
rename to rpc/transport/transport_test.go
index 2d6638e1..682585c4 100644
--- a/transport/transport_test.go
+++ b/rpc/transport/transport_test.go
@@ -45,8 +45,8 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/grpc-go/codes"
-	"github.com/google/grpc-go/credentials"
+	"github.com/google/grpc-go/rpc/codes"
+	"github.com/google/grpc-go/rpc/credentials"
 	"golang.org/x/net/context"
 )
 

From 5a8bbe621b571fe1e9d1a00ec92e7d63d4f3cfcf Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Thu, 22 Jan 2015 18:21:02 -0800
Subject: [PATCH 14/44] remove some files

---
 replace.sh | 8 --------
 1 file changed, 8 deletions(-)
 delete mode 100755 replace.sh

diff --git a/replace.sh b/replace.sh
deleted file mode 100755
index 8e18923e..00000000
--- a/replace.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-shopt -s globstar
-
-origin='github.com/google/grpc-go/metadata'
-replace='github.com/google/grpc-go/rpc/metadata'
-sed -i "s%$origin%$replace%g" **/*.go
-

From e5a5eb12dc984fb720265d4b59cc624839ccb050 Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Thu, 22 Jan 2015 18:36:45 -0800
Subject: [PATCH 15/44] Fix the missed import path changes.

---
 rpc/interop/client/client.go | 2 +-
 rpc/interop/server/server.go | 2 +-
 rpc/test/end2end_test.go     | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/rpc/interop/client/client.go b/rpc/interop/client/client.go
index caf7c1e4..1562a744 100644
--- a/rpc/interop/client/client.go
+++ b/rpc/interop/client/client.go
@@ -43,7 +43,7 @@ import (
 	"github.com/golang/protobuf/proto"
 	"github.com/google/grpc-go/go"
 	"github.com/google/grpc-go/rpc/credentials"
-	testpb "github.com/google/grpc-go/interop/testdata"
+	testpb "github.com/google/grpc-go/rpc/interop/testdata"
 	"golang.org/x/net/context"
 )
 
diff --git a/rpc/interop/server/server.go b/rpc/interop/server/server.go
index 4305f015..22a16f59 100644
--- a/rpc/interop/server/server.go
+++ b/rpc/interop/server/server.go
@@ -43,7 +43,7 @@ import (
 	"time"
 
 	"github.com/google/grpc-go/rpc/credentials"
-	testpb "github.com/google/grpc-go/interop/testdata"
+	testpb "github.com/google/grpc-go/rpc/interop/testdata"
 	"github.com/google/grpc-go/rpc"
 	"github.com/golang/protobuf/proto"
 	"golang.org/x/net/context"
diff --git a/rpc/test/end2end_test.go b/rpc/test/end2end_test.go
index 05abbfaf..dc084202 100644
--- a/rpc/test/end2end_test.go
+++ b/rpc/test/end2end_test.go
@@ -50,7 +50,7 @@ import (
 	"github.com/google/grpc-go/rpc/credentials"
 	"github.com/google/grpc-go/rpc/metadata"
 	"github.com/google/grpc-go/rpc"
-	testpb "github.com/google/grpc-go/test/testdata"
+	testpb "github.com/google/grpc-go/rpc/test/testdata"
 	"github.com/golang/protobuf/proto"
 	"golang.org/x/net/context"
 )

From 2991390717baee48975a81c7e73c7516c71137fc Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Thu, 22 Jan 2015 18:48:55 -0800
Subject: [PATCH 16/44] fix typo

---
 rpc/interop/client/client.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/rpc/interop/client/client.go b/rpc/interop/client/client.go
index 1562a744..2e9c7542 100644
--- a/rpc/interop/client/client.go
+++ b/rpc/interop/client/client.go
@@ -41,7 +41,7 @@ import (
 	"strconv"
 
 	"github.com/golang/protobuf/proto"
-	"github.com/google/grpc-go/go"
+	"github.com/google/grpc-go/rpc"
 	"github.com/google/grpc-go/rpc/credentials"
 	testpb "github.com/google/grpc-go/rpc/interop/testdata"
 	"golang.org/x/net/context"

From 0bc4587a2c7b115a850a724c350a0ae3ed0779c0 Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Fri, 23 Jan 2015 15:00:56 -0800
Subject: [PATCH 17/44] Correct the ServerName setting for TLS credentials.

---
 rpc/interop/client/client.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/rpc/interop/client/client.go b/rpc/interop/client/client.go
index 2e9c7542..6373e090 100644
--- a/rpc/interop/client/client.go
+++ b/rpc/interop/client/client.go
@@ -227,7 +227,7 @@ func main() {
 	serverAddr := net.JoinHostPort(*serverHost, strconv.Itoa(*serverPort))
 	var opts []rpc.DialOption
 	if *useTLS {
-		sn := *serverHost
+		var sn string
 		if *tlsServerName != "" {
 			sn = *tlsServerName
 		}

From 890b893b806b8a4972ab469d46b38234bdb1d60a Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Fri, 23 Jan 2015 16:14:23 -0800
Subject: [PATCH 18/44] i) Fix some English errors; ii) Let
 ClientTransport.Close() and ServerTransport.Close() return error to follow
 the style of io.Closer

---
 rpc/codes/codes.go                      | 6 +++---
 rpc/transport/http2_client_transport.go | 5 +++--
 rpc/transport/http2_server_transport.go | 5 +++--
 rpc/transport/transport.go              | 4 ++--
 4 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/rpc/codes/codes.go b/rpc/codes/codes.go
index c1018b44..85d1eb02 100644
--- a/rpc/codes/codes.go
+++ b/rpc/codes/codes.go
@@ -35,11 +35,11 @@
 // consistent across various languages.
 package codes
 
-// An Code is an unsigned 32-bit error code as defined gRPC spec.
+// A Code is an unsigned 32-bit error code as defined in the gRPC spec.
 type Code uint32
 
 const (
-	// OK means returned on success
+	// OK is returned on success.
 	OK Code = 0
 
 	// Canceled indicates the operation was cancelled (typically by the caller).
@@ -69,7 +69,7 @@ const (
 	// not found.
 	NotFound Code = 5
 
-	// AlreadyExists means some entity that we attempted to create
+	// AlreadyExists means an attempt to create an entity failed because one
 	// already exists.
 	AlreadyExists Code = 6
 
diff --git a/rpc/transport/http2_client_transport.go b/rpc/transport/http2_client_transport.go
index af7347b4..e87c01b5 100644
--- a/rpc/transport/http2_client_transport.go
+++ b/rpc/transport/http2_client_transport.go
@@ -304,12 +304,12 @@ func (t *http2Client) CloseStream(s *Stream, err error) {
 // Close kicks off the shutdown process of the transport. This should be called
 // only once on a transport. Once it is called, the transport should not be
 // accessed any more.
-func (t *http2Client) Close() {
+func (t *http2Client) Close() (err error) {
 	t.mu.Lock()
 	t.state = closing
 	t.mu.Unlock()
 	close(t.shutdownChan)
-	t.conn.Close()
+	err = t.conn.Close()
 	t.mu.Lock()
 	streams := t.activeStreams
 	t.activeStreams = nil
@@ -324,6 +324,7 @@ func (t *http2Client) Close() {
 		s.mu.Unlock()
 		s.write(recvMsg{err: ErrConnClosing})
 	}
+	return
 }
 
 // Write formats the data into HTTP2 data frame(s) and sends it out. The caller
diff --git a/rpc/transport/http2_server_transport.go b/rpc/transport/http2_server_transport.go
index d486e0b8..119f62b7 100644
--- a/rpc/transport/http2_server_transport.go
+++ b/rpc/transport/http2_server_transport.go
@@ -561,7 +561,7 @@ func (t *http2Server) controller() {
 // Close starts shutting down the http2Server transport.
 // TODO(zhaoq): Now the destruction is not blocked on any pending streams. This
 // could cause some resource issue. Revisit this later.
-func (t *http2Server) Close() {
+func (t *http2Server) Close() (err error) {
 	t.mu.Lock()
 	if t.state == closing {
 		t.mu.Unlock()
@@ -572,11 +572,12 @@ func (t *http2Server) Close() {
 	t.activeStreams = nil
 	t.mu.Unlock()
 	close(t.shutdownChan)
-	t.conn.Close()
+	err = t.conn.Close()
 	// Notify all active streams.
 	for _, s := range streams {
 		s.write(recvMsg{err: ErrConnClosing})
 	}
+	return
 }
 
 // closeStream clears the footprint of a stream when the stream is not needed
diff --git a/rpc/transport/transport.go b/rpc/transport/transport.go
index 5c3ceee1..568da2ed 100644
--- a/rpc/transport/transport.go
+++ b/rpc/transport/transport.go
@@ -333,7 +333,7 @@ type ClientTransport interface {
 	// Close tears down this transport. Once it returns, the transport
 	// should not be accessed any more. The caller must make sure this
 	// is called only once.
-	Close()
+	Close() error
 
 	// Write sends the data for the given stream. A nil stream indicates
 	// the write is to be performed on the transport as a whole.
@@ -370,7 +370,7 @@ type ServerTransport interface {
 	// Close tears down the transport. Once it is called, the transport
 	// should not be accessed any more. All the pending streams and their
 	// handlers will be terminated asynchronously.
-	Close()
+	Close() error
 }
 
 // StreamErrorf creates an StreamError with the specified error code and description.

From 8fd8a8b40077dbf6692294058a08e49645bd099e Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Fri, 23 Jan 2015 17:15:08 -0800
Subject: [PATCH 19/44] Polish some comments

---
 rpc/call.go       | 2 +-
 rpc/clientconn.go | 7 +++----
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/rpc/call.go b/rpc/call.go
index cf52316b..d0534724 100644
--- a/rpc/call.go
+++ b/rpc/call.go
@@ -115,7 +115,7 @@ func Invoke(ctx context.Context, method string, args, reply proto.Message, cc *C
 		Delay: false,
 	}
 	ts := 0
-	var lastErr error // record the error happened in the last iteration
+	var lastErr error // record the error that happened
 	for {
 		var (
 			err    error
diff --git a/rpc/clientconn.go b/rpc/clientconn.go
index ff50312d..8ccf74ad 100644
--- a/rpc/clientconn.go
+++ b/rpc/clientconn.go
@@ -49,7 +49,6 @@ import (
 type dialOptions struct {
 	protocol    string
 	authOptions []credentials.Credentials
-	// TBD: other options
 }
 
 // DialOption configures how we set up the connection including auth
@@ -64,8 +63,8 @@ func WithClientTLS(creds credentials.TransportAuthenticator) DialOption {
 	}
 }
 
-// WithComputeEngine returns a DialOption which sets a
-// credentials which uses application default credentials as provided to
+// WithComputeEngine returns a DialOption which sets
+// credentials which use application default credentials as provided to
 // Google Compute Engine. Note that TLS credentials is typically also
 // needed. If it is the case, users need to pass WithTLS option too.
 func WithComputeEngine(creds credentials.Credentials) DialOption {
@@ -76,7 +75,7 @@ func WithComputeEngine(creds credentials.Credentials) DialOption {
 
 // Dial creates a client connection the given target.
 // TODO(zhaoq): Have an option to make Dial return immediately without waiting
-// for connection complete.
+// for connection to complete.
 func Dial(target string, opts ...DialOption) (*ClientConn, error) {
 	if target == "" {
 		return nil, fmt.Errorf("rpc.Dial: target is empty")

From 9f80723bc5f05e77444182fe2d5da5f9ab3faacd Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Mon, 26 Jan 2015 19:07:37 -0800
Subject: [PATCH 20/44] Given a tiny timeout, NewStream could timeout before a
 stream is created. In that case we must not call hpack.Encoder.WriteField
 because hpack.Encoder is stateful.

---
 rpc/transport/http2_client_transport.go | 20 ++++++++++++--------
 rpc/transport/http2_server_transport.go |  4 ++--
 rpc/transport/http_util.go              |  4 ++--
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/rpc/transport/http2_client_transport.go b/rpc/transport/http2_client_transport.go
index e87c01b5..beb5095d 100644
--- a/rpc/transport/http2_client_transport.go
+++ b/rpc/transport/http2_client_transport.go
@@ -42,12 +42,12 @@ import (
 	"sync"
 	"time"
 
+	"github.com/bradfitz/http2"
+	"github.com/bradfitz/http2/hpack"
 	"github.com/google/grpc-go/rpc/codes"
 	"github.com/google/grpc-go/rpc/credentials"
 	"github.com/google/grpc-go/rpc/metadata"
 	"golang.org/x/net/context"
-	"github.com/bradfitz/http2/hpack"
-	"github.com/bradfitz/http2"
 )
 
 // http2Client implements the ClientTransport interface with HTTP2.
@@ -201,6 +201,14 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
 			t.writableChan <- 0
 		}
 	}()
+	// Record the timeout value on the context.
+	var timeout time.Duration
+	if dl, ok := ctx.Deadline(); ok {
+		timeout = dl.Sub(time.Now())
+		if timeout <= 0 {
+			return nil, ContextErr(context.DeadlineExceeded)
+		}
+	}
 	// HPACK encodes various headers.
 	t.hBuf.Reset()
 	t.hEnc.WriteField(hpack.HeaderField{Name: ":method", Value: "POST"})
@@ -218,12 +226,8 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
 			t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: v})
 		}
 	}
-	if dl, ok := ctx.Deadline(); ok {
-		to := dl.Sub(time.Now())
-		if to <= 0 {
-			return nil, ContextErr(context.DeadlineExceeded)
-		}
-		t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-timeout", Value: timeoutEncode(to)})
+	if timeout > 0 {
+		t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-timeout", Value: timeoutEncode(timeout)})
 	}
 	if md, ok := metadata.FromContext(ctx); ok {
 		for k, v := range md.Copy() {
diff --git a/rpc/transport/http2_server_transport.go b/rpc/transport/http2_server_transport.go
index 119f62b7..ce793d28 100644
--- a/rpc/transport/http2_server_transport.go
+++ b/rpc/transport/http2_server_transport.go
@@ -43,11 +43,11 @@ import (
 	"strconv"
 	"sync"
 
+	"github.com/bradfitz/http2"
+	"github.com/bradfitz/http2/hpack"
 	"github.com/google/grpc-go/rpc/codes"
 	"github.com/google/grpc-go/rpc/metadata"
 	"golang.org/x/net/context"
-	"github.com/bradfitz/http2/hpack"
-	"github.com/bradfitz/http2"
 )
 
 // http2Server implements the ServerTransport interface with HTTP2.
diff --git a/rpc/transport/http_util.go b/rpc/transport/http_util.go
index 5d1a871a..33a17a1d 100644
--- a/rpc/transport/http_util.go
+++ b/rpc/transport/http_util.go
@@ -39,10 +39,10 @@ import (
 	"strconv"
 	"time"
 
+	"github.com/bradfitz/http2"
+	"github.com/bradfitz/http2/hpack"
 	"github.com/google/grpc-go/rpc/codes"
 	"github.com/google/grpc-go/rpc/metadata"
-	"github.com/bradfitz/http2/hpack"
-	"github.com/bradfitz/http2"
 )
 
 const (

From 6d347a8be71d891ed7939d8032e9def9b563395e Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Tue, 27 Jan 2015 15:51:10 -0800
Subject: [PATCH 21/44] Allow --tls_ca_file= to use the host's root CA set in
 interop client.

---
 rpc/clientconn.go            |  1 +
 rpc/interop/client/client.go | 12 +++++++++---
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/rpc/clientconn.go b/rpc/clientconn.go
index 8ccf74ad..9b18a387 100644
--- a/rpc/clientconn.go
+++ b/rpc/clientconn.go
@@ -132,6 +132,7 @@ func (cc *ClientConn) resetTransport(closeTransport bool) error {
 		}
 		newTransport, err := transport.NewClientTransport(cc.dopts.protocol, cc.target, cc.dopts.authOptions)
 		if err != nil {
+			// TODO(zhaoq): Record the error with glog.V.
 			closeTransport = false
 			time.Sleep(backoff(retries))
 			retries++
diff --git a/rpc/interop/client/client.go b/rpc/interop/client/client.go
index 6373e090..5537c08a 100644
--- a/rpc/interop/client/client.go
+++ b/rpc/interop/client/client.go
@@ -231,9 +231,15 @@ func main() {
 		if *tlsServerName != "" {
 			sn = *tlsServerName
 		}
-		creds, err := credentials.NewClientTLSFromFile(*caFile, sn)
-		if err != nil {
-			log.Fatalf("Failed to create credentials %v", err)
+		var creds credentials.TransportAuthenticator
+		if *caFile != "" {
+			var err error
+			creds, err = credentials.NewClientTLSFromFile(*caFile, sn)
+			if err != nil {
+				log.Fatalf("Failed to create credentials %v", err)
+			}
+		} else {
+			creds = credentials.NewClientTLSFromCert(nil, sn)
 		}
 		opts = append(opts, rpc.WithClientTLS(creds))
 	}

From 56dc3ff09524ba8d9125aec7ec5a48bdc144e809 Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Tue, 27 Jan 2015 17:40:23 -0800
Subject: [PATCH 22/44] Fix the setup for no-TLS case.

---
 rpc/test/end2end_test.go | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/rpc/test/end2end_test.go b/rpc/test/end2end_test.go
index dc084202..84ce6b0d 100644
--- a/rpc/test/end2end_test.go
+++ b/rpc/test/end2end_test.go
@@ -170,20 +170,25 @@ func setUp(useTLS bool, maxStream uint32) (s *rpc.Server, mc testpb.MathClient)
 	testpb.RegisterService(s, ms)
 	go s.Run()
 	addr := "localhost:" + port
-	creds, err := credentials.NewClientTLSFromFile(tlsDir+"ca.pem", "x.test.youtube.com")
-	if err != nil {
-		log.Fatalf("Failed to create credentials %v", err)
+	var conn *rpc.ClientConn
+	if useTLS {
+		creds, err := credentials.NewClientTLSFromFile(tlsDir+"ca.pem", "x.test.youtube.com")
+		if err != nil {
+			log.Fatalf("Failed to create credentials %v", err)
+		}
+		conn, err = rpc.Dial(addr, rpc.WithClientTLS(creds))
+	} else {
+		conn, err = rpc.Dial(addr)
 	}
-	conn, err := rpc.Dial(addr, rpc.WithClientTLS(creds))
 	if err != nil {
-		log.Fatalf("Dial(%v) = %v", conn, err)
+		log.Fatalf("Dial(%q) = %v", addr, err)
 	}
 	mc = testpb.NewMathClient(conn)
 	return
 }
 
 func TestFailedRPC(t *testing.T) {
-	s, mc := setUp(true, math.MaxUint32)
+	s, mc := setUp(false, math.MaxUint32)
 	defer s.Stop()
 	args := &testpb.DivArgs{
 		Dividend: proto.Int64(8),

From 330d92ae90f9b371afd84cc04603aa180a442a55 Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Tue, 27 Jan 2015 17:54:18 -0800
Subject: [PATCH 23/44] If a crappy client sends grpc-timeout 0 to the server.
 The server cannot distinguish between unset and set-with-0. Make it be able
 to.

---
 rpc/transport/http2_server_transport.go | 3 ++-
 rpc/transport/http_util.go              | 6 ++++--
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/rpc/transport/http2_server_transport.go b/rpc/transport/http2_server_transport.go
index ce793d28..f2d4a211 100644
--- a/rpc/transport/http2_server_transport.go
+++ b/rpc/transport/http2_server_transport.go
@@ -156,7 +156,7 @@ func (t *http2Server) operateHeaders(hDec *hpackDecoder, s *Stream, frame header
 	s.windowHandler = func(n int) {
 		t.addRecvQuota(s, n)
 	}
-	if hDec.state.timeout > 0 {
+	if hDec.state.timeoutSet > 0 {
 		s.ctx, s.cancel = context.WithTimeout(context.TODO(), hDec.state.timeout)
 	} else {
 		s.ctx, s.cancel = context.WithCancel(context.TODO())
@@ -426,6 +426,7 @@ func (t *http2Server) WriteStatus(s *Stream, statusCode codes.Code, statusDesc s
 	}
 	s.mu.RUnlock()
 	if _, err := wait(s.ctx, t.shutdownChan, t.writableChan); err != nil {
+		// TODO(zhaoq): Print some errors using glog, e.g., glog.V(1).
 		return err
 	}
 	t.hBuf.Reset()
diff --git a/rpc/transport/http_util.go b/rpc/transport/http_util.go
index 33a17a1d..d2c9356b 100644
--- a/rpc/transport/http_util.go
+++ b/rpc/transport/http_util.go
@@ -87,8 +87,9 @@ type decodeState struct {
 	statusCode codes.Code
 	statusDesc string
 	// Server side only fields.
-	timeout time.Duration
-	method  string
+	timeoutSet bool
+	timeout    time.Duration
+	method     string
 	// key-value metadata map from the peer.
 	mdata map[string]string
 }
@@ -144,6 +145,7 @@ func newHPACKDecoder() *hpackDecoder {
 		case "grpc-message":
 			d.state.statusDesc = f.Value
 		case "grpc-timeout":
+			d.state.timeoutSet = true
 			var err error
 			d.state.timeout, err = timeoutDecode(f.Value)
 			if err != nil {

From 0cb60b315445478cc5716eed745f83d7a36d2b4d Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Tue, 27 Jan 2015 17:56:55 -0800
Subject: [PATCH 24/44] fix a bug in the preivous commit.

---
 rpc/transport/http2_server_transport.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/rpc/transport/http2_server_transport.go b/rpc/transport/http2_server_transport.go
index f2d4a211..f7058a5b 100644
--- a/rpc/transport/http2_server_transport.go
+++ b/rpc/transport/http2_server_transport.go
@@ -156,7 +156,7 @@ func (t *http2Server) operateHeaders(hDec *hpackDecoder, s *Stream, frame header
 	s.windowHandler = func(n int) {
 		t.addRecvQuota(s, n)
 	}
-	if hDec.state.timeoutSet > 0 {
+	if hDec.state.timeoutSet {
 		s.ctx, s.cancel = context.WithTimeout(context.TODO(), hDec.state.timeout)
 	} else {
 		s.ctx, s.cancel = context.WithCancel(context.TODO())

From 3befeb9b910826a3ecb9af7f3b048b30953200c9 Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Tue, 27 Jan 2015 18:12:14 -0800
Subject: [PATCH 25/44] run gofmt

---
 rpc/call.go              | 2 +-
 rpc/rpc_util.go          | 2 +-
 rpc/rpc_util_test.go     | 2 +-
 rpc/server.go            | 2 +-
 rpc/stream.go            | 2 +-
 rpc/test/end2end_test.go | 4 ++--
 6 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/rpc/call.go b/rpc/call.go
index d0534724..82e0d7eb 100644
--- a/rpc/call.go
+++ b/rpc/call.go
@@ -36,10 +36,10 @@ package rpc
 import (
 	"io"
 
+	"github.com/golang/protobuf/proto"
 	"github.com/google/grpc-go/rpc/codes"
 	"github.com/google/grpc-go/rpc/metadata"
 	"github.com/google/grpc-go/rpc/transport"
-	"github.com/golang/protobuf/proto"
 	"golang.org/x/net/context"
 )
 
diff --git a/rpc/rpc_util.go b/rpc/rpc_util.go
index b38ef701..5b564280 100644
--- a/rpc/rpc_util.go
+++ b/rpc/rpc_util.go
@@ -42,10 +42,10 @@ import (
 	"os"
 	"time"
 
+	"github.com/golang/protobuf/proto"
 	"github.com/google/grpc-go/rpc/codes"
 	"github.com/google/grpc-go/rpc/metadata"
 	"github.com/google/grpc-go/rpc/transport"
-	"github.com/golang/protobuf/proto"
 	"golang.org/x/net/context"
 )
 
diff --git a/rpc/rpc_util_test.go b/rpc/rpc_util_test.go
index 4c08c602..5219cd80 100644
--- a/rpc/rpc_util_test.go
+++ b/rpc/rpc_util_test.go
@@ -41,9 +41,9 @@ import (
 	"testing"
 	"time"
 
+	"github.com/golang/protobuf/proto"
 	"github.com/google/grpc-go/rpc/codes"
 	"github.com/google/grpc-go/rpc/transport"
-	"github.com/golang/protobuf/proto"
 	"golang.org/x/net/context"
 )
 
diff --git a/rpc/server.go b/rpc/server.go
index 2dcd4ff3..0199d80e 100644
--- a/rpc/server.go
+++ b/rpc/server.go
@@ -42,11 +42,11 @@ import (
 	"strings"
 	"sync"
 
+	"github.com/golang/protobuf/proto"
 	"github.com/google/grpc-go/rpc/codes"
 	"github.com/google/grpc-go/rpc/credentials"
 	"github.com/google/grpc-go/rpc/metadata"
 	"github.com/google/grpc-go/rpc/transport"
-	"github.com/golang/protobuf/proto"
 	"golang.org/x/net/context"
 )
 
diff --git a/rpc/stream.go b/rpc/stream.go
index 13a96216..58a67045 100644
--- a/rpc/stream.go
+++ b/rpc/stream.go
@@ -36,10 +36,10 @@ package rpc
 import (
 	"io"
 
+	"github.com/golang/protobuf/proto"
 	"github.com/google/grpc-go/rpc/codes"
 	"github.com/google/grpc-go/rpc/metadata"
 	"github.com/google/grpc-go/rpc/transport"
-	"github.com/golang/protobuf/proto"
 	"golang.org/x/net/context"
 )
 
diff --git a/rpc/test/end2end_test.go b/rpc/test/end2end_test.go
index 84ce6b0d..68ba0153 100644
--- a/rpc/test/end2end_test.go
+++ b/rpc/test/end2end_test.go
@@ -46,12 +46,12 @@ import (
 	"testing"
 	"time"
 
+	"github.com/golang/protobuf/proto"
+	"github.com/google/grpc-go/rpc"
 	"github.com/google/grpc-go/rpc/codes"
 	"github.com/google/grpc-go/rpc/credentials"
 	"github.com/google/grpc-go/rpc/metadata"
-	"github.com/google/grpc-go/rpc"
 	testpb "github.com/google/grpc-go/rpc/test/testdata"
-	"github.com/golang/protobuf/proto"
 	"golang.org/x/net/context"
 )
 

From 2098bc80fdd649e6dd1c611b1c81726a42ca5dc5 Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Wed, 28 Jan 2015 13:28:34 -0800
Subject: [PATCH 26/44] Remove a log.Print in the test to avoid spamming

---
 rpc/transport/transport_test.go | 1 -
 1 file changed, 1 deletion(-)

diff --git a/rpc/transport/transport_test.go b/rpc/transport/transport_test.go
index 682585c4..41ccf0e3 100644
--- a/rpc/transport/transport_test.go
+++ b/rpc/transport/transport_test.go
@@ -258,7 +258,6 @@ func performOneRPC(ct ClientTransport) {
 	}
 	s, err := ct.NewStream(context.Background(), callHdr)
 	if err != nil {
-		log.Printf("failed to open stream: %v", err)
 		return
 	}
 	opts := Options{

From a485dd03758317d66672b0655d537a6b12a3dc98 Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Wed, 28 Jan 2015 13:49:18 -0800
Subject: [PATCH 27/44] change MD to type MD map[string]string

---
 rpc/metadata/metadata.go | 35 +++++++++++++++--------------------
 1 file changed, 15 insertions(+), 20 deletions(-)

diff --git a/rpc/metadata/metadata.go b/rpc/metadata/metadata.go
index 79be970d..425a1825 100644
--- a/rpc/metadata/metadata.go
+++ b/rpc/metadata/metadata.go
@@ -84,33 +84,28 @@ func DecodeKeyValue(k, v string) (string, string, error) {
 }
 
 // MD is a mapping from metadata keys to values.
-type MD struct {
-	m map[string]string
-}
+type MD map[string]string
 
 // New creates a MD from given key-value map.
-func New(m map[string]string) (md MD) {
+func New(m map[string]string) MD {
+	md := MD{}
 	if len(m) == 0 {
-		return
+		return md
 	}
-	md.m = make(map[string]string)
 	for k, v := range m {
 		key, val := encodeKeyValue(k, v)
-		md.m[key] = val
+		md[key] = val
 	}
-	return
+	return md
 }
 
 // Pairs returns an MD formed by the mapping of key, value ...
 // Pairs panics if len(kv) is odd.
-func Pairs(kv ...string) (md MD) {
+func Pairs(kv ...string) MD {
 	if len(kv)%2 == 1 {
 		panic(fmt.Sprintf("Got the odd number of input pairs for metadata: %d", len(kv)))
 	}
-	if len(kv) == 0 {
-		return
-	}
-	md.m = make(map[string]string)
+	md := MD{}
 	var k string
 	for i, s := range kv {
 		if i%2 == 0 {
@@ -118,23 +113,23 @@ func Pairs(kv ...string) (md MD) {
 			continue
 		}
 		key, val := encodeKeyValue(k, s)
-		md.m[key] = val
+		md[key] = val
 	}
-	return
+	return md
 }
 
 // Len returns the length of md.
 func (md MD) Len() int {
-	return len(md.m)
+	return len(md)
 }
 
 // Copy returns a copy of md's mapping.
-func (md MD) Copy() (m map[string]string) {
-	m = make(map[string]string)
-	for k, v := range md.m {
+func (md MD) Copy() map[string]string {
+	m := make(map[string]string)
+	for k, v := range md {
 		m[k] = v
 	}
-	return
+	return m
 }
 
 type mdKey struct{}

From f3abfd9f63176e519b1d7cbe60bb1fa45fa00f53 Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Wed, 28 Jan 2015 13:53:44 -0800
Subject: [PATCH 28/44] Delete unnecessary logic

---
 rpc/metadata/metadata.go | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/rpc/metadata/metadata.go b/rpc/metadata/metadata.go
index 425a1825..45dbd18a 100644
--- a/rpc/metadata/metadata.go
+++ b/rpc/metadata/metadata.go
@@ -89,9 +89,6 @@ type MD map[string]string
 // New creates a MD from given key-value map.
 func New(m map[string]string) MD {
 	md := MD{}
-	if len(m) == 0 {
-		return md
-	}
 	for k, v := range m {
 		key, val := encodeKeyValue(k, v)
 		md[key] = val

From c52694457f78bdf2af1a51e509393786c38397ce Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Wed, 28 Jan 2015 15:59:12 -0800
Subject: [PATCH 29/44] Tune metadata package to simplify the code.

---
 rpc/call.go                             |  3 +--
 rpc/metadata/metadata.go                | 22 +++++------------
 rpc/stream.go                           |  6 +----
 rpc/test/end2end_test.go                | 32 ++++++++++++-------------
 rpc/transport/http2_client_transport.go |  2 +-
 rpc/transport/http2_server_transport.go |  4 ++--
 rpc/transport/transport.go              | 10 ++++----
 7 files changed, 31 insertions(+), 48 deletions(-)

diff --git a/rpc/call.go b/rpc/call.go
index 82e0d7eb..f92d1ebe 100644
--- a/rpc/call.go
+++ b/rpc/call.go
@@ -146,11 +146,10 @@ func Invoke(ctx context.Context, method string, args, reply proto.Message, cc *C
 			return toRPCErr(err)
 		}
 		// Try to acquire header metadata from the server if there is any.
-		m, err := stream.Header()
+		c.headerMD, err = stream.Header()
 		if err != nil {
 			return toRPCErr(err)
 		}
-		c.headerMD = metadata.New(m)
 		// Receive the response
 		lastErr = recv(stream, reply)
 		if _, ok := lastErr.(transport.ConnectionError); ok {
diff --git a/rpc/metadata/metadata.go b/rpc/metadata/metadata.go
index 45dbd18a..0caf2bbc 100644
--- a/rpc/metadata/metadata.go
+++ b/rpc/metadata/metadata.go
@@ -86,16 +86,6 @@ func DecodeKeyValue(k, v string) (string, string, error) {
 // MD is a mapping from metadata keys to values.
 type MD map[string]string
 
-// New creates a MD from given key-value map.
-func New(m map[string]string) MD {
-	md := MD{}
-	for k, v := range m {
-		key, val := encodeKeyValue(k, v)
-		md[key] = val
-	}
-	return md
-}
-
 // Pairs returns an MD formed by the mapping of key, value ...
 // Pairs panics if len(kv) is odd.
 func Pairs(kv ...string) MD {
@@ -115,18 +105,18 @@ func Pairs(kv ...string) MD {
 	return md
 }
 
-// Len returns the length of md.
+// Len returns the number of items in md.
 func (md MD) Len() int {
 	return len(md)
 }
 
-// Copy returns a copy of md's mapping.
-func (md MD) Copy() map[string]string {
-	m := make(map[string]string)
+// Copy returns a copy of md.
+func (md MD) Copy() MD {
+	out := MD{}
 	for k, v := range md {
-		m[k] = v
+		out[k] = v
 	}
-	return m
+	return out
 }
 
 type mdKey struct{}
diff --git a/rpc/stream.go b/rpc/stream.go
index 58a67045..59b125b8 100644
--- a/rpc/stream.go
+++ b/rpc/stream.go
@@ -110,11 +110,7 @@ func (cs *clientStream) Context() context.Context {
 // is any. Empty metadata.MD is returned if there is no header metadata.
 // It blocks if the metadata is not ready to read.
 func (cs *clientStream) Header() (md metadata.MD, err error) {
-	m, err := cs.s.Header()
-	if err != nil {
-		return md, err
-	}
-	return metadata.New(m), nil
+	return cs.s.Header()
 }
 
 // Trailer returns the trailer metadata from the server. It must be called
diff --git a/rpc/test/end2end_test.go b/rpc/test/end2end_test.go
index 68ba0153..c9ecd2d8 100644
--- a/rpc/test/end2end_test.go
+++ b/rpc/test/end2end_test.go
@@ -56,7 +56,7 @@ import (
 )
 
 var (
-	testMetadata = map[string]string{
+	testMetadata = metadata.MD{
 		"key1": "value1",
 		"key2": "value2",
 	}
@@ -208,18 +208,17 @@ func TestMetadataUnaryRPC(t *testing.T) {
 		Dividend: proto.Int64(8),
 		Divisor:  proto.Int64(2),
 	}
-	md := metadata.New(testMetadata)
-	ctx := metadata.NewContext(context.Background(), md)
+	ctx := metadata.NewContext(context.Background(), testMetadata)
 	var header, trailer metadata.MD
 	_, err := mc.Div(ctx, args, rpc.Header(&header), rpc.Trailer(&trailer))
 	if err != nil {
 		t.Fatalf("mathClient.Div(%v, _, _, _) = _, %v; want _, <nil>", ctx, err)
 	}
-	if !reflect.DeepEqual(testMetadata, header.Copy()) {
-		t.Fatalf("Received header metadata %v, want %v", header.Copy(), testMetadata)
+	if !reflect.DeepEqual(testMetadata, header) {
+		t.Fatalf("Received header metadata %v, want %v", header, testMetadata)
 	}
-	if !reflect.DeepEqual(testMetadata, trailer.Copy()) {
-		t.Fatalf("Received trailer metadata %v, want %v", trailer.Copy(), testMetadata)
+	if !reflect.DeepEqual(testMetadata, trailer) {
+		t.Fatalf("Received trailer metadata %v, want %v", trailer, testMetadata)
 	}
 }
 
@@ -234,7 +233,7 @@ func performOneRPC(t *testing.T, mc testpb.MathClient, wg *sync.WaitGroup) {
 		Remainder: proto.Int64(2),
 	}
 	if err != nil || !proto.Equal(reply, want) {
-		t.Fatalf(`mathClient.Div(_, _) = %v, %v; want %v, <nil>`, reply, err, want)
+		t.Errorf(`mathClient.Div(_, _) = %v, %v; want %v, <nil>`, reply, err, want)
 	}
 	wg.Done()
 }
@@ -322,7 +321,7 @@ func TestBidiStreaming(t *testing.T) {
 		go func() {
 			for _, args := range parseArgs(test.divs) {
 				if err := stream.Send(args); err != nil {
-					t.Fatal("Send failed: ", err)
+					t.Errorf("Send failed: ", err)
 					return
 				}
 			}
@@ -367,25 +366,24 @@ func parseArgs(divs []string) (args []*testpb.DivArgs) {
 func TestMetadataStreamingRPC(t *testing.T) {
 	s, mc := setUp(true, math.MaxUint32)
 	defer s.Stop()
-	md := metadata.New(testMetadata)
-	ctx := metadata.NewContext(context.Background(), md)
+	ctx := metadata.NewContext(context.Background(), testMetadata)
 	stream, err := mc.DivMany(ctx)
 	if err != nil {
 		t.Fatalf("Failed to create stream %v", err)
 	}
 	go func() {
 		headerMD, err := stream.Header()
-		if err != nil || !reflect.DeepEqual(testMetadata, headerMD.Copy()) {
-			t.Fatalf("#1 %v.Header() = %v, %v, want %v, <nil>", stream, headerMD, err, testMetadata)
+		if err != nil || !reflect.DeepEqual(testMetadata, headerMD) {
+			t.Errorf("#1 %v.Header() = %v, %v, want %v, <nil>", stream, headerMD, err, testMetadata)
 		}
 		// test the cached value.
 		headerMD, err = stream.Header()
-		if err != nil || !reflect.DeepEqual(testMetadata, headerMD.Copy()) {
-			t.Fatalf("#2 %v.Header() = %v, %v, want %v, <nil>", stream, headerMD, err, testMetadata)
+		if err != nil || !reflect.DeepEqual(testMetadata, headerMD) {
+			t.Errorf("#2 %v.Header() = %v, %v, want %v, <nil>", stream, headerMD, err, testMetadata)
 		}
 		for _, args := range parseArgs([]string{"1/1", "3/2", "2/3"}) {
 			if err := stream.Send(args); err != nil {
-				t.Fatalf("%v.Send(_) failed: %v", stream, err)
+				t.Errorf("%v.Send(_) failed: %v", stream, err)
 				return
 			}
 		}
@@ -399,7 +397,7 @@ func TestMetadataStreamingRPC(t *testing.T) {
 		}
 	}
 	trailerMD := stream.Trailer()
-	if !reflect.DeepEqual(testMetadata, trailerMD.Copy()) {
+	if !reflect.DeepEqual(testMetadata, trailerMD) {
 		t.Fatalf("%v.Trailer() = %v, want %v", stream, trailerMD, testMetadata)
 	}
 }
diff --git a/rpc/transport/http2_client_transport.go b/rpc/transport/http2_client_transport.go
index beb5095d..726a3f18 100644
--- a/rpc/transport/http2_client_transport.go
+++ b/rpc/transport/http2_client_transport.go
@@ -230,7 +230,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
 		t.hEnc.WriteField(hpack.HeaderField{Name: "grpc-timeout", Value: timeoutEncode(timeout)})
 	}
 	if md, ok := metadata.FromContext(ctx); ok {
-		for k, v := range md.Copy() {
+		for k, v := range md {
 			t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: v})
 		}
 	}
diff --git a/rpc/transport/http2_server_transport.go b/rpc/transport/http2_server_transport.go
index f7058a5b..d908f382 100644
--- a/rpc/transport/http2_server_transport.go
+++ b/rpc/transport/http2_server_transport.go
@@ -167,7 +167,7 @@ func (t *http2Server) operateHeaders(hDec *hpackDecoder, s *Stream, frame header
 	s.ctx = newContextWithStream(s.ctx, s)
 	// Attach the received metadata to the context.
 	if len(hDec.state.mdata) > 0 {
-		s.ctx = metadata.NewContext(s.ctx, metadata.New(hDec.state.mdata))
+		s.ctx = metadata.NewContext(s.ctx, hDec.state.mdata)
 	}
 
 	s.dec = &recvBufferReader{
@@ -404,7 +404,7 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error {
 	t.hBuf.Reset()
 	t.hEnc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"})
 	t.hEnc.WriteField(hpack.HeaderField{Name: "content-type", Value: "application/grpc"})
-	for k, v := range md.Copy() {
+	for k, v := range md {
 		t.hEnc.WriteField(hpack.HeaderField{Name: k, Value: v})
 	}
 	if err := t.writeHeaders(s, t.hBuf, false); err != nil {
diff --git a/rpc/transport/transport.go b/rpc/transport/transport.go
index 568da2ed..4139006b 100644
--- a/rpc/transport/transport.go
+++ b/rpc/transport/transport.go
@@ -181,9 +181,9 @@ type Stream struct {
 	// Close headerChan to indicate the end of reception of header metadata.
 	headerChan chan struct{}
 	// header caches the received header metadata.
-	header map[string]string
+	header metadata.MD
 	// The key-value map of trailer metadata.
-	trailer map[string]string
+	trailer metadata.MD
 
 	mu sync.RWMutex
 	// headerOK becomes true from the first header is about to send.
@@ -200,12 +200,12 @@ type Stream struct {
 // Header acquires the key-value pairs of header metadata once it
 // is available. It blocks until i) the metadata is ready or ii) there is no
 // header metadata or iii) the stream is cancelled/expired.
-func (s *Stream) Header() (map[string]string, error) {
+func (s *Stream) Header() (metadata.MD, error) {
 	select {
 	case <-s.ctx.Done():
 		return nil, ContextErr(s.ctx.Err())
 	case <-s.headerChan:
-		return s.header, nil
+		return s.header.Copy(), nil
 	}
 }
 
@@ -215,7 +215,7 @@ func (s *Stream) Header() (map[string]string, error) {
 func (s *Stream) Trailer() metadata.MD {
 	s.mu.RLock()
 	defer s.mu.RUnlock()
-	return metadata.New(s.trailer)
+	return s.trailer.Copy()
 }
 
 // ServerTransport returns the underlying ServerTransport for the stream.

From be58fe3a0960d78664fe330aae85b810ecf33dfd Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Wed, 28 Jan 2015 16:04:05 -0800
Subject: [PATCH 30/44] Fix the missing test in the previous commit

---
 rpc/metadata/metadata_test.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/rpc/metadata/metadata_test.go b/rpc/metadata/metadata_test.go
index ef3a1b8c..1ff61a26 100644
--- a/rpc/metadata/metadata_test.go
+++ b/rpc/metadata/metadata_test.go
@@ -69,7 +69,7 @@ func TestPairsMD(t *testing.T) {
 		md MD
 	}{
 		{[]string{}, MD{}},
-		{[]string{"k1", "v1", "k2", binaryValue}, New(map[string]string{
+		{[]string{"k1", "v1", "k2", binaryValue}, MD(map[string]string{
 			"k1":     "v1",
 			"k2-bin": "woA=",
 		})},

From f1ef72717076d990589e3bb7358ad27c2f9818ef Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Wed, 28 Jan 2015 22:49:38 -0800
Subject: [PATCH 31/44] Add metadata.New back

---
 rpc/metadata/metadata.go      | 13 ++++++++++++-
 rpc/metadata/metadata_test.go |  2 +-
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/rpc/metadata/metadata.go b/rpc/metadata/metadata.go
index 0caf2bbc..13b5a93a 100644
--- a/rpc/metadata/metadata.go
+++ b/rpc/metadata/metadata.go
@@ -83,9 +83,20 @@ func DecodeKeyValue(k, v string) (string, string, error) {
 	return key, string(val), nil
 }
 
-// MD is a mapping from metadata keys to values.
+// MD is a mapping from metadata keys to values. Users should use the following
+// two convenience functions New and Pairs to generate MD.
 type MD map[string]string
 
+// New creates a MD from given key-value map.
+func New(m map[string]string) MD {
+	md := MD{}
+	for k, v := range m {
+		key, val := encodeKeyValue(k, v)
+		md[key] = val
+	}
+	return md
+}
+
 // Pairs returns an MD formed by the mapping of key, value ...
 // Pairs panics if len(kv) is odd.
 func Pairs(kv ...string) MD {
diff --git a/rpc/metadata/metadata_test.go b/rpc/metadata/metadata_test.go
index 1ff61a26..ef3a1b8c 100644
--- a/rpc/metadata/metadata_test.go
+++ b/rpc/metadata/metadata_test.go
@@ -69,7 +69,7 @@ func TestPairsMD(t *testing.T) {
 		md MD
 	}{
 		{[]string{}, MD{}},
-		{[]string{"k1", "v1", "k2", binaryValue}, MD(map[string]string{
+		{[]string{"k1", "v1", "k2", binaryValue}, New(map[string]string{
 			"k1":     "v1",
 			"k2-bin": "woA=",
 		})},

From ec01f31e1a8bb7ae9f0acb993e8d7acd2faf4a02 Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Thu, 29 Jan 2015 13:38:54 -0800
Subject: [PATCH 32/44] Fix the broken import path in the generated code

---
 rpc/compiler/go_generator.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/rpc/compiler/go_generator.cc b/rpc/compiler/go_generator.cc
index 1f990c5b..e64c658c 100644
--- a/rpc/compiler/go_generator.cc
+++ b/rpc/compiler/go_generator.cc
@@ -507,7 +507,7 @@ string GetServices(const google::protobuf::FileDescriptor* file) {
         "\t\"io\"\n");
   }
   printer.Print(
-      "\t\"github.com/google/grpc-go\"\n"
+      "\t\"github.com/google/grpc-go/rpc\"\n"
       "\tcontext \"golang.org/x/net/context\"\n"
       "\tproto \"github.com/golang/protobuf/proto\"\n"
       ")\n\n");

From 796d00c003112be8e09e7f2a11035ff290ff5054 Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Thu, 29 Jan 2015 18:07:54 -0800
Subject: [PATCH 33/44] Make grpc-go proto plugin better: i) support external
 imports; ii) do not generate *_grpc.pb.go file if there is no service
 defined; ii) add more comment to gen.sh

---
 rpc/compiler/gen.sh          | 12 +++--
 rpc/compiler/go_generator.cc | 96 ++++++++++++++++++++++++++++++------
 rpc/compiler/go_plugin.cc    |  4 ++
 3 files changed, 95 insertions(+), 17 deletions(-)

diff --git a/rpc/compiler/gen.sh b/rpc/compiler/gen.sh
index 13fc58b4..cb56094c 100755
--- a/rpc/compiler/gen.sh
+++ b/rpc/compiler/gen.sh
@@ -1,8 +1,14 @@
 #!/bin/bash
 
-# Please run this under the same directory where the input proto stays. The
-# output will stay in the same directory. If this is not the behavior you want,
-# feel free to make your own scripts.
+# This script serves as an example to demonstrate how to generate the gRPC-Go
+# interface and the related messages.
+#
+# We suggest the importing paths in proto file are relative to $GOPATH/src and
+# this script should be run at $GOPATH/src.
+#
+# If this is not what you need, feel free to make your own scripts. Again, this
+# script is for demonstration purpose.
+# 
 locProtocGenGo=$1
 locGoPlugIn=$2
 proto=$3
diff --git a/rpc/compiler/go_generator.cc b/rpc/compiler/go_generator.cc
index e64c658c..21484f3b 100644
--- a/rpc/compiler/go_generator.cc
+++ b/rpc/compiler/go_generator.cc
@@ -79,12 +79,34 @@ string LowerCaseService(const string& service) {
   return ret;
 }
 
+std::string BadToUnderscore(std::string str) {
+  for (unsigned i = 0; i < str.size(); ++i) {
+    if (!std::isalnum(str[i])) {
+      str[i] = '_';
+    }
+  }
+  return str;
+}
+
+const string GetFullName(const string& selfPkg,
+                         const string& msgPkg,
+                         const string& msgName) {
+  if (selfPkg == msgPkg) {
+    return msgName;
+  }
+  return BadToUnderscore(msgPkg) + "." + msgName;
+}
+
 void PrintClientMethodDef(google::protobuf::io::Printer* printer,
                           const google::protobuf::MethodDescriptor* method,
                           map<string, string>* vars) {
   (*vars)["Method"] = method->name();
-  (*vars)["Request"] = method->input_type()->name();
-  (*vars)["Response"] = method->output_type()->name();
+  (*vars)["Request"] = GetFullName((*vars)["PackageName"],
+                                   method->input_type()->file()->package(),
+                                   method->input_type()->name());
+  (*vars)["Response"] = GetFullName((*vars)["PackageName"],
+                                   method->output_type()->file()->package(),
+                                   method->output_type()->name());
   if (NoStreaming(method)) {
     printer->Print(*vars,
                    "\t$Method$(ctx context.Context, in *$Request$, opts "
@@ -110,9 +132,12 @@ void PrintClientMethodImpl(google::protobuf::io::Printer* printer,
                            const google::protobuf::MethodDescriptor* method,
                            map<string, string>* vars) {
   (*vars)["Method"] = method->name();
-  (*vars)["Request"] = method->input_type()->name();
-  (*vars)["Response"] = method->output_type()->name();
-
+  (*vars)["Request"] = GetFullName((*vars)["PackageName"],
+                                   method->input_type()->file()->package(),
+                                   method->input_type()->name());
+  (*vars)["Response"] = GetFullName((*vars)["PackageName"],
+                                   method->output_type()->file()->package(),
+                                   method->output_type()->name());
   if (NoStreaming(method)) {
     printer->Print(
         *vars,
@@ -281,8 +306,12 @@ void PrintServerMethodDef(google::protobuf::io::Printer* printer,
                           const google::protobuf::MethodDescriptor* method,
                           map<string, string>* vars) {
   (*vars)["Method"] = method->name();
-  (*vars)["Request"] = method->input_type()->name();
-  (*vars)["Response"] = method->output_type()->name();
+  (*vars)["Request"] = GetFullName((*vars)["PackageName"],
+                                   method->input_type()->file()->package(),
+                                   method->input_type()->name());
+  (*vars)["Response"] = GetFullName((*vars)["PackageName"],
+                                   method->output_type()->file()->package(),
+                                   method->output_type()->name());
   if (NoStreaming(method)) {
     printer->Print(
         *vars,
@@ -301,8 +330,12 @@ void PrintServerHandler(google::protobuf::io::Printer* printer,
                         const google::protobuf::MethodDescriptor* method,
                         map<string, string>* vars) {
   (*vars)["Method"] = method->name();
-  (*vars)["Request"] = method->input_type()->name();
-  (*vars)["Response"] = method->output_type()->name();
+  (*vars)["Request"] = GetFullName((*vars)["PackageName"],
+                                   method->input_type()->file()->package(),
+                                   method->input_type()->name());
+  (*vars)["Response"] = GetFullName((*vars)["PackageName"],
+                                   method->output_type()->file()->package(),
+                                   method->output_type()->name());
   if (NoStreaming(method)) {
     printer->Print(
         *vars,
@@ -480,13 +513,46 @@ void PrintServer(google::protobuf::io::Printer* printer,
       "}\n\n");
 }
 
-std::string BadToUnderscore(std::string str) {
-  for (unsigned i = 0; i < str.size(); ++i) {
-    if (!std::isalnum(str[i])) {
-      str[i] = '_';
+void PrintMessageImports(
+    google::protobuf::io::Printer* printer,
+    const google::protobuf::FileDescriptor* file,
+    map<string, string>* vars) {
+  set<const google::protobuf::FileDescriptor*> descs;
+  set<string> importedPkgs;
+  for (int i = 0; i < file->service_count(); ++i) {
+    const google::protobuf::ServiceDescriptor* service = file->service(i);
+    for (int j = 0; j < service->method_count(); ++j) {
+      const google::protobuf::MethodDescriptor* method = service->method(i);
+      // Remove duplicated imports.
+      if (importedPkgs.find(
+          method->input_type()->file()->package()) == importedPkgs.end()) {
+        descs.insert(method->input_type()->file());
+        importedPkgs.insert(method->input_type()->file()->package());
+      }
+      if (importedPkgs.find(
+          method->output_type()->file()->package()) == importedPkgs.end()) {
+        descs.insert(method->output_type()->file());
+        importedPkgs.insert(method->output_type()->file()->package());
+      }
     }
   }
-  return str;
+
+  for (auto fd : descs) {
+    if (fd->package() == (*vars)["PackageName"]) {
+      continue;
+    }
+    string name = fd->name();
+    string import_path = "import \"";
+    if (name.find('/') == string::npos) {
+      // Assume all the proto in the same directory belong to the same package.
+      continue;
+    } else {
+      import_path += name.substr(0, name.find_last_of('/')) + "\"";
+    }
+    printer->Print(import_path.c_str());
+    printer->Print("\n");
+  }
+  printer->Print("\n");
 }
 
 string GetServices(const google::protobuf::FileDescriptor* file) {
@@ -512,6 +578,8 @@ string GetServices(const google::protobuf::FileDescriptor* file) {
       "\tproto \"github.com/golang/protobuf/proto\"\n"
       ")\n\n");
 
+  PrintMessageImports(&printer, file, &vars);
+
   // $Package$ is used to fully qualify method names.
   vars["Package"] = file->package();
   if (!file->package().empty()) {
diff --git a/rpc/compiler/go_plugin.cc b/rpc/compiler/go_plugin.cc
index bcd637d2..79423164 100644
--- a/rpc/compiler/go_plugin.cc
+++ b/rpc/compiler/go_plugin.cc
@@ -58,6 +58,10 @@ class GoGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
                         const string& parameter,
                         google::protobuf::compiler::GeneratorContext* context,
                         string* error) const {
+    if (file->service_count() <= 0) {
+      // Do not generate anything if there is no rpc service defined.
+      return true;
+    }
     // Get output file name.
     string file_name;
     if (file->name().size() > 6 &&

From 40dc264aaf3aff5f63650265cc67a2cc8cc49395 Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Fri, 30 Jan 2015 18:27:23 -0800
Subject: [PATCH 34/44] Revise codegen plugin to accommodate more cases and fix
 some bugs

---
 rpc/compiler/go_generator.cc | 101 ++++++++++++++++++-----------------
 1 file changed, 53 insertions(+), 48 deletions(-)

diff --git a/rpc/compiler/go_generator.cc b/rpc/compiler/go_generator.cc
index 21484f3b..0c2ce94a 100644
--- a/rpc/compiler/go_generator.cc
+++ b/rpc/compiler/go_generator.cc
@@ -44,6 +44,9 @@ using namespace std;
 
 namespace grpc_go_generator {
 
+static map<string, string> g_import_alias;
+static set<string> g_imports;
+
 bool NoStreaming(const google::protobuf::MethodDescriptor* method) {
   return !method->client_streaming() && !method->server_streaming();
 }
@@ -88,25 +91,32 @@ std::string BadToUnderscore(std::string str) {
   return str;
 }
 
-const string GetFullName(const string& selfPkg,
-                         const string& msgPkg,
-                         const string& msgName) {
-  if (selfPkg == msgPkg) {
-    return msgName;
+string GenerateFullPackage(const google::protobuf::FileDescriptor* file) {
+  // In opensouce environment, assume each directory has at most one package.
+  size_t pos = file->name().find_last_of('/');
+  if (pos != string::npos) {
+    return file->name().substr(0, pos);
   }
-  return BadToUnderscore(msgPkg) + "." + msgName;
+  return "";
+}
+
+const string GetFullName(const google::protobuf::Descriptor* desc) {
+  string pkg = GenerateFullPackage(desc->file());
+  if (g_imports.find(pkg) == g_imports.end()) {
+    return desc->name();
+  }
+  if (g_import_alias.find(pkg) != g_import_alias.end()) {
+    return g_import_alias[pkg] + "." + desc->name();
+  }
+  return BadToUnderscore(desc->file()->package()) + "." + desc->name();
 }
 
 void PrintClientMethodDef(google::protobuf::io::Printer* printer,
                           const google::protobuf::MethodDescriptor* method,
                           map<string, string>* vars) {
   (*vars)["Method"] = method->name();
-  (*vars)["Request"] = GetFullName((*vars)["PackageName"],
-                                   method->input_type()->file()->package(),
-                                   method->input_type()->name());
-  (*vars)["Response"] = GetFullName((*vars)["PackageName"],
-                                   method->output_type()->file()->package(),
-                                   method->output_type()->name());
+  (*vars)["Request"] = GetFullName(method->input_type());
+  (*vars)["Response"] = GetFullName(method->output_type());
   if (NoStreaming(method)) {
     printer->Print(*vars,
                    "\t$Method$(ctx context.Context, in *$Request$, opts "
@@ -132,12 +142,8 @@ void PrintClientMethodImpl(google::protobuf::io::Printer* printer,
                            const google::protobuf::MethodDescriptor* method,
                            map<string, string>* vars) {
   (*vars)["Method"] = method->name();
-  (*vars)["Request"] = GetFullName((*vars)["PackageName"],
-                                   method->input_type()->file()->package(),
-                                   method->input_type()->name());
-  (*vars)["Response"] = GetFullName((*vars)["PackageName"],
-                                   method->output_type()->file()->package(),
-                                   method->output_type()->name());
+  (*vars)["Request"] = GetFullName(method->input_type());
+  (*vars)["Response"] = GetFullName(method->output_type());
   if (NoStreaming(method)) {
     printer->Print(
         *vars,
@@ -306,12 +312,8 @@ void PrintServerMethodDef(google::protobuf::io::Printer* printer,
                           const google::protobuf::MethodDescriptor* method,
                           map<string, string>* vars) {
   (*vars)["Method"] = method->name();
-  (*vars)["Request"] = GetFullName((*vars)["PackageName"],
-                                   method->input_type()->file()->package(),
-                                   method->input_type()->name());
-  (*vars)["Response"] = GetFullName((*vars)["PackageName"],
-                                   method->output_type()->file()->package(),
-                                   method->output_type()->name());
+  (*vars)["Request"] = GetFullName(method->input_type());
+  (*vars)["Response"] = GetFullName(method->output_type());
   if (NoStreaming(method)) {
     printer->Print(
         *vars,
@@ -330,12 +332,8 @@ void PrintServerHandler(google::protobuf::io::Printer* printer,
                         const google::protobuf::MethodDescriptor* method,
                         map<string, string>* vars) {
   (*vars)["Method"] = method->name();
-  (*vars)["Request"] = GetFullName((*vars)["PackageName"],
-                                   method->input_type()->file()->package(),
-                                   method->input_type()->name());
-  (*vars)["Response"] = GetFullName((*vars)["PackageName"],
-                                   method->output_type()->file()->package(),
-                                   method->output_type()->name());
+  (*vars)["Request"] = GetFullName(method->input_type());
+  (*vars)["Response"] = GetFullName(method->output_type());
   if (NoStreaming(method)) {
     printer->Print(
         *vars,
@@ -513,42 +511,49 @@ void PrintServer(google::protobuf::io::Printer* printer,
       "}\n\n");
 }
 
+bool IsSelfImport(const google::protobuf::FileDescriptor* self,
+                  const google::protobuf::FileDescriptor* import) {
+  if (GenerateFullPackage(self) == GenerateFullPackage(import)) {
+    return true;
+  }
+  return false;
+}
+
 void PrintMessageImports(
     google::protobuf::io::Printer* printer,
     const google::protobuf::FileDescriptor* file,
     map<string, string>* vars) {
   set<const google::protobuf::FileDescriptor*> descs;
-  set<string> importedPkgs;
   for (int i = 0; i < file->service_count(); ++i) {
     const google::protobuf::ServiceDescriptor* service = file->service(i);
     for (int j = 0; j < service->method_count(); ++j) {
-      const google::protobuf::MethodDescriptor* method = service->method(i);
-      // Remove duplicated imports.
-      if (importedPkgs.find(
-          method->input_type()->file()->package()) == importedPkgs.end()) {
+      const google::protobuf::MethodDescriptor* method = service->method(j);
+      if (!IsSelfImport(file, method->input_type()->file())) {
         descs.insert(method->input_type()->file());
-        importedPkgs.insert(method->input_type()->file()->package());
       }
-      if (importedPkgs.find(
-          method->output_type()->file()->package()) == importedPkgs.end()) {
+      if (!IsSelfImport(file, method->output_type()->file())) {
         descs.insert(method->output_type()->file());
-        importedPkgs.insert(method->output_type()->file()->package());
       }
     }
   }
 
+  int idx = 0;
   for (auto fd : descs) {
-    if (fd->package() == (*vars)["PackageName"]) {
-      continue;
+    string pkg = GenerateFullPackage(fd);
+    if (pkg != "") {
+      g_imports.insert(pkg);
+      if (file->package() == fd->package()) {
+        // the same package name in different directories. Require an alias.
+        g_import_alias[pkg] = "apb" + std::to_string(idx++);
+      }
     }
-    string name = fd->name();
-    string import_path = "import \"";
-    if (name.find('/') == string::npos) {
-      // Assume all the proto in the same directory belong to the same package.
-      continue;
-    } else {
-      import_path += name.substr(0, name.find_last_of('/')) + "\"";
+  }
+  for (auto import : g_imports) {
+    string import_path = "import ";
+    if (g_import_alias.find(import) != g_import_alias.end()) {
+      import_path += g_import_alias[import] + " ";
     }
+    import_path += "\"" + import + "\"";
     printer->Print(import_path.c_str());
     printer->Print("\n");
   }

From 55680c22a195add8da2aa176ca7042b017dce630 Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Mon, 2 Feb 2015 16:37:58 -0800
Subject: [PATCH 35/44] i) Eliminate the global vars; ii) properly handle the
 case that an external imported package contains multiple files; and iii) some
 function name touch-up

---
 rpc/compiler/go_generator.cc | 104 +++++++++++++++++++++--------------
 1 file changed, 64 insertions(+), 40 deletions(-)

diff --git a/rpc/compiler/go_generator.cc b/rpc/compiler/go_generator.cc
index 0c2ce94a..f5517436 100644
--- a/rpc/compiler/go_generator.cc
+++ b/rpc/compiler/go_generator.cc
@@ -42,11 +42,9 @@
 
 using namespace std;
 
+// TODO(zhaoq): Support go_package option.
 namespace grpc_go_generator {
 
-static map<string, string> g_import_alias;
-static set<string> g_imports;
-
 bool NoStreaming(const google::protobuf::MethodDescriptor* method) {
   return !method->client_streaming() && !method->server_streaming();
 }
@@ -91,7 +89,7 @@ std::string BadToUnderscore(std::string str) {
   return str;
 }
 
-string GenerateFullPackage(const google::protobuf::FileDescriptor* file) {
+string GenerateFullGoPackage(const google::protobuf::FileDescriptor* file) {
   // In opensouce environment, assume each directory has at most one package.
   size_t pos = file->name().find_last_of('/');
   if (pos != string::npos) {
@@ -100,23 +98,30 @@ string GenerateFullPackage(const google::protobuf::FileDescriptor* file) {
   return "";
 }
 
-const string GetFullName(const google::protobuf::Descriptor* desc) {
-  string pkg = GenerateFullPackage(desc->file());
-  if (g_imports.find(pkg) == g_imports.end()) {
+const string GetFullMessageQualifiedName(
+    const google::protobuf::Descriptor* desc,
+    set<string>& imports,
+    map<string, string>& import_alias) {
+  string pkg = GenerateFullGoPackage(desc->file());
+  if (imports.find(pkg) == imports.end()) {
     return desc->name();
   }
-  if (g_import_alias.find(pkg) != g_import_alias.end()) {
-    return g_import_alias[pkg] + "." + desc->name();
+  if (import_alias.find(pkg) != import_alias.end()) {
+    return import_alias[pkg] + "." + desc->name();
   }
   return BadToUnderscore(desc->file()->package()) + "." + desc->name();
 }
 
 void PrintClientMethodDef(google::protobuf::io::Printer* printer,
                           const google::protobuf::MethodDescriptor* method,
-                          map<string, string>* vars) {
+                          map<string, string>* vars,
+                          set<string>& imports,
+                          map<string, string>& import_alias) {
   (*vars)["Method"] = method->name();
-  (*vars)["Request"] = GetFullName(method->input_type());
-  (*vars)["Response"] = GetFullName(method->output_type());
+  (*vars)["Request"] =
+      GetFullMessageQualifiedName(method->input_type(), imports, import_alias);
+  (*vars)["Response"] =
+      GetFullMessageQualifiedName(method->output_type(), imports, import_alias);
   if (NoStreaming(method)) {
     printer->Print(*vars,
                    "\t$Method$(ctx context.Context, in *$Request$, opts "
@@ -140,10 +145,14 @@ void PrintClientMethodDef(google::protobuf::io::Printer* printer,
 
 void PrintClientMethodImpl(google::protobuf::io::Printer* printer,
                            const google::protobuf::MethodDescriptor* method,
-                           map<string, string>* vars) {
+                           map<string, string>* vars,
+                           set<string>& imports,
+                           map<string, string>& import_alias) {
   (*vars)["Method"] = method->name();
-  (*vars)["Request"] = GetFullName(method->input_type());
-  (*vars)["Response"] = GetFullName(method->output_type());
+  (*vars)["Request"] =
+      GetFullMessageQualifiedName(method->input_type(), imports, import_alias);
+  (*vars)["Response"] =
+      GetFullMessageQualifiedName(method->output_type(), imports, import_alias);
   if (NoStreaming(method)) {
     printer->Print(
         *vars,
@@ -285,12 +294,14 @@ void PrintClientMethodImpl(google::protobuf::io::Printer* printer,
 
 void PrintClient(google::protobuf::io::Printer* printer,
                  const google::protobuf::ServiceDescriptor* service,
-                 map<string, string>* vars) {
+                 map<string, string>* vars,
+                 set<string>& imports,
+                 map<string, string>& import_alias) {
   (*vars)["Service"] = service->name();
   (*vars)["ServiceStruct"] = LowerCaseService(service->name());
   printer->Print(*vars, "type $Service$Client interface {\n");
   for (int i = 0; i < service->method_count(); ++i) {
-    PrintClientMethodDef(printer, service->method(i), vars);
+    PrintClientMethodDef(printer, service->method(i), vars, imports, import_alias);
   }
   printer->Print("}\n\n");
 
@@ -304,16 +315,20 @@ void PrintClient(google::protobuf::io::Printer* printer,
       "\treturn &$ServiceStruct$Client{cc}\n"
       "}\n\n");
   for (int i = 0; i < service->method_count(); ++i) {
-    PrintClientMethodImpl(printer, service->method(i), vars);
+    PrintClientMethodImpl(printer, service->method(i), vars, imports, import_alias);
   }
 }
 
 void PrintServerMethodDef(google::protobuf::io::Printer* printer,
                           const google::protobuf::MethodDescriptor* method,
-                          map<string, string>* vars) {
+                          map<string, string>* vars,
+                          set<string>& imports,
+                          map<string, string>& import_alias) {
   (*vars)["Method"] = method->name();
-  (*vars)["Request"] = GetFullName(method->input_type());
-  (*vars)["Response"] = GetFullName(method->output_type());
+  (*vars)["Request"] =
+      GetFullMessageQualifiedName(method->input_type(), imports, import_alias);
+  (*vars)["Response"] =
+      GetFullMessageQualifiedName(method->output_type(), imports, import_alias);
   if (NoStreaming(method)) {
     printer->Print(
         *vars,
@@ -330,10 +345,14 @@ void PrintServerMethodDef(google::protobuf::io::Printer* printer,
 
 void PrintServerHandler(google::protobuf::io::Printer* printer,
                         const google::protobuf::MethodDescriptor* method,
-                        map<string, string>* vars) {
+                        map<string, string>* vars,
+                        set<string>& imports,
+                        map<string, string>& import_alias) {
   (*vars)["Method"] = method->name();
-  (*vars)["Request"] = GetFullName(method->input_type());
-  (*vars)["Response"] = GetFullName(method->output_type());
+  (*vars)["Request"] =
+      GetFullMessageQualifiedName(method->input_type(), imports, import_alias);
+  (*vars)["Response"] =
+      GetFullMessageQualifiedName(method->output_type(), imports, import_alias);
   if (NoStreaming(method)) {
     printer->Print(
         *vars,
@@ -471,11 +490,13 @@ void PrintServerStreamingMethodDesc(
 
 void PrintServer(google::protobuf::io::Printer* printer,
                  const google::protobuf::ServiceDescriptor* service,
-                 map<string, string>* vars) {
+                 map<string, string>* vars,
+                 set<string>& imports,
+                 map<string, string>& import_alias) {
   (*vars)["Service"] = service->name();
   printer->Print(*vars, "type $Service$Server interface {\n");
   for (int i = 0; i < service->method_count(); ++i) {
-    PrintServerMethodDef(printer, service->method(i), vars);
+    PrintServerMethodDef(printer, service->method(i), vars, imports, import_alias);
   }
   printer->Print("}\n\n");
 
@@ -485,7 +506,7 @@ void PrintServer(google::protobuf::io::Printer* printer,
                  "}\n\n");
 
   for (int i = 0; i < service->method_count(); ++i) {
-    PrintServerHandler(printer, service->method(i), vars);
+    PrintServerHandler(printer, service->method(i), vars, imports, import_alias);
   }
 
   printer->Print(*vars,
@@ -513,7 +534,7 @@ void PrintServer(google::protobuf::io::Printer* printer,
 
 bool IsSelfImport(const google::protobuf::FileDescriptor* self,
                   const google::protobuf::FileDescriptor* import) {
-  if (GenerateFullPackage(self) == GenerateFullPackage(import)) {
+  if (GenerateFullGoPackage(self) == GenerateFullGoPackage(import)) {
     return true;
   }
   return false;
@@ -522,7 +543,9 @@ bool IsSelfImport(const google::protobuf::FileDescriptor* self,
 void PrintMessageImports(
     google::protobuf::io::Printer* printer,
     const google::protobuf::FileDescriptor* file,
-    map<string, string>* vars) {
+    map<string, string>* vars,
+    set<string>* imports,
+    map<string, string>* import_alias) {
   set<const google::protobuf::FileDescriptor*> descs;
   for (int i = 0; i < file->service_count(); ++i) {
     const google::protobuf::ServiceDescriptor* service = file->service(i);
@@ -539,19 +562,19 @@ void PrintMessageImports(
 
   int idx = 0;
   for (auto fd : descs) {
-    string pkg = GenerateFullPackage(fd);
+    string pkg = GenerateFullGoPackage(fd);
     if (pkg != "") {
-      g_imports.insert(pkg);
-      if (file->package() == fd->package()) {
+      auto ret = imports->insert(pkg);
+      if (ret.second == true && file->package() == fd->package()) {
         // the same package name in different directories. Require an alias.
-        g_import_alias[pkg] = "apb" + std::to_string(idx++);
+        (*import_alias)[pkg] = "apb" + std::to_string(idx++);
       }
     }
   }
-  for (auto import : g_imports) {
+  for (auto import : *imports) {
     string import_path = "import ";
-    if (g_import_alias.find(import) != g_import_alias.end()) {
-      import_path += g_import_alias[import] + " ";
+    if (import_alias->find(import) != import_alias->end()) {
+      import_path += (*import_alias)[import] + " ";
     }
     import_path += "\"" + import + "\"";
     printer->Print(import_path.c_str());
@@ -565,7 +588,8 @@ string GetServices(const google::protobuf::FileDescriptor* file) {
   google::protobuf::io::StringOutputStream output_stream(&output);
   google::protobuf::io::Printer printer(&output_stream, '$');
   map<string, string> vars;
-
+  map<string, string> import_alias;
+  set<string> imports;
   string package_name = !file->options().go_package().empty()
                             ? file->options().go_package()
                             : file->package();
@@ -583,7 +607,7 @@ string GetServices(const google::protobuf::FileDescriptor* file) {
       "\tproto \"github.com/golang/protobuf/proto\"\n"
       ")\n\n");
 
-  PrintMessageImports(&printer, file, &vars);
+  PrintMessageImports(&printer, file, &vars, &imports, &import_alias);
 
   // $Package$ is used to fully qualify method names.
   vars["Package"] = file->package();
@@ -592,9 +616,9 @@ string GetServices(const google::protobuf::FileDescriptor* file) {
   }
 
   for (int i = 0; i < file->service_count(); ++i) {
-    PrintClient(&printer, file->service(0), &vars);
+    PrintClient(&printer, file->service(0), &vars, imports, import_alias);
     printer.Print("\n");
-    PrintServer(&printer, file->service(0), &vars);
+    PrintServer(&printer, file->service(0), &vars, imports, import_alias);
     printer.Print("\n");
   }
   return output;

From 0f4f9d04d32acfd5d47fa8bd966c280869826c6c Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Mon, 2 Feb 2015 17:02:29 -0800
Subject: [PATCH 36/44] resolved some comments

---
 rpc/compiler/go_generator.cc | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/rpc/compiler/go_generator.cc b/rpc/compiler/go_generator.cc
index f5517436..9085f4d6 100644
--- a/rpc/compiler/go_generator.cc
+++ b/rpc/compiler/go_generator.cc
@@ -104,9 +104,12 @@ const string GetFullMessageQualifiedName(
     map<string, string>& import_alias) {
   string pkg = GenerateFullGoPackage(desc->file());
   if (imports.find(pkg) == imports.end()) {
+    // The message is in the same package as the services definition.
     return desc->name();
   }
   if (import_alias.find(pkg) != import_alias.end()) {
+    // The message is in a package whose name is as same as the one consisting
+    // of the service definition. Use the alias to differentiate.
     return import_alias[pkg] + "." + desc->name();
   }
   return BadToUnderscore(desc->file()->package()) + "." + desc->name();
@@ -565,7 +568,7 @@ void PrintMessageImports(
     string pkg = GenerateFullGoPackage(fd);
     if (pkg != "") {
       auto ret = imports->insert(pkg);
-      if (ret.second == true && file->package() == fd->package()) {
+      if (ret.second && file->package() == fd->package()) {
         // the same package name in different directories. Require an alias.
         (*import_alias)[pkg] = "apb" + std::to_string(idx++);
       }

From 4a1cba09a6b7f2319a749e754bc19df5990708df Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Mon, 2 Feb 2015 17:05:03 -0800
Subject: [PATCH 37/44] add a comment

---
 rpc/compiler/go_generator.cc | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/rpc/compiler/go_generator.cc b/rpc/compiler/go_generator.cc
index 9085f4d6..bbc5a562 100644
--- a/rpc/compiler/go_generator.cc
+++ b/rpc/compiler/go_generator.cc
@@ -568,6 +568,8 @@ void PrintMessageImports(
     string pkg = GenerateFullGoPackage(fd);
     if (pkg != "") {
       auto ret = imports->insert(pkg);
+      // Use ret.second to guarantee if a package spans multiple files, it only
+      // gets 1 alias.
       if (ret.second && file->package() == fd->package()) {
         // the same package name in different directories. Require an alias.
         (*import_alias)[pkg] = "apb" + std::to_string(idx++);

From afe57a6648bb32c07f4dda33ddf8d59e6ae9a0cd Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Tue, 3 Feb 2015 16:48:50 -0800
Subject: [PATCH 38/44] remove tmp dir

---
 rpc/test/testdata/tmp/test.pb.go      | 157 --------------
 rpc/test/testdata/tmp/test_grpc.pb.go | 293 --------------------------
 2 files changed, 450 deletions(-)
 delete mode 100644 rpc/test/testdata/tmp/test.pb.go
 delete mode 100644 rpc/test/testdata/tmp/test_grpc.pb.go

diff --git a/rpc/test/testdata/tmp/test.pb.go b/rpc/test/testdata/tmp/test.pb.go
deleted file mode 100644
index 46fa1d3f..00000000
--- a/rpc/test/testdata/tmp/test.pb.go
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- *
- * Copyright 2014, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-// Code generated by protoc-gen-go.
-// source: test.proto
-// DO NOT EDIT!
-
-/*
-Package test is a generated protocol buffer package.
-
-It is generated from these files:
-	test.proto
-
-It has these top-level messages:
-	DivArgs
-	DivReply
-	FibArgs
-	Num
-	FibReply
-*/
-package test
-
-import proto "github.com/golang/protobuf/proto"
-import math "math"
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ = proto.Marshal
-var _ = math.Inf
-
-type DivArgs struct {
-	Dividend         *int64 `protobuf:"varint,1,req,name=dividend" json:"dividend,omitempty"`
-	Divisor          *int64 `protobuf:"varint,2,req,name=divisor" json:"divisor,omitempty"`
-	XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *DivArgs) Reset()         { *m = DivArgs{} }
-func (m *DivArgs) String() string { return proto.CompactTextString(m) }
-func (*DivArgs) ProtoMessage()    {}
-
-func (m *DivArgs) GetDividend() int64 {
-	if m != nil && m.Dividend != nil {
-		return *m.Dividend
-	}
-	return 0
-}
-
-func (m *DivArgs) GetDivisor() int64 {
-	if m != nil && m.Divisor != nil {
-		return *m.Divisor
-	}
-	return 0
-}
-
-type DivReply struct {
-	Quotient         *int64 `protobuf:"varint,1,req,name=quotient" json:"quotient,omitempty"`
-	Remainder        *int64 `protobuf:"varint,2,req,name=remainder" json:"remainder,omitempty"`
-	XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *DivReply) Reset()         { *m = DivReply{} }
-func (m *DivReply) String() string { return proto.CompactTextString(m) }
-func (*DivReply) ProtoMessage()    {}
-
-func (m *DivReply) GetQuotient() int64 {
-	if m != nil && m.Quotient != nil {
-		return *m.Quotient
-	}
-	return 0
-}
-
-func (m *DivReply) GetRemainder() int64 {
-	if m != nil && m.Remainder != nil {
-		return *m.Remainder
-	}
-	return 0
-}
-
-type FibArgs struct {
-	Limit            *int64 `protobuf:"varint,1,opt,name=limit" json:"limit,omitempty"`
-	XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *FibArgs) Reset()         { *m = FibArgs{} }
-func (m *FibArgs) String() string { return proto.CompactTextString(m) }
-func (*FibArgs) ProtoMessage()    {}
-
-func (m *FibArgs) GetLimit() int64 {
-	if m != nil && m.Limit != nil {
-		return *m.Limit
-	}
-	return 0
-}
-
-type Num struct {
-	Num              *int64 `protobuf:"varint,1,req,name=num" json:"num,omitempty"`
-	XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *Num) Reset()         { *m = Num{} }
-func (m *Num) String() string { return proto.CompactTextString(m) }
-func (*Num) ProtoMessage()    {}
-
-func (m *Num) GetNum() int64 {
-	if m != nil && m.Num != nil {
-		return *m.Num
-	}
-	return 0
-}
-
-type FibReply struct {
-	Count            *int64 `protobuf:"varint,1,req,name=count" json:"count,omitempty"`
-	XXX_unrecognized []byte `json:"-"`
-}
-
-func (m *FibReply) Reset()         { *m = FibReply{} }
-func (m *FibReply) String() string { return proto.CompactTextString(m) }
-func (*FibReply) ProtoMessage()    {}
-
-func (m *FibReply) GetCount() int64 {
-	if m != nil && m.Count != nil {
-		return *m.Count
-	}
-	return 0
-}
-
-func init() {
-}
diff --git a/rpc/test/testdata/tmp/test_grpc.pb.go b/rpc/test/testdata/tmp/test_grpc.pb.go
deleted file mode 100644
index 6dc16a59..00000000
--- a/rpc/test/testdata/tmp/test_grpc.pb.go
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- *
- * Copyright 2014, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-package test
-
-import (
-	"fmt"
-	"io"
-	"github.com/google/grpc-go/rpc"
-	context "golang.org/x/net/context"
-	proto "github.com/golang/protobuf/proto"
-)
-
-type MathClient interface {
-	Div(ctx context.Context, in *DivArgs, opts ...rpc.CallOption) (*DivReply, error)
-	DivMany(ctx context.Context, opts ...rpc.CallOption) (Math_DivManyClient, error)
-	Fib(ctx context.Context, m *FibArgs, opts ...rpc.CallOption) (Math_FibClient, error)
-	Sum(ctx context.Context, opts ...rpc.CallOption) (Math_SumClient, error)
-}
-
-type mathClient struct {
-	cc *rpc.ClientConn
-}
-
-func NewMathClient(cc *rpc.ClientConn) MathClient {
-	return &mathClient{cc}
-}
-
-func (c *mathClient) Div(ctx context.Context, in *DivArgs, opts ...rpc.CallOption) (*DivReply, error) {
-	out := new(DivReply)
-	err := rpc.Invoke(ctx, "/test.Math/Div", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *mathClient) DivMany(ctx context.Context, opts ...rpc.CallOption) (Math_DivManyClient, error) {
-	stream, err := rpc.NewClientStream(ctx, c.cc, "/test.Math/DivMany", opts...)
-	if err != nil {
-		return nil, err
-	}
-	return &mathDivManyClient{stream}, nil
-}
-
-type Math_DivManyClient interface {
-	Send(*DivArgs) error
-	Recv() (*DivReply, error)
-	rpc.ClientStream
-}
-
-type mathDivManyClient struct {
-	rpc.ClientStream
-}
-
-func (x *mathDivManyClient) Send(m *DivArgs) error {
-	return x.ClientStream.SendProto(m)
-}
-
-func (x *mathDivManyClient) Recv() (*DivReply, error) {
-	m := new(DivReply)
-	if err := x.ClientStream.RecvProto(m); err != nil {
-		return nil, err
-	}
-	return m, nil
-}
-
-func (c *mathClient) Fib(ctx context.Context, m *FibArgs, opts ...rpc.CallOption) (Math_FibClient, error) {
-	stream, err := rpc.NewClientStream(ctx, c.cc, "/test.Math/Fib", opts...)
-	if err != nil {
-		return nil, err
-	}
-	x := &mathFibClient{stream}
-	if err := x.ClientStream.SendProto(m); err != nil {
-		return nil, err
-	}
-	if err := x.ClientStream.CloseSend(); err != nil {
-		return nil, err
-	}
-	return x, nil
-}
-
-type Math_FibClient interface {
-	Recv() (*Num, error)
-	rpc.ClientStream
-}
-
-type mathFibClient struct {
-	rpc.ClientStream
-}
-
-func (x *mathFibClient) Recv() (*Num, error) {
-	m := new(Num)
-	if err := x.ClientStream.RecvProto(m); err != nil {
-		return nil, err
-	}
-	return m, nil
-}
-
-func (c *mathClient) Sum(ctx context.Context, opts ...rpc.CallOption) (Math_SumClient, error) {
-	stream, err := rpc.NewClientStream(ctx, c.cc, "/test.Math/Sum", opts...)
-	if err != nil {
-		return nil, err
-	}
-	return &mathSumClient{stream}, nil
-}
-
-type Math_SumClient interface {
-	Send(*Num) error
-	CloseAndRecv() (*Num, error)
-	rpc.ClientStream
-}
-
-type mathSumClient struct {
-	rpc.ClientStream
-}
-
-func (x *mathSumClient) Send(m *Num) error {
-	return x.ClientStream.SendProto(m)
-}
-
-func (x *mathSumClient) CloseAndRecv() (*Num, error) {
-	if err := x.ClientStream.CloseSend(); err != nil {
-		return nil, err
-	}
-	m := new(Num)
-	if err := x.ClientStream.RecvProto(m); err != nil {
-		return nil, err
-	}
-	// Read EOF.
-	if err := x.ClientStream.RecvProto(m); err == io.EOF {
-		return m, io.EOF
-	}
-	// gRPC protocol violation.
-	return m, fmt.Errorf("Violate gRPC client streaming protocol: no EOF after the response.")
-}
-
-
-type MathServer interface {
-	Div(context.Context, *DivArgs) (*DivReply, error)
-	DivMany(Math_DivManyServer) error
-	Fib(*FibArgs, Math_FibServer) error
-	Sum(Math_SumServer) error
-}
-
-func RegisterService(s *rpc.Server, srv MathServer) {
-	s.RegisterService(&_Math_serviceDesc, srv)
-}
-
-func _Math_Div_Handler(srv interface{}, ctx context.Context, buf []byte) (proto.Message, error) {
-	in := new(DivArgs)
-	if err := proto.Unmarshal(buf, in); err != nil {
-		return nil, err
-	}
-	out, err := srv.(MathServer).Div(ctx, in)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func _Math_DivMany_Handler(srv interface{}, stream rpc.ServerStream) error {
-	return srv.(MathServer).DivMany(&mathDivManyServer{stream})
-}
-
-type Math_DivManyServer interface {
-	Send(*DivReply) error
-	Recv() (*DivArgs, error)
-	rpc.ServerStream
-}
-
-type mathDivManyServer struct {
-	rpc.ServerStream
-}
-
-func (x *mathDivManyServer) Send(m *DivReply) error {
-	return x.ServerStream.SendProto(m)
-}
-
-func (x *mathDivManyServer) Recv() (*DivArgs, error) {
-	m := new(DivArgs)
-	if err := x.ServerStream.RecvProto(m); err != nil {
-		return nil, err
-	}
-	return m, nil
-}
-
-func _Math_Fib_Handler(srv interface{}, stream rpc.ServerStream) error {
-	m := new(FibArgs)
-	if err := stream.RecvProto(m); err != nil {
-		return err
-	}
-	return srv.(MathServer).Fib(m, &mathFibServer{stream})
-}
-
-type Math_FibServer interface {
-	Send(*Num) error
-	rpc.ServerStream
-}
-
-type mathFibServer struct {
-	rpc.ServerStream
-}
-
-func (x *mathFibServer) Send(m *Num) error {
-	return x.ServerStream.SendProto(m)
-}
-
-func _Math_Sum_Handler(srv interface{}, stream rpc.ServerStream) error {
-	return srv.(MathServer).Sum(&mathSumServer{stream})
-}
-
-type Math_SumServer interface {
-	SendAndClose(*Num) error
-	Recv() (*Num, error)
-	rpc.ServerStream
-}
-
-type mathSumServer struct {
-	rpc.ServerStream
-}
-
-func (x *mathSumServer) SendAndClose(m *Num) error {
-	if err := x.ServerStream.SendProto(m); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (x *mathSumServer) Recv() (*Num, error) {
-	m := new(Num)
-	if err := x.ServerStream.RecvProto(m); err != nil {
-		return nil, err
-	}
-	return m, nil
-}
-
-var _Math_serviceDesc = rpc.ServiceDesc{
-	ServiceName: "test.Math",
-	HandlerType: (*MathServer)(nil),
-	Methods: []rpc.MethodDesc{
-		{
-			MethodName:	"Div",
-			Handler:	_Math_Div_Handler,
-		},
-	},
-	Streams: []rpc.StreamDesc{
-		{
-			StreamName:	"DivMany",
-			Handler:	_Math_DivMany_Handler,
-		},
-		{
-			StreamName:	"Fib",
-			Handler:	_Math_Fib_Handler,
-		},
-		{
-			StreamName:	"Sum",
-			Handler:	_Math_Sum_Handler,
-		},
-	},
-}
-
-

From 0f6fd6e2c32cafd6b071d0b59aafaffb8e8440ed Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Tue, 3 Feb 2015 17:26:15 -0800
Subject: [PATCH 39/44] Support import_prefix cmdline param

---
 rpc/compiler/go_generator.cc |  16 +++++++++++++---
 rpc/compiler/go_generator.h  |   6 +++++-
 rpc/compiler/go_generator.o  | Bin 0 -> 229208 bytes
 rpc/compiler/go_plugin       | Bin 0 -> 132164 bytes
 rpc/compiler/go_plugin.cc    |   4 +++-
 rpc/compiler/go_plugin.o     | Bin 0 -> 41872 bytes
 6 files changed, 21 insertions(+), 5 deletions(-)
 create mode 100644 rpc/compiler/go_generator.o
 create mode 100755 rpc/compiler/go_plugin
 create mode 100644 rpc/compiler/go_plugin.o

diff --git a/rpc/compiler/go_generator.cc b/rpc/compiler/go_generator.cc
index bbc5a562..91259a75 100644
--- a/rpc/compiler/go_generator.cc
+++ b/rpc/compiler/go_generator.cc
@@ -547,6 +547,7 @@ void PrintMessageImports(
     google::protobuf::io::Printer* printer,
     const google::protobuf::FileDescriptor* file,
     map<string, string>* vars,
+    const string& import_prefix,
     set<string>* imports,
     map<string, string>* import_alias) {
   set<const google::protobuf::FileDescriptor*> descs;
@@ -581,14 +582,15 @@ void PrintMessageImports(
     if (import_alias->find(import) != import_alias->end()) {
       import_path += (*import_alias)[import] + " ";
     }
-    import_path += "\"" + import + "\"";
+    import_path += "\"" + import_prefix + import + "\"";
     printer->Print(import_path.c_str());
     printer->Print("\n");
   }
   printer->Print("\n");
 }
 
-string GetServices(const google::protobuf::FileDescriptor* file) {
+string GetServices(const google::protobuf::FileDescriptor* file,
+                   vector<pair<string, string> >& options) {
   string output;
   google::protobuf::io::StringOutputStream output_stream(&output);
   google::protobuf::io::Printer printer(&output_stream, '$');
@@ -612,7 +614,15 @@ string GetServices(const google::protobuf::FileDescriptor* file) {
       "\tproto \"github.com/golang/protobuf/proto\"\n"
       ")\n\n");
 
-  PrintMessageImports(&printer, file, &vars, &imports, &import_alias);
+  // TODO(zhaoq): Support other command line parameters supported by
+  // the protoc-gen-go plugin.
+  string import_prefix = "";
+  for (auto& p : options) {
+    if (p.first == "import_prefix") {
+      import_prefix = p.second;
+    }
+  }
+  PrintMessageImports(&printer, file, &vars, import_prefix, &imports, &import_alias);
 
   // $Package$ is used to fully qualify method names.
   vars["Package"] = file->package();
diff --git a/rpc/compiler/go_generator.h b/rpc/compiler/go_generator.h
index 5744345b..e421968e 100644
--- a/rpc/compiler/go_generator.h
+++ b/rpc/compiler/go_generator.h
@@ -35,6 +35,9 @@
 #define NET_GRPC_COMPILER_GO_GENERATOR_H_
 
 #include <string>
+#include <vector>
+
+using namespace std;
 
 namespace google {
 namespace protobuf {
@@ -44,7 +47,8 @@ class FileDescriptor;
 
 namespace grpc_go_generator {
 
-std::string GetServices(const google::protobuf::FileDescriptor* file);
+string GetServices(const google::protobuf::FileDescriptor* file,
+                   vector<std::pair<string, string> >& options);
 
 }  // namespace grpc_go_generator
 
diff --git a/rpc/compiler/go_generator.o b/rpc/compiler/go_generator.o
new file mode 100644
index 0000000000000000000000000000000000000000..68718af6a37a9afec80f67a150a579004b9dd056
GIT binary patch
literal 229208
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

literal 0
HcmV?d00001

diff --git a/rpc/compiler/go_plugin b/rpc/compiler/go_plugin
new file mode 100755
index 0000000000000000000000000000000000000000..17e2a556252d2a0d8a1694ab3989078955fb59ff
GIT binary patch
literal 132164
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

literal 0
HcmV?d00001

diff --git a/rpc/compiler/go_plugin.cc b/rpc/compiler/go_plugin.cc
index 79423164..33f18c5e 100644
--- a/rpc/compiler/go_plugin.cc
+++ b/rpc/compiler/go_plugin.cc
@@ -73,10 +73,12 @@ class GoGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
       return false;
     }
 
+    vector<pair<string, string> > options;
+    google::protobuf::compiler::ParseGeneratorParameter(parameter, &options);
     unique_ptr<google::protobuf::io::ZeroCopyOutputStream> output(
         context->Open(file_name));
     google::protobuf::io::CodedOutputStream coded_out(output.get());
-    string code = grpc_go_generator::GetServices(file);
+    string code = grpc_go_generator::GetServices(file, options);
     coded_out.WriteRaw(code.data(), code.size());
     return true;
   }
diff --git a/rpc/compiler/go_plugin.o b/rpc/compiler/go_plugin.o
new file mode 100644
index 0000000000000000000000000000000000000000..1462cd9a112d50c99faf7636001c1b66d1942e0e
GIT binary patch
literal 41872
zcmd5_4|rTvm4EGPN|AyU5D-v85DZdcCQbiRr4YtW+O&<G6br&mr;}+Lnq<Pvq<`E3
zWlOO!l<o586QyEttN7pIqE@YLq^vA1`gQ$St$tm<uDV(&xUB2$*0p}!bM8Cmz4Pv$
zWQI=B`+bvp=XcLJzjOb-``*0VdsnjK-Q&lN^Eiz2-sMH#81=kVW0an!lJmSzd!JOY
z*TQ$yxsKxNDQ=@UN%4G&+aX>^=|vPTrnr;hr4)Bjyo}--DSj`-H&OgPif^SjLvfbk
z9L3!fucCMj#kW!1OK~5?1&VK{xJ2<F#p@~FNbz4%yousFDZY#1yD8p6@m7jIK=C$;
zKS=R?6yHzr4vHV3_(6&vruah?KSJ?`DSnjVk5c?Gig!W0EH(7+>C~2&8i(#Ulo}d5
zklLO+oEm!e2xNJw?aL0Qh8G<ePD0lA2^`ulMTQO@y)YGrQbPwr16!VHeBZ76!Bo>g
zu~05}nbpOCT+_hHrqx)t?fvVry*=IaDzAQ3Pj9}yKiijYs_#VM0O%VmmFx5U-Sz8x
z%4_P$4CtOXaRRG#Gkh?O0l#C|j9)N;F@}-vT<zg!Jc1%%*;7Mz97_!+kENbf8Q^RT
z9riS2c-|UDw!AbY)aDwCEImh-q*TD6=tyBNvThwIPnO_w`;`w;Q`)C=AeBzt{n9^z
zjnvRLmqSrgLtpMx(ZeYfZJ!5G$I#YU_-%M=kQcP>){)mgHgeBM`E}pG@%!s*pmtK*
zx2{lX)c$dWs8x?mT(?NGmU{MS&^+-iEKev19m8ef$hg$({e!3NMed_@sv7PYdHp?)
zp}Iq7`||%Yvc3Z@4=9&^{Ph_1_T=W&_U)KO`1eDvwl9M$D(DX*6co6Y*(MKz<Q~pC
z`WA2jD>GKmZy@!rUqs)xFWUnWLFGrrhqq!oq=voJmXRqKZQrgcdiY_54}o((I&mO1
z^mJ-_az|<?QdD2b4V4Q*GIv)%xIJiCQO4vhc3F+i@LOu=+rV*P=qE6uSweLHKqDcL
z;LN}yvnIkS46=p}{`y`lzhc|W%13<#P!k1`N9PAZAsY!rlng*kkV;@iGy~a<^;R+O
z-2DuW37C3LoESIfeRZDq=(x?}j@Nllj<4HY=RG^V?!h|mH{&k?WVb){Xr1>5zwRe>
z-oq2>o~!frPpI2l=RGtLv_N~()Velrd635MvFYJf9;o$dA{ZKcB{j6{NNN~ANk~U6
z#XSq!5T^){17F?a-JOGd1uYGyCIvB6eb}G@M^JZUf~Gn0IQ$kCCoIa8uqdhsF(W)9
zVL??ff?P;LVJU5tP%A^A8_5sDc)%K&63S_nnLOgQT?w<gx<R49%-~^YpM#(jU7>J_
z5?4GJ9m7Z{hes;7iqV{m-UX&maQm_osqKrvY*_c!`sRugl@=B^sPGDNqU$xdp_K&O
zL6=~5feQ-EQ<%O0B2n0%hE<8VbU6~m3;TuZ0(25y!y>~dDmZJqPEud0ifniuSf?@J
zrLKHBHFO~L?PC){EEpzHJ3+-jujB3=jst|lv7q(DWz_4#Vf`AkwXN2)dchI3<&Iap
z^7-IAxQG`SC@ow^!C}0vX!4@qsuIMi<k@+XVBQ2xsGDc!O~G^}?Gvx3&=;7Ua3)*?
zUg*Pv`+}McEcF_+2TKW$qbhf`QZyH7<p!>!Z&F30X6NQlZAl&rW}$16uMGYxmly_v
zK3y8a0&AMBnO<7`$4Y&5Au)Y^VLmLN=jZ$L#ca7ytklf>wzfI-jmuUJ_Lm3iTbpJz
zwOpN;J*d7Wt_%P)buQT(_x`2cxD8XrT{QW$NjqSHb}``i!SF`>bKO}}?j7HD=EP1A
zfUlT07jX!0z(1Vd5#`^4I0RSzrXbt99AnmB5$W%w{5djzFv{OY`B%vNY?P1ixc7H<
zsFI!L<5!={_g46V9}Jg4)&xwj52-D_f1a-lp-cznLFk50OfI>_AAfVi*MSRL2xs9R
zw$&cx_fr0RnLqw|C2%od_fh_ZGJjd1Uk}&|h(l<DPt1=yBaQ=O`0&aY`BUhI>2*lN
zWk^Q$n<@V-GXJJ1zmxLk%KY_F{s84S%KTiEzk~Aec|gcNevuNW2WSuFt2PP!gLVk2
zQT59gNajjuqdVgG9p$^)>0H%SJkQn+*iNlu<adpdk7X!RK0eC`%ZPnxN#x@rB;)dN
z?<gGT<H0fVkByOkf$CtM_h#wi^2ongl<%se<)h@+gUwyUzXZ~;zC3<`BEd53Bpa?e
z*hl%Uc0M$Q{&C88mEmHz1;F6SpF2kWEo0<wqWoqg;l8{!s^guM|4x~|A<Ex3hW$g7
z-zxPBk^XVYzg*^v`S;?9m@!KEDc?0$+(P*cXoSmmYs9~a@@LBYVwAsg4Ey^i-_<`3
zQU2Sd{d{EqIOW^g*J~<m>?>ziLR>Be@fuDQ^S#-oa(+YEYwFIHvtHB6QpsylXt59=
zp-5Ba=EXBs7YeI;^Rv`5ua$$VX5|Wf1MuXln3&d9=+1|i_O_PfI!_r!t%bT;qV?UN
zbVI(BEA|Y)N}v@VoK>Zfm{!Uc*Y)J`nOp(Z1*jWy)L3i;9*r(@gYtR|nP!7)p+Po_
zDk7ikTxispUijqFh3Qh~;&dVt)#i+-CJX)8KFQ8BG|cK;E|cGo%MX+@(2%`(Rk?pM
z_OOA|<<`E!x_tZ6bSb%Hak`wCQOqNdDdtz@i~0UszP&4xY%Omb$S0SiTQc#sN|y(E
z+jF3m$gRm1Gv#8or(9~!CDU2>lT5D!-LB?LS0V$tGcuhE)6+Bqz&K-FJ_r4%9XuJx
z_CQ<$SHJ*NYBFhQ`Y|+uj)3(JHJmQbTvaHp&lbDemv$Ph+0s*JX}&pMEVLB{HZB<~
z4-A&m<zhbDmrO3{$}F|l29$%UL)2l&0#(u4onMt5>@8=y^S$|UzP%dS>Uhz?M5b$S
zpf{iC>4TQ&=xa%~J1Q;FoJr-g-I<lyQXT{o$&+-oV`T!F+SAiB>r{QkdxpigL=xKg
z<f?}V+miw14FgM{dzr-XqBbY1Y5I<p&8l2W)2)>jtU1|U4TGf;U|b|a)^_Y-qZV*_
z8QZ+QrmR33a5}1Vu)pW_!F*<*T&$)?yUGgVx>HRCG*Gd-oOG+r%q+^Rfj*vG3Z2sI
z71~g#RjUcsnHnn;swI<IoiBr1y#x6ojJxVOqiw(heFZ9Pb|#bU?#79_9Yz67N=tz=
zR?y`zeYdA)Wo{V2X*e0LmUMX<c&FT|O=pU`g{?YG_0<f_g?;({ayz<{E^`M4r@-?h
z`5qRbO{+)MJ8IhjW0whKKQ=v9*Gy{8i2A|8KTY>rn0{^hAM`WT0dsm6T=*yNgK^hh
zWj9=yHu@o!thu%w5eJ~LECrgD%#CVY6kM>ai=#*eul|-5aAjt!Yplq&S}<7ojWJY-
z&$D5Y#u>3|Ad~IwE#&ZNqF(-V8Rn}z+~^cGws*#<VGdi@m4P{MDJ&6j@(5R9<{+-k
z8YddpaEXjhpGX;-Y;j#>o3pE0113jdR4p36qMURoVZ{gqspe`jbBwDAR6<P_L~*yU
zw*O48CW!=g>0rUHdNVI;aKbp58-iRft&?JRwyGCYIX&1$IoxE)o37-mo<b7SU{rVK
zX+XoRGu*uO#m9<!Ow)jli!a7Iz?gGE0k~qJyRPmZ%;Yv~NKEU`uaD*uP0LcGN>vlh
zu@bfDCBpvL!t+!nJGh};tpmV(w{`AHs)FLmwAw<%iVm#7g}0b5l?to0@^-?Ft8tqS
zo{D>Gvr1&!#6*+pz#cVB@K6bEs=ID99$SEjdgO$;X<IHntBOS0Eh6wV3Kxi8Q-7hH
zZ<@b&+0~_THn*0@^J_AzitwNbo}&~Cg9G>|trp?zbLe*=&DcEpu6~n*^b_z2pAkcv
z9@%;>{gg%jaiKSsey2tM<5lP{x9Foy=H=Ms{|bx#d#cc1W6}Ri75d!3lgSR&|7WYv
z-$Z({{q|R(e~(4~$tv{m{YeaxAAd{Ydgs_x{|_ncxPH0{{hb#5=c~})ZPEW;75bmE
z=yz42|CB`^-^Jy6<JeVy`z-qS4lnC*?9zY6qL1(XvL44SeXMH?vi)&PvL44S{TGyW
zTpxd@V?B;t`iCs~H&>zm3yc2GtI&VRqK`J&Z;oC5|IVWS%PRDbTl9}qp+A9spO)>1
z?|QS}9J~CVY|($Y3jK2}`oF0{|6+^&D^=*f)uR8~D)gsX^zltwt~ZWd_19|AzoiQO
zxfXqVN1u5)cJbd}(f^Ao^gAs2&sCw{Wzqj`75cYW^l?mZxjA-~zuTh!$13!DE&BLk
zJo9qw;xAkD@!v&Qk7JkqCX4>jD){fQ=;NHmyd1mu@3ZJ<s?dMPqQ9aF{hb#5-&di(
z+oJ!6D)c{R(a%<)|CB|4Wfl7SEc&Mb#_h(jtNos_=ufIb|9Ojkt_uHOu;@>&g8z_3
zzq<<lUs&|dtb+d~i~jB^_<v{7Kf4P4;}-olSoG_`ClsYuFd!9#3G{9j)|m`sHiRyM
z6!)bNgv0>;gA{}fL8R^<XG5CT6BiJE1;l8RUPB_(^VSf52v9=jp9(nIe6{*BKo@Q5
zbj<$<<jKJPGnRmat^7x*{9I1Ff5Z2OSfBAWz>t5U?f?}?z4HnA9CWdFL57XrdnnLg
z9^}6kK05zKz-;{I5x;t8G%%(9>il?5YSVA5P#>=;HvKuIuil9oh5uKOXDj~&RQ_ht
z#qzhoM=$>rAh+?aApSX|&yimKGeFtKpCbMgDI$LoK01G^ga0GMkK;oIo&OyU{vDR`
z&j&*~|8fWa2=U`PxiaYdX$SuZ@xMa)SbqHfQ=R|2#6Mm${BxR+uz$+{;<1ndJ;XG1
z@6yu(v2$b6fvkjXCVhSUO(%WzPMc8B`5$rUw~_vQp^Hgf|3T2V^`AX7@yPzO81(h}
z`>})ngT$}isS`eccr4&Mx;Fk}#4qO$e14|$p8@TQWzy?!H}SW{*vxjC2>LeuDIX3L
zW%=>>k<LHM!T&4bAFKTybLjtfh5F}#^S1I&AV<|ZnW7H#`k&{}Ka2F$``x4HUjzEK
z`dd!*C)*F7-{|%CB?tdh5}YfzF{%6ic?bW1rTuQQ@LvV*zS`<<4e>XQ!G8tl+seP!
zQht1Xp_hNy!M}q9)%)+l2fh6FI`|I|{|eH50%E-X*7+yHJZCHa&q%O?^f}V`PXm2h
z`I|oyXrxFH`SJcs=fBgz-*kGQsNU%&8yM;Q8y)-`h+p=<Ea>a}|K{L-FY%8xey@XZ
zYOB9I>Fe_!%E~Yo^lkOG!{UE8DC+)y)xm#Ph5TP~@PEp}zskbD92~Nh|HBpXr$OIV
z{t*lR8Vmmk2me#Vk7Hg2z5o25ga07$r%3q;h;M@rh^xT;Dg!*W@}Ef)?^yk3#G!u?
z>0d~E9O?b%8=!Bizxqexexm=lw}tNiOyIHkKfOZ!7Lc>?&$962z7IP8AqW4G3i*HJ
z;P15X-)`amz!~=P-$wjz1|1pn{_|I$Z!7;A3x5d=>E-_q2mdxl`E~vm9sHXu{DT($
z8I$eh|9FM`3DCEd{}BuSdJBKS!M~6A@i$)?^zz^4;NL_1^8RZh7}D$iZyo%Tp<XfQ
z<5%bZ4~PDRq<>{#Cj6_9-xnSJAGXxrCa|LW|JF0@?bqh;U+4djL;pRbKi2&70O;G=
z|Cq)9yDa{n4i#*hf7VvWKLPY@{8M%YRnGG?&VP4X_&@33-&!I6;|~5t3;z}i|DxC1
z%fHLPulK(c=-bLa&%(de!oSzS|8?T$@dK(V==^6*vHOqn5(a$cB!jMhI_TT{UvBY#
z8yM32|1t-EBaABydjHk=J01K37XA-{J)M7}ga3NsZ&hAIe{}w`gMXWa|2_-<eh2?L
z;=eqiRw;e_f6KwY%ff%Zh5xq>{+$)p|H}^ky%zo*7XCND147&U@fG5y%Sc!Ydi{4e
z^hZd)A=C^Ky8e97xAorx7XR^)tlobfcJTj<_|^YJ3Lo_L+u`6pLj297i}T;Z7XBYP
z_%DQc9m81lH~DOP{o{2B15A&xp!<KVL%)Ue-yYL8@Bik2zODW*_-LRg%a6Cjdi`e{
z{I?LlK7Z)`-|XN|5x>0t;3ZM#A0~eN`Qv8dZ`8_PuYJGQ!M}p|SCBlmKSDbHrycxz
zh##_J0fuWVJnzsyK>A#MR?_vKb@)F*{-;P0{oe&2-TxPfpWB(ly(7f$n*X>R|BLil
zkK;4-j!PM=$8wX-3HrZ2FH9l*3r=InAZGs=^+Dg(e<wW_NNlSMVl4k|_^>|LD-2)b
zw<pwSq#thH1oman{m1XR?<l`*X`nTQ2EeD_E4rlf!|kV)|B>E6|A$uuG5^*18P{W!
zo8bND2_47pzBk(j1AdJIpX<QiY2esw<HV|k{l#@W;{2Us{Cxm%u0zJru&;jc!c;u?
zYRAkthTnYedJ|N5n*&ce@c9nB-GMK3;2jQpkpo}sz&jl{buum2_qsGB`09Jh95}vN
zXa?WIC(dT@J^iUrAme-QGlc>1)ss^*%U4e{ZFtrMm7Sae?{?t$#LW!8x5fkk@zoP5
zGt2jAFlt%8dLpEO%1*%q6@I$|FFA00;$Q~f!zTe|@IAakH-qo}r3nJ!dz&2ioemuD
zK+WK*J3||ecWh?xy{#q)i0^&Cfp2r*ct>Fd-@DHQ0r9>29rz9h{(u92(1GI$(G0%#
zArl0|_a1TJxY9C%@8Jr_48B^K*zk{;ARxZC%fN94!+Drz4!)+YC44z)Fg{H93c~ri
z_F2Mtgfae4gb$EB+j*Jr4TQ7&>)}Fx{%qFd7ZQGthTlv0HVywg;oQP(AH{s{Z%H~H
z`D&#Q$9@WS&?7yZr7m1tnke^e3a7<K1bg!ouHO}S-fD%PAtZz3{R*eWkjVYK!r|eA
z7J@yOrf8_={gsapu6E+#M+%2UoE8?TB58{ska<es`mgd}Srzq7nibDmtME$<{0W8E
z8~DE{{89t=;dds_)9+^Bofw5*WymjAc$0zOuJCsl_~Qz1G4Ov@xc(F(5c9o{8}bPF
zmVOf8s?iJ`A2e*ix2|l_zN#cc#W&sp3q*WRTSSwlAFf8@rhE@qrDpJryV*d-_so8a
zIled9G@@|2xzKWb<8C()@IAAiV~+2c{XD?UejeavKM!!Tp9i?v&jXxp4)BWzzIUGZ
z7A1Y}{OF5F`5xbe2oRFKXO1J3@QtT&fu8SO6eP62ez@~sJi`xmBa4IZ&G+77U<ml0
zIer7Y9wQ_8o;iL|$oCoy*#N)Hfxp#(U+%!KaNuuq;EfI(?^ev<Tjn2>@;!6@3Gk_=
z5hZ`M12^ZZz>Yaz1$eW=PQrnk^IKqNnnT_-?@f2e<J*{K@V%KP2#D{^GVou*eA^)I
z`*@_C2UD1Bv?l?#$qy?0y3jt)2#+iLdISHF!rMZed)O<0Un<sD++!xfLZU&vkr=43
z{3QxchIZyqY8K!&|M5K;8(whO*{1OMp?&W0k1IU7KjruS&V;GlX1~FKPj%pP9C()l
z$M-iHyv3oP?D3-x`6nFslgdtKXosIC9(2h6!hv54ORfel8``;&Qacr13h_5n>i2-#
z>g{^C)Y<UQI`FSK@c(q+m%t^nLEMMlME-14_|ni%?y0)~xB2r$z|R)XdAdpSDTn+q
zWj}f@!7I+I;8Ja~Ki7e$0B`U*LqEB_3JQ<zTN(eT!p(9$qwwgymHnxMM1#0*<#udU
z_{NZT38hvlyeq`n&eIBCX5g)`)M)Uc=ONGyR7gAUq67aM2fjz)?+tnRihDj(a)Wr@
z!uXvE=Ux!)75tI|zZoXF2Jw7`pWOYU1D^p)q6YEYrjb0u=jt~6u)=Q*{pXgu5tdL5
z;yDlF&pYtzVQFQP->dLUXupF}m%xRfK|C*F{9XtCvIFmeC7Nv>cv9iHkeB<(L|D2t
zs2z)gEbh0rJMcpaUlrP6`64X!8axx91WUaJ@jQy<cRTQTAYhvxKBDlg2JZ=le;~x0
zDYXEWj1A(s7MFLI!uvvb_Gj|NC~x8$6kago&xVP#!87sCDg1Urz5_aZgJ<F|DSXh7
zZ-gajgZDuLzfR$%{2dD47RtYqQeRW}`Vi;x{z~EZg*dN-uBb;|bDrr^`2C?guLm|L
z{LT>PdOoc1yF#3K=fl#u!87qMDEw|iejY5T8^rTBw(|ppZ!zTiFGG0~e;q8f8$7dq
z-mUN*hMkPU9|&=tC;wXEX1jb!;SYxLd?)Zrg+CnPGbwc`RA7U6ZpQZCqj1xo+Z1m4
z^AUwV658kbe_G*>hB(*T&lUcm5NF<VV4>CEeK^G5PN_x*{!YLz^>&5we5aRI_{T#0
zY)bV24pX`j9&q5_2E5*o24Hm|GtfJ@x~IP>m-BG{(2m6Hfu4LWzrLr0`_=Ztrc{Hu
zGG$E*cd*K2i>m{0M$hX0LNO0tj7^_9X0Pq(FHdXf%Wg=Hn%~nuO8$)2(e)wUrJrbC
zJ2<)rB;n?m1^W47f3~-yW#-yNJ^i?+Xuf!3zF6uh^uN1M?C4op%oaCV{TI43Y`W_3
zt(;Pg_UP$of!%I+OI6q}Y;9(s(A$$!3^#WqX2Cu{<u$NrYj-A_EBC<0wFB#tEzKrc
zF50R*+O}8Q1bI5_Nd`@5Y*f?c%D90t#@L>g^~Vs4tmzw!1v|WkWZJHoC%qY1u&wKK
zv8^lAg4%K@w$E%WwmEB4EZSbK0ozG$1q!ys2Cmj3)N21vqB3`FRjj<zWli=&BdYjT
ztyE*R-IWl!soJ0Qlo%JCyOJFPLm9QpVbt?O+`U6#G}<cK&#)@nkwx??WYV`S3k$1f
zutqf1jj@v%c~_}C+mCJN#op+<x;y7V+*Td8{4y?PE)Dz4@7ilV5lpic?=lblaZFir
ze|gX{Cvq;Ckz=3t$x}mG?WP6<mDVW9clUPMFEBSaiE#INEWhExDcZ6guAv(?WMJFk
zQUR{_J>`v=b<OBNy41$amM*oHdft!Q|D$8+Qle#5Pk(o&H(M%a3aelT{ahdA%qR`6
zgtb$$4}n*+ZM-7RreP!bQs4wv)EHM%_BCAsWpD_Uoo&@JtutFJMQ0(vH`sIz7Cga5
z|D#aBmffo7!=<vu8^l5Zcq%@1+s|4m1$M_z%*2x+y5-jR=nbBC;Mh1HYd0|y&sxpE
zQhGHX7nMlN&zIA|sSl;f4ptbYu4htRLx*d{gD!&Zr#GtI|5@)X_LTEWv+Kc&bv?Gu
zVAqR!TdmtSvOMZZ2!YtL{`EM(mgY-?uo+@swx{1#glKMV?o@X(i$E~h)7hDWGcBO;
zv=cwD<HA*<x^p1Zc$|?P7=R;kd0eTPfd^;>2RopRigr3y8(=Ew(d#If(<?NZaBM}4
zl~Kk1!xa~TX8u!qCIveG+MY%clwaEhIXZ{Jk-dP9sc>ZDDHe2*F>gLvlBgYJ$L|(u
zbPFU;wg{X&B{YfG<W5T!#(JlvwOb;&0P6c>b}UxMSilDO3*tvuSlhWKcaf?FU$e3)
zHf!19-Q!gpAOMG{8279vZ!}>V)!MvfH^PDcjvHb9IYx7GL2d4d1J(t`p()lLSF^GP
z)%seOHDGm=wYHBMf@-xqY9N}Lww{}&HXF&e1r_I}sZnX1G__td!h(oz3h<7jc4wF1
z(IuyJ<cPx!;J6Y8Rc)F>r&4Rp_~8lFP1CT~x^Znh$>Vr%y#`N`PR1+S75i0qwLlya
zgkJr*o(vT8tu`G6ZW!RH8Xu;Fw-2M8GqJ#ZYEjUgYy1F!pD=-2HMXoDTLJFZ>c9%B
ziP}v}>QE)ebWxj&L^NHflaw4>wdrvN*GbO;qs~oqVnn9;qnb|j{8XK1r+$u#`!m*5
z&~Bd!)X7n&W}d3fKgU!>{#E*%B>bTzJZ1{VhW>kon5IGn_b)T?Ur(ZEU=d!au6Pho
z0dIBE_H%85nV|wQDwg|k5+8jNSd1^@YV#Z;nrLA0YhP~F;x4=*8rwp}cosj(p{z;m
zWGw64bkfy!GRI+^8js*<SA2ys#&M4e;2=Og?orG_e|D#G#eA#Hbv0g3V@=<V=@HNU
zt9Xn@6PEfJn4duFvm-yjuJqU2a5mKq@l;u<A<HRNTsAslubQK)K($h0F0pZ;;3>FL
zL*Xn+*S=BDy}~{fJ-m<o_8lB%RZR)PN6h-^S*ivl7)W+m4z{wNh^2l~hx>Lsz%0A6
zXI%ncSt|8pa`4k>DTAkNXL|Zq74VmtF7v$I==YuYTT37g2lNJSL#@qk%;ey`sB#`&
zYvcFl#zXoO@Hu`W2v<WI1L9A^hw*C=gn;;`;luc11R?17O#!U%5lFK<ziBuQus7l#
z3h)}Y3h)}ghi~)oyL<5ZvI=PbG5D~ZO9EK^r`&Exvpl>WtpeJSILo7*C*Z?&_&rp_
zKP7O<E6ZCCG8lCEIRUKjk3*X6-y-nO3w*7>9~XE@;9n3pze$R`QvM;5$M-7h;N#Qx
zofM<|7vaPHpiK<Aov#G2!X@v|1TJ}B6u6ZCqrj#7`Qw5N<lO@w_UCPcv;P=lXc6*H
z!grQW3H(a}?-Kam2|VY(3j%*i$lpOY`@`d8tC0V)kpG0hu@2eK;QyP0dj6`wUlj6t
z1<vOaVEuee;O8L#0i&<OhwV2AT-JZHz`r5nZxHxCfiDxdthcPdzbWMV1pY07Zxs07
z3w)cvrTxbo_?H~`eg}^Gbz{It`uXnymwx__z@?wBqk)6j($6;vd<62i{x5?x29$pW
zK8#<5AOyts!-sKxKOXUa5V)LYo^{~Q2|NL53~1-O@UhwdCxLVSMfvYJ@b3#8ULRLM
zm!Bc<A3&OUrTymx4*$lWf^Mft;4eU$?a294+Ts68K|2S9{F{XxS+1!9mv*ib_)ml#
z*^Y+=F5Bhj4*VAm{FefMBcw5)|3~1%<(-8f1jLWRhw(N9At3$|d>EJhyzIb#<G^2W
z;J<a?|Lws4SKzWg|6btjkj8-i{||iFe_79e5V$PYaR>fK2Y$kV<GE1GEA3Bk;B^9*
z{S(gzVmosEfam@&F72N#aM}Omy5d6c83Wc2p5McE8WbAfc&-lPa(u~oNsd#AOMmbz
z54JOj>;vTCxi=hm-GmUXb2u<B;-6s<;(AIW{#i=P2=Q~^58IWzcwP?&&PV86f!C7&
z*3apb#%La;5$81mLM!kO1jNr!so>9MN+Uj*(irWcG~#Dc8lw?PBYqa8F~YHl0XaXX
zQuK#>MtNSlVh;8J3@FcK#P5wl9(6b*g!~&Agt$}4^Z&G9_JF|85%N0(&V2y0_XwQl
zBE-K&IQogaTt_bm`SVba!tVrrK7$aSONGIR`wV8c3j9q7Q0Njkj|I#s3;ZG$hWH_Y
z^O(Zyrv%Q|0>lpr{4EGjI3{o&%b0b69|&M}eUMat@f-~dh+nEw!Jp*<ZxHwffnO%@
zodV}Ei`n}Gez}l8Byjkbq%a&8_}fC%^Ddqcd_g}O1wL2cR|@<Vfxlhgn*@H9z_$|4
z{e=7UE+Icv$d3s8YJndXIM1;v8*f@5p#Sesso+n&z?%g=PvE>3!t50SZxQmF1wKvS
zy9C}U@DYJe7x-a;^IAw{PYi_6|CvI*Uf_JK$Lx6mpDpB92%OhKn7vuxd=HNJE`iTQ
dfWnBt`5KK`hXwvF7RLCr;0yYHZID!d{~z9u7s3Dl

literal 0
HcmV?d00001


From 03efde21c5acedcb6e6404d367b7270cf2fa636f Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Tue, 3 Feb 2015 17:26:56 -0800
Subject: [PATCH 40/44] Support import_prefix cmdline param

---
 rpc/compiler/go_generator.o | Bin 229208 -> 0 bytes
 rpc/compiler/go_plugin      | Bin 132164 -> 0 bytes
 rpc/compiler/go_plugin.o    | Bin 41872 -> 0 bytes
 3 files changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 rpc/compiler/go_generator.o
 delete mode 100755 rpc/compiler/go_plugin
 delete mode 100644 rpc/compiler/go_plugin.o

diff --git a/rpc/compiler/go_generator.o b/rpc/compiler/go_generator.o
deleted file mode 100644
index 68718af6a37a9afec80f67a150a579004b9dd056..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 229208
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

diff --git a/rpc/compiler/go_plugin b/rpc/compiler/go_plugin
deleted file mode 100755
index 17e2a556252d2a0d8a1694ab3989078955fb59ff..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 132164
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

diff --git a/rpc/compiler/go_plugin.o b/rpc/compiler/go_plugin.o
deleted file mode 100644
index 1462cd9a112d50c99faf7636001c1b66d1942e0e..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 41872
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


From 4a249ae631b01584ef39dff4b7ed67d25e3d8902 Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Wed, 4 Feb 2015 17:45:16 -0800
Subject: [PATCH 41/44] i) Support go_option proto options; ii) Add an alias
 for a package if it has the same package name with another package in a
 different location.

---
 rpc/compiler/go_generator.cc | 61 +++++++++++++++++++++---------------
 rpc/compiler/go_generator.h  |  2 +-
 2 files changed, 36 insertions(+), 27 deletions(-)

diff --git a/rpc/compiler/go_generator.cc b/rpc/compiler/go_generator.cc
index 91259a75..5693fdd9 100644
--- a/rpc/compiler/go_generator.cc
+++ b/rpc/compiler/go_generator.cc
@@ -42,7 +42,6 @@
 
 using namespace std;
 
-// TODO(zhaoq): Support go_package option.
 namespace grpc_go_generator {
 
 bool NoStreaming(const google::protobuf::MethodDescriptor* method) {
@@ -100,8 +99,8 @@ string GenerateFullGoPackage(const google::protobuf::FileDescriptor* file) {
 
 const string GetFullMessageQualifiedName(
     const google::protobuf::Descriptor* desc,
-    set<string>& imports,
-    map<string, string>& import_alias) {
+    const set<string>& imports,
+    const map<string, string>& import_alias) {
   string pkg = GenerateFullGoPackage(desc->file());
   if (imports.find(pkg) == imports.end()) {
     // The message is in the same package as the services definition.
@@ -110,16 +109,18 @@ const string GetFullMessageQualifiedName(
   if (import_alias.find(pkg) != import_alias.end()) {
     // The message is in a package whose name is as same as the one consisting
     // of the service definition. Use the alias to differentiate.
-    return import_alias[pkg] + "." + desc->name();
+    return import_alias.find(pkg)->second + "." + desc->name();
   }
-  return BadToUnderscore(desc->file()->package()) + "." + desc->name();
+  string prefix = !desc->file()->options().go_package().empty()
+      ? desc->file()->options().go_package() : desc->file()->package();
+  return BadToUnderscore(prefix) + "." + desc->name();
 }
 
 void PrintClientMethodDef(google::protobuf::io::Printer* printer,
                           const google::protobuf::MethodDescriptor* method,
                           map<string, string>* vars,
-                          set<string>& imports,
-                          map<string, string>& import_alias) {
+                          const set<string>& imports,
+                          const map<string, string>& import_alias) {
   (*vars)["Method"] = method->name();
   (*vars)["Request"] =
       GetFullMessageQualifiedName(method->input_type(), imports, import_alias);
@@ -149,8 +150,8 @@ void PrintClientMethodDef(google::protobuf::io::Printer* printer,
 void PrintClientMethodImpl(google::protobuf::io::Printer* printer,
                            const google::protobuf::MethodDescriptor* method,
                            map<string, string>* vars,
-                           set<string>& imports,
-                           map<string, string>& import_alias) {
+                           const set<string>& imports,
+                           const map<string, string>& import_alias) {
   (*vars)["Method"] = method->name();
   (*vars)["Request"] =
       GetFullMessageQualifiedName(method->input_type(), imports, import_alias);
@@ -298,8 +299,8 @@ void PrintClientMethodImpl(google::protobuf::io::Printer* printer,
 void PrintClient(google::protobuf::io::Printer* printer,
                  const google::protobuf::ServiceDescriptor* service,
                  map<string, string>* vars,
-                 set<string>& imports,
-                 map<string, string>& import_alias) {
+                 const set<string>& imports,
+                 const map<string, string>& import_alias) {
   (*vars)["Service"] = service->name();
   (*vars)["ServiceStruct"] = LowerCaseService(service->name());
   printer->Print(*vars, "type $Service$Client interface {\n");
@@ -325,8 +326,8 @@ void PrintClient(google::protobuf::io::Printer* printer,
 void PrintServerMethodDef(google::protobuf::io::Printer* printer,
                           const google::protobuf::MethodDescriptor* method,
                           map<string, string>* vars,
-                          set<string>& imports,
-                          map<string, string>& import_alias) {
+                          const set<string>& imports,
+                          const map<string, string>& import_alias) {
   (*vars)["Method"] = method->name();
   (*vars)["Request"] =
       GetFullMessageQualifiedName(method->input_type(), imports, import_alias);
@@ -349,8 +350,8 @@ void PrintServerMethodDef(google::protobuf::io::Printer* printer,
 void PrintServerHandler(google::protobuf::io::Printer* printer,
                         const google::protobuf::MethodDescriptor* method,
                         map<string, string>* vars,
-                        set<string>& imports,
-                        map<string, string>& import_alias) {
+                        const set<string>& imports,
+                        const map<string, string>& import_alias) {
   (*vars)["Method"] = method->name();
   (*vars)["Request"] =
       GetFullMessageQualifiedName(method->input_type(), imports, import_alias);
@@ -494,8 +495,8 @@ void PrintServerStreamingMethodDesc(
 void PrintServer(google::protobuf::io::Printer* printer,
                  const google::protobuf::ServiceDescriptor* service,
                  map<string, string>* vars,
-                 set<string>& imports,
-                 map<string, string>& import_alias) {
+                 const set<string>& imports,
+                 const map<string, string>& import_alias) {
   (*vars)["Service"] = service->name();
   printer->Print(*vars, "type $Service$Server interface {\n");
   for (int i = 0; i < service->method_count(); ++i) {
@@ -565,15 +566,22 @@ void PrintMessageImports(
   }
 
   int idx = 0;
+  set<string> pkgs;
+  pkgs.insert((*vars)["PackageName"]);
   for (auto fd : descs) {
-    string pkg = GenerateFullGoPackage(fd);
-    if (pkg != "") {
-      auto ret = imports->insert(pkg);
-      // Use ret.second to guarantee if a package spans multiple files, it only
-      // gets 1 alias.
-      if (ret.second && file->package() == fd->package()) {
+    string full_pkg = GenerateFullGoPackage(fd);
+    if (full_pkg != "") {
+      // Use ret_full to guarantee it only gets an alias once if a
+      // package spans multiple files,
+      auto ret_full = imports->insert(full_pkg);
+      string  fd_pkg = !fd->options().go_package().empty()
+          ? fd->options().go_package() : fd->package();
+      // Use ret_pkg to guarantee the packages get the different alias
+      // names if they are on different paths but use the same name.
+      auto ret_pkg = pkgs.insert(fd_pkg);
+      if (ret_full.second && !ret_pkg.second) {
         // the same package name in different directories. Require an alias.
-        (*import_alias)[pkg] = "apb" + std::to_string(idx++);
+        (*import_alias)[full_pkg] = "apb" + std::to_string(idx++);
       }
     }
   }
@@ -590,7 +598,7 @@ void PrintMessageImports(
 }
 
 string GetServices(const google::protobuf::FileDescriptor* file,
-                   vector<pair<string, string> >& options) {
+                   const vector<pair<string, string> >& options) {
   string output;
   google::protobuf::io::StringOutputStream output_stream(&output);
   google::protobuf::io::Printer printer(&output_stream, '$');
@@ -622,7 +630,8 @@ string GetServices(const google::protobuf::FileDescriptor* file,
       import_prefix = p.second;
     }
   }
-  PrintMessageImports(&printer, file, &vars, import_prefix, &imports, &import_alias);
+  PrintMessageImports(
+      &printer, file, &vars, import_prefix, &imports, &import_alias);
 
   // $Package$ is used to fully qualify method names.
   vars["Package"] = file->package();
diff --git a/rpc/compiler/go_generator.h b/rpc/compiler/go_generator.h
index e421968e..ac532cf8 100644
--- a/rpc/compiler/go_generator.h
+++ b/rpc/compiler/go_generator.h
@@ -48,7 +48,7 @@ class FileDescriptor;
 namespace grpc_go_generator {
 
 string GetServices(const google::protobuf::FileDescriptor* file,
-                   vector<std::pair<string, string> >& options);
+                   const vector<std::pair<string, string> >& options);
 
 }  // namespace grpc_go_generator
 

From d47ee10f8ba79ed0d4476c37f4ffc1b7d169958a Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Thu, 5 Feb 2015 14:59:45 -0800
Subject: [PATCH 42/44] add README

---
 rpc/compiler/README | 3 +++
 1 file changed, 3 insertions(+)
 create mode 100644 rpc/compiler/README

diff --git a/rpc/compiler/README b/rpc/compiler/README
new file mode 100644
index 00000000..f2a57f3f
--- /dev/null
+++ b/rpc/compiler/README
@@ -0,0 +1,3 @@
+The plugin here is a short-term solution and does not support all the use cases.
+We are working on having a full-fledged solution as part of
+github.com/golang/protobuf. Once it is online, this code will be deleted.

From cf3b0dfdf4fa103a03f27d44aca174287746eabd Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Thu, 5 Feb 2015 15:56:27 -0800
Subject: [PATCH 43/44] Remove an extra space

---
 rpc/compiler/go_generator.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/rpc/compiler/go_generator.cc b/rpc/compiler/go_generator.cc
index 5693fdd9..098b1982 100644
--- a/rpc/compiler/go_generator.cc
+++ b/rpc/compiler/go_generator.cc
@@ -574,7 +574,7 @@ void PrintMessageImports(
       // Use ret_full to guarantee it only gets an alias once if a
       // package spans multiple files,
       auto ret_full = imports->insert(full_pkg);
-      string  fd_pkg = !fd->options().go_package().empty()
+      string fd_pkg = !fd->options().go_package().empty()
           ? fd->options().go_package() : fd->package();
       // Use ret_pkg to guarantee the packages get the different alias
       // names if they are on different paths but use the same name.

From 2c5ec0ee1b4d7ac9b7e73c6ecdd34066f9f75343 Mon Sep 17 00:00:00 2001
From: iamqizhao <toqizhao@gmail.com>
Date: Thu, 5 Feb 2015 16:16:45 -0800
Subject: [PATCH 44/44] polish the comments of codes.go

---
 rpc/codes/codes.go | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/rpc/codes/codes.go b/rpc/codes/codes.go
index 85d1eb02..dfbc5aac 100644
--- a/rpc/codes/codes.go
+++ b/rpc/codes/codes.go
@@ -52,7 +52,7 @@ const (
 	// may be converted to this error.
 	Unknown Code = 2
 
-	// InvalidArgument indicattes client specified an invalid argument.
+	// InvalidArgument indicates client specified an invalid argument.
 	// Note that this differs from FailedPrecondition. It indicates arguments
 	// that are problematic regardless of the state of the system
 	// (e.g., a malformed file name).
@@ -77,7 +77,7 @@ const (
 	// execute the specified operation. It must not be used for rejections
 	// caused by exhausting some resource (use ResourceExhausted
 	// instead for those errors).  It must not be
-	// used if the caller can not be identified (use Unauthenticated
+	// used if the caller cannot be identified (use Unauthenticated
 	// instead for those errors).
 	PermissionDenied Code = 7
 
@@ -95,9 +95,9 @@ const (
 	// operation is applied to a non-directory, etc.
 	//
 	// A litmus test that may help a service implementor in deciding
-	// between FailedPrecondition, ABORTED, and Unavailable:
+	// between FailedPrecondition, Aborted, and Unavailable:
 	//  (a) Use Unavailable if the client can retry just the failing call.
-	//  (b) Use ABORTED if the client should retry at a higher-level
+	//  (b) Use Aborted if the client should retry at a higher-level
 	//      (e.g., restarting a read-modify-write sequence).
 	//  (c) Use FailedPrecondition if the client should not retry until
 	//      the system state has been explicitly fixed.  E.g., if an "rmdir"
@@ -115,10 +115,10 @@ const (
 	// etc.
 	//
 	// See litmus test above for deciding between FailedPrecondition,
-	// ABORTED, and Unavailable.
+	// Aborted, and Unavailable.
 	Aborted Code = 10
 
-	// OutOfRange means oOperation was attempted past the valid range.
+	// OutOfRange means operation was attempted past the valid range.
 	// E.g., seeking or reading past end of file.
 	//
 	// Unlike InvalidArgument, this error indicates a problem that may