Add basic OAuth support to gRPC.

The primary functionality is an interceptor that authenticates calls using oauth. However, most of the changes are for an integration test to make sure the code works with ESF.

This is based on work by lryan and simonma.
-------------
Created by MOE: http://code.google.com/p/moe-java
MOE_MIGRATED_REVID=72567773
diff --git a/core/src/main/java/com/google/net/stubby/newtransport/HttpUtil.java b/core/src/main/java/com/google/net/stubby/newtransport/HttpUtil.java
index c049091..2b6c56f 100644
--- a/core/src/main/java/com/google/net/stubby/newtransport/HttpUtil.java
+++ b/core/src/main/java/com/google/net/stubby/newtransport/HttpUtil.java
@@ -2,6 +2,8 @@
 
 import com.google.net.stubby.transport.Transport;
 
+import java.net.HttpURLConnection;
+
 /**
  * Constants for GRPC-over-HTTP (or HTTP/2)
  */
@@ -32,6 +34,15 @@
    * Maps HTTP error response status codes to transport codes.
    */
   public static Transport.Code httpStatusToTransportCode(int httpStatusCode) {
+    // Specific HTTP code handling.
+    switch (httpStatusCode) {
+      case HttpURLConnection.HTTP_UNAUTHORIZED: // 401
+        return Transport.Code.UNAUTHENTICATED;
+      case HttpURLConnection.HTTP_FORBIDDEN: // 403
+        return Transport.Code.PERMISSION_DENIED;
+      default:
+    }
+    // Generic HTTP code handling.
     if (httpStatusCode < 300) {
       return Transport.Code.OK;
     }
diff --git a/core/src/main/java/com/google/net/stubby/newtransport/netty/NettyClientHandler.java b/core/src/main/java/com/google/net/stubby/newtransport/netty/NettyClientHandler.java
index b4c7ec6..7a83149 100644
--- a/core/src/main/java/com/google/net/stubby/newtransport/netty/NettyClientHandler.java
+++ b/core/src/main/java/com/google/net/stubby/newtransport/netty/NettyClientHandler.java
@@ -125,7 +125,7 @@
       boolean endSegment) throws Http2Exception {
     // TODO(user): Assuming that all headers fit in a single HEADERS frame.
     NettyClientStream stream = clientStream(connection().requireStream(streamId));
-    stream.inboundHeadersRecieved(headers);
+    stream.inboundHeadersRecieved(headers, endStream);
   }
 
   /**
diff --git a/core/src/main/java/com/google/net/stubby/newtransport/netty/NettyClientStream.java b/core/src/main/java/com/google/net/stubby/newtransport/netty/NettyClientStream.java
index f0f33c5..c9c3c06 100644
--- a/core/src/main/java/com/google/net/stubby/newtransport/netty/NettyClientStream.java
+++ b/core/src/main/java/com/google/net/stubby/newtransport/netty/NettyClientStream.java
@@ -61,9 +61,12 @@
   /**
    * Called in the channel thread to process headers received from the server.
    */
-  public void inboundHeadersRecieved(Http2Headers headers) {
+  public void inboundHeadersRecieved(Http2Headers headers, boolean endOfStream) {
     responseCode = responseCode(headers);
     isGrpcResponse = isGrpcResponse(headers, responseCode);
+    if (!isGrpcResponse && endOfStream) {
+      setStatus(new Status(responseCode));
+    }
   }
 
   /**
diff --git a/core/src/test/java/com/google/net/stubby/newtransport/netty/NettyClientHandlerTest.java b/core/src/test/java/com/google/net/stubby/newtransport/netty/NettyClientHandlerTest.java
index 5123105..39dfe02 100644
--- a/core/src/test/java/com/google/net/stubby/newtransport/netty/NettyClientHandlerTest.java
+++ b/core/src/test/java/com/google/net/stubby/newtransport/netty/NettyClientHandlerTest.java
@@ -187,7 +187,7 @@
         .set(HttpUtil.CONTENT_TYPE_HEADER, HttpUtil.CONTENT_TYPE_PROTORPC).build();
     ByteBuf headersFrame = headersFrame(3, headers);
     handler.channelRead(this.ctx, headersFrame);
-    verify(stream).inboundHeadersRecieved(headers);
+    verify(stream).inboundHeadersRecieved(headers, false);
   }
 
   @Test
diff --git a/core/src/test/java/com/google/net/stubby/newtransport/netty/NettyClientStreamTest.java b/core/src/test/java/com/google/net/stubby/newtransport/netty/NettyClientStreamTest.java
index 43473d4..54b68a3 100644
--- a/core/src/test/java/com/google/net/stubby/newtransport/netty/NettyClientStreamTest.java
+++ b/core/src/test/java/com/google/net/stubby/newtransport/netty/NettyClientStreamTest.java
@@ -171,7 +171,7 @@
   @Test
   public void inboundContextShouldCallListener() throws Exception {
     // Receive headers first so that it's a valid GRPC response.
-    stream.inboundHeadersRecieved(grpcResponseHeaders());
+    stream.inboundHeadersRecieved(grpcResponseHeaders(), false);
 
     stream.inboundDataReceived(contextFrame(), false, promise);
     ArgumentCaptor<InputStream> captor = ArgumentCaptor.forClass(InputStream.class);
@@ -183,7 +183,7 @@
   @Test
   public void inboundMessageShouldCallListener() throws Exception {
     // Receive headers first so that it's a valid GRPC response.
-    stream.inboundHeadersRecieved(grpcResponseHeaders());
+    stream.inboundHeadersRecieved(grpcResponseHeaders(), false);
 
     stream.inboundDataReceived(messageFrame(), false, promise);
     ArgumentCaptor<InputStream> captor = ArgumentCaptor.forClass(InputStream.class);
@@ -197,7 +197,7 @@
     stream.id(1);
 
     // Receive headers first so that it's a valid GRPC response.
-    stream.inboundHeadersRecieved(grpcResponseHeaders());
+    stream.inboundHeadersRecieved(grpcResponseHeaders(), false);
 
     stream.inboundDataReceived(statusFrame(), false, promise);
     ArgumentCaptor<Status> captor = ArgumentCaptor.forClass(Status.class);
diff --git a/stub/src/main/java/com/google/net/stubby/stub/AbstractStub.java b/stub/src/main/java/com/google/net/stubby/stub/AbstractStub.java
index b201330..f073263 100644
--- a/stub/src/main/java/com/google/net/stubby/stub/AbstractStub.java
+++ b/stub/src/main/java/com/google/net/stubby/stub/AbstractStub.java
@@ -35,6 +35,10 @@
     return new StubConfigBuilder();
   }
 
+  public Channel getChannel() {
+    return channel;
+  }
+
   /**
    * Returns a new stub configuration for the provided method configurations.
    */
@@ -46,8 +50,10 @@
   public class StubConfigBuilder {
 
     private final Map<String, MethodDescriptor> methodMap;
+    private Channel channel;
 
     private StubConfigBuilder() {
+      this.channel = AbstractStub.this.channel;
       methodMap = Maps.newHashMapWithExpectedSize(config.methods().size());
       for (MethodDescriptor method : AbstractStub.this.config.methods()) {
         methodMap.put(method.getName(), method);
@@ -75,6 +81,14 @@
     }
 
     /**
+     * Set the channel to be used by the stub.
+     */
+    public StubConfigBuilder setChannel(Channel channel) {
+      this.channel = channel;
+      return this;
+    }
+
+    /**
      * Create a new stub configuration
      */
     public S build() {