• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 The gRPC Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package io.grpc.testing.integration;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNotNull;
21 import static org.junit.Assert.assertTrue;
22 
23 import com.google.common.base.Throwables;
24 import com.squareup.okhttp.ConnectionSpec;
25 import io.grpc.ChannelCredentials;
26 import io.grpc.ManagedChannel;
27 import io.grpc.ServerBuilder;
28 import io.grpc.ServerCredentials;
29 import io.grpc.TlsChannelCredentials;
30 import io.grpc.TlsServerCredentials;
31 import io.grpc.internal.GrpcUtil;
32 import io.grpc.internal.testing.StreamRecorder;
33 import io.grpc.internal.testing.TestUtils;
34 import io.grpc.netty.InternalNettyServerBuilder;
35 import io.grpc.netty.NettyServerBuilder;
36 import io.grpc.okhttp.InternalOkHttpChannelBuilder;
37 import io.grpc.okhttp.OkHttpChannelBuilder;
38 import io.grpc.okhttp.internal.Platform;
39 import io.grpc.stub.StreamObserver;
40 import io.grpc.testing.TlsTesting;
41 import io.grpc.testing.integration.EmptyProtos.Empty;
42 import java.io.IOException;
43 import java.net.InetSocketAddress;
44 import javax.net.ssl.HostnameVerifier;
45 import javax.net.ssl.SSLPeerUnverifiedException;
46 import javax.net.ssl.SSLSession;
47 import org.junit.Test;
48 import org.junit.runner.RunWith;
49 import org.junit.runners.JUnit4;
50 
51 /**
52  * Integration tests for GRPC over Http2 using the OkHttp framework.
53  */
54 @RunWith(JUnit4.class)
55 public class Http2OkHttpTest extends AbstractInteropTest {
56 
57   private static final String BAD_HOSTNAME = "I.am.a.bad.hostname";
58 
59   @Override
getServerBuilder()60   protected ServerBuilder<?> getServerBuilder() {
61     // Starts the server with HTTPS.
62     try {
63       ServerCredentials serverCreds = TlsServerCredentials.create(
64           TlsTesting.loadCert("server1.pem"), TlsTesting.loadCert("server1.key"));
65       NettyServerBuilder builder = NettyServerBuilder.forPort(0, serverCreds)
66           .flowControlWindow(AbstractInteropTest.TEST_FLOW_CONTROL_WINDOW)
67           .maxInboundMessageSize(AbstractInteropTest.MAX_MESSAGE_SIZE);
68       // Disable the default census stats tracer, use testing tracer instead.
69       InternalNettyServerBuilder.setStatsEnabled(builder, false);
70       return builder.addStreamTracerFactory(createCustomCensusTracerFactory());
71     } catch (IOException ex) {
72       throw new RuntimeException(ex);
73     }
74   }
75 
76   @Override
createChannelBuilder()77   protected OkHttpChannelBuilder createChannelBuilder() {
78     int port = ((InetSocketAddress) getListenAddress()).getPort();
79     ChannelCredentials channelCreds;
80     try {
81       channelCreds = TlsChannelCredentials.newBuilder()
82           .trustManager(TlsTesting.loadCert("ca.pem"))
83           .build();
84     } catch (IOException ex) {
85       throw new RuntimeException(ex);
86     }
87     OkHttpChannelBuilder builder = OkHttpChannelBuilder.forAddress("localhost", port, channelCreds)
88         .maxInboundMessageSize(AbstractInteropTest.MAX_MESSAGE_SIZE)
89         .overrideAuthority(GrpcUtil.authorityFromHostAndPort(
90             TestUtils.TEST_SERVER_HOST, port));
91     // Disable the default census stats interceptor, use testing interceptor instead.
92     InternalOkHttpChannelBuilder.setStatsEnabled(builder, false);
93     return builder.intercept(createCensusStatsClientInterceptor());
94   }
95 
createChannelBuilderPreCredentialsApi()96   private OkHttpChannelBuilder createChannelBuilderPreCredentialsApi() {
97     int port = ((InetSocketAddress) getListenAddress()).getPort();
98     OkHttpChannelBuilder builder = OkHttpChannelBuilder.forAddress("localhost", port)
99         .maxInboundMessageSize(AbstractInteropTest.MAX_MESSAGE_SIZE)
100         .connectionSpec(new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
101             .build())
102         .overrideAuthority(GrpcUtil.authorityFromHostAndPort(
103             TestUtils.TEST_SERVER_HOST, port));
104     try {
105       builder.sslSocketFactory(TestUtils.newSslSocketFactoryForCa(Platform.get().getProvider(),
106           TestUtils.loadCert("ca.pem")));
107     } catch (Exception e) {
108       throw new RuntimeException(e);
109     }
110     // Disable the default census stats interceptor, use testing interceptor instead.
111     InternalOkHttpChannelBuilder.setStatsEnabled(builder, false);
112     return builder.intercept(createCensusStatsClientInterceptor());
113   }
114 
115   @Test
receivedDataForFinishedStream()116   public void receivedDataForFinishedStream() throws Exception {
117     Messages.ResponseParameters.Builder responseParameters =
118         Messages.ResponseParameters.newBuilder()
119         .setSize(1);
120     Messages.StreamingOutputCallRequest.Builder requestBuilder =
121         Messages.StreamingOutputCallRequest.newBuilder();
122     for (int i = 0; i < 1000; i++) {
123       requestBuilder.addResponseParameters(responseParameters);
124     }
125 
126     StreamRecorder<Messages.StreamingOutputCallResponse> recorder = StreamRecorder.create();
127     StreamObserver<Messages.StreamingOutputCallRequest> requestStream =
128         asyncStub.fullDuplexCall(recorder);
129     Messages.StreamingOutputCallRequest request = requestBuilder.build();
130     requestStream.onNext(request);
131     recorder.firstValue().get();
132     requestStream.onError(new Exception("failed"));
133 
134     recorder.awaitCompletion();
135 
136     assertEquals(EMPTY, blockingStub.emptyCall(EMPTY));
137   }
138 
139   @Test
wrongHostNameFailHostnameVerification()140   public void wrongHostNameFailHostnameVerification() throws Exception {
141     int port = ((InetSocketAddress) getListenAddress()).getPort();
142     ManagedChannel channel = createChannelBuilderPreCredentialsApi()
143         .overrideAuthority(GrpcUtil.authorityFromHostAndPort(
144             BAD_HOSTNAME, port))
145         .build();
146     TestServiceGrpc.TestServiceBlockingStub blockingStub =
147         TestServiceGrpc.newBlockingStub(channel);
148 
149     Throwable actualThrown = null;
150     try {
151       blockingStub.emptyCall(Empty.getDefaultInstance());
152     } catch (Throwable t) {
153       actualThrown = t;
154     }
155     assertNotNull("The rpc should have been failed due to hostname verification", actualThrown);
156     Throwable cause = Throwables.getRootCause(actualThrown);
157     assertTrue(
158         "Failed by unexpected exception: " + cause, cause instanceof SSLPeerUnverifiedException);
159     channel.shutdown();
160   }
161 
162   @Test
hostnameVerifierWithBadHostname()163   public void hostnameVerifierWithBadHostname() throws Exception {
164     int port = ((InetSocketAddress) getListenAddress()).getPort();
165     ManagedChannel channel = createChannelBuilderPreCredentialsApi()
166         .overrideAuthority(GrpcUtil.authorityFromHostAndPort(
167             BAD_HOSTNAME, port))
168         .hostnameVerifier(new HostnameVerifier() {
169           @Override
170           public boolean verify(String hostname, SSLSession session) {
171             return true;
172           }
173         })
174         .build();
175     TestServiceGrpc.TestServiceBlockingStub blockingStub =
176         TestServiceGrpc.newBlockingStub(channel);
177 
178     blockingStub.emptyCall(Empty.getDefaultInstance());
179 
180     channel.shutdown();
181   }
182 
183   @Test
hostnameVerifierWithCorrectHostname()184   public void hostnameVerifierWithCorrectHostname() throws Exception {
185     int port = ((InetSocketAddress) getListenAddress()).getPort();
186     ManagedChannel channel = createChannelBuilderPreCredentialsApi()
187         .overrideAuthority(GrpcUtil.authorityFromHostAndPort(
188             TestUtils.TEST_SERVER_HOST, port))
189         .hostnameVerifier(new HostnameVerifier() {
190           @Override
191           public boolean verify(String hostname, SSLSession session) {
192             return false;
193           }
194         })
195         .build();
196     TestServiceGrpc.TestServiceBlockingStub blockingStub =
197         TestServiceGrpc.newBlockingStub(channel);
198 
199     Throwable actualThrown = null;
200     try {
201       blockingStub.emptyCall(Empty.getDefaultInstance());
202     } catch (Throwable t) {
203       actualThrown = t;
204     }
205     assertNotNull("The rpc should have been failed due to hostname verification", actualThrown);
206     Throwable cause = Throwables.getRootCause(actualThrown);
207     assertTrue(
208         "Failed by unexpected exception: " + cause, cause instanceof SSLPeerUnverifiedException);
209     channel.shutdown();
210   }
211 }
212