@Test public void proxy_500() throws Exception { ServerSocket serverSocket = new ServerSocket(0); clientTransport = new OkHttpClientTransport( InetSocketAddress.createUnresolved("theservice", 80), "authority", "userAgent", executor, sslSocketFactory, hostnameVerifier, ConnectionSpec.CLEARTEXT, DEFAULT_MAX_MESSAGE_SIZE, INITIAL_WINDOW_SIZE, new ProxyParameters( (InetSocketAddress) serverSocket.getLocalSocketAddress(), NO_USER, NO_PW), tooManyPingsRunnable, DEFAULT_MAX_INBOUND_METADATA_SIZE, transportTracer); clientTransport.start(transportListener); Socket sock = serverSocket.accept(); serverSocket.close(); BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream(), UTF_8)); assertEquals("CONNECT theservice:80 HTTP/1.1", reader.readLine()); assertEquals("Host: theservice:80", reader.readLine()); while (!"".equals(reader.readLine())) {} final String errorText = "text describing error"; sock.getOutputStream().write("HTTP/1.1 500 OH NO\r\n\r\n".getBytes(UTF_8)); sock.getOutputStream().write(errorText.getBytes(UTF_8)); sock.getOutputStream().flush(); sock.shutdownOutput(); assertEquals(-1, sock.getInputStream().read()); ArgumentCaptor<Status> captor = ArgumentCaptor.forClass(Status.class); verify(transportListener, timeout(TIME_OUT_MS)).transportShutdown(captor.capture()); Status error = captor.getValue(); assertTrue("Status didn't contain error code: " + captor.getValue(), error.getDescription().contains("500")); assertTrue("Status didn't contain error description: " + captor.getValue(), error.getDescription().contains("OH NO")); assertTrue("Status didn't contain error text: " + captor.getValue(), error.getDescription().contains(errorText)); assertEquals("Not UNAVAILABLE: " + captor.getValue(), Status.UNAVAILABLE.getCode(), error.getCode()); sock.close(); verify(transportListener, timeout(TIME_OUT_MS)).transportTerminated(); }
@Override public Runnable start(Listener listener) { this.listener = Preconditions.checkNotNull(listener, "listener"); if (enableKeepAlive) { scheduler = SharedResourceHolder.get(TIMER_SERVICE); keepAliveManager = new KeepAliveManager( new ClientKeepAlivePinger(this), scheduler, keepAliveTimeNanos, keepAliveTimeoutNanos, keepAliveWithoutCalls); keepAliveManager.onTransportStarted(); } frameWriter = new AsyncFrameWriter(this, serializingExecutor); outboundFlow = new OutboundFlowController(this, frameWriter, initialWindowSize); serializingExecutor.execute(new Runnable() { @Override public void run() { if (isForTest()) { if (connectingCallback != null) { connectingCallback.run(); } clientFrameHandler = new ClientFrameHandler(testFrameReader); executor.execute(clientFrameHandler); synchronized (lock) { maxConcurrentStreams = Integer.MAX_VALUE; startPendingStreams(); } frameWriter.becomeConnected(testFrameWriter, socket); connectedFuture.set(null); return; } BufferedSource source = Okio.buffer(new Source() { @Override public long read(Buffer sink, long byteCount) { return -1; } @Override public Timeout timeout() { return Timeout.NONE; } @Override public void close() {} }); Variant variant = new Http2(); BufferedSink sink; Socket sock; SSLSession sslSession = null; try { if (proxy == null) { sock = new Socket(address.getAddress(), address.getPort()); } else { sock = createHttpProxySocket( address, proxy.proxyAddress, proxy.username, proxy.password); } if (sslSocketFactory != null) { SSLSocket sslSocket = OkHttpTlsUpgrader.upgrade( sslSocketFactory, hostnameVerifier, sock, getOverridenHost(), getOverridenPort(), connectionSpec); sslSession = sslSocket.getSession(); sock = sslSocket; } sock.setTcpNoDelay(true); source = Okio.buffer(Okio.source(sock)); sink = Okio.buffer(Okio.sink(sock)); attributes = Attributes .newBuilder() .set(Grpc.TRANSPORT_ATTR_REMOTE_ADDR, sock.getRemoteSocketAddress()) .set(Grpc.TRANSPORT_ATTR_LOCAL_ADDR, sock.getLocalSocketAddress()) .set(Grpc.TRANSPORT_ATTR_SSL_SESSION, sslSession) .set(GrpcAttributes.ATTR_SECURITY_LEVEL, sslSession == null ? SecurityLevel.NONE : SecurityLevel.PRIVACY_AND_INTEGRITY) .build(); } catch (StatusException e) { startGoAway(0, ErrorCode.INTERNAL_ERROR, e.getStatus()); return; } catch (Exception e) { onException(e); return; } finally { clientFrameHandler = new ClientFrameHandler(variant.newReader(source, true)); executor.execute(clientFrameHandler); } FrameWriter rawFrameWriter; synchronized (lock) { socket = Preconditions.checkNotNull(sock, "socket"); maxConcurrentStreams = Integer.MAX_VALUE; startPendingStreams(); if (sslSession != null) { securityInfo = new InternalChannelz.Security(new InternalChannelz.Tls(sslSession)); } } rawFrameWriter = variant.newWriter(sink, true); frameWriter.becomeConnected(rawFrameWriter, socket); try { rawFrameWriter.connectionPreface(); Settings settings = new Settings(); rawFrameWriter.settings(settings); } catch (Exception e) { onException(e); return; } } }); return null; }
OkHttpClientTransport implements ConnectionClientTransport, TransportExceptionHandler { @Override public Runnable start(Listener listener) { this.listener = Preconditions.checkNotNull(listener, "listener"); if (enableKeepAlive) { scheduler = SharedResourceHolder.get(TIMER_SERVICE); keepAliveManager = new KeepAliveManager( new ClientKeepAlivePinger(this), scheduler, keepAliveTimeNanos, keepAliveTimeoutNanos, keepAliveWithoutCalls); keepAliveManager.onTransportStarted(); } frameWriter = new AsyncFrameWriter(this, serializingExecutor); outboundFlow = new OutboundFlowController(this, frameWriter, initialWindowSize); serializingExecutor.execute(new Runnable() { @Override public void run() { if (isForTest()) { if (connectingCallback != null) { connectingCallback.run(); } clientFrameHandler = new ClientFrameHandler(testFrameReader); executor.execute(clientFrameHandler); synchronized (lock) { maxConcurrentStreams = Integer.MAX_VALUE; startPendingStreams(); } frameWriter.becomeConnected(testFrameWriter, socket); connectedFuture.set(null); return; } BufferedSource source = Okio.buffer(new Source() { @Override public long read(Buffer sink, long byteCount) { return -1; } @Override public Timeout timeout() { return Timeout.NONE; } @Override public void close() {} }); Variant variant = new Http2(); BufferedSink sink; Socket sock; SSLSession sslSession = null; try { if (proxy == null) { sock = new Socket(address.getAddress(), address.getPort()); } else { sock = createHttpProxySocket( address, proxy.proxyAddress, proxy.username, proxy.password); } if (sslSocketFactory != null) { SSLSocket sslSocket = OkHttpTlsUpgrader.upgrade( sslSocketFactory, hostnameVerifier, sock, getOverridenHost(), getOverridenPort(), connectionSpec); sslSession = sslSocket.getSession(); sock = sslSocket; } sock.setTcpNoDelay(true); source = Okio.buffer(Okio.source(sock)); sink = Okio.buffer(Okio.sink(sock)); attributes = Attributes .newBuilder() .set(Grpc.TRANSPORT_ATTR_REMOTE_ADDR, sock.getRemoteSocketAddress()) .set(Grpc.TRANSPORT_ATTR_LOCAL_ADDR, sock.getLocalSocketAddress()) .set(Grpc.TRANSPORT_ATTR_SSL_SESSION, sslSession) .set(GrpcAttributes.ATTR_SECURITY_LEVEL, sslSession == null ? SecurityLevel.NONE : SecurityLevel.PRIVACY_AND_INTEGRITY) .build(); } catch (StatusException e) { startGoAway(0, ErrorCode.INTERNAL_ERROR, e.getStatus()); return; } catch (Exception e) { onException(e); return; } finally { clientFrameHandler = new ClientFrameHandler(variant.newReader(source, true)); executor.execute(clientFrameHandler); } FrameWriter rawFrameWriter; synchronized (lock) { socket = Preconditions.checkNotNull(sock, "socket"); maxConcurrentStreams = Integer.MAX_VALUE; startPendingStreams(); if (sslSession != null) { securityInfo = new InternalChannelz.Security(new InternalChannelz.Tls(sslSession)); } } rawFrameWriter = variant.newWriter(sink, true); frameWriter.becomeConnected(rawFrameWriter, socket); try { rawFrameWriter.connectionPreface(); Settings settings = new Settings(); rawFrameWriter.settings(settings); } catch (Exception e) { onException(e); return; } } }); return null; } }
OkHttpClientTransport implements ConnectionClientTransport, TransportExceptionHandler { @Override public Runnable start(Listener listener) { this.listener = Preconditions.checkNotNull(listener, "listener"); if (enableKeepAlive) { scheduler = SharedResourceHolder.get(TIMER_SERVICE); keepAliveManager = new KeepAliveManager( new ClientKeepAlivePinger(this), scheduler, keepAliveTimeNanos, keepAliveTimeoutNanos, keepAliveWithoutCalls); keepAliveManager.onTransportStarted(); } frameWriter = new AsyncFrameWriter(this, serializingExecutor); outboundFlow = new OutboundFlowController(this, frameWriter, initialWindowSize); serializingExecutor.execute(new Runnable() { @Override public void run() { if (isForTest()) { if (connectingCallback != null) { connectingCallback.run(); } clientFrameHandler = new ClientFrameHandler(testFrameReader); executor.execute(clientFrameHandler); synchronized (lock) { maxConcurrentStreams = Integer.MAX_VALUE; startPendingStreams(); } frameWriter.becomeConnected(testFrameWriter, socket); connectedFuture.set(null); return; } BufferedSource source = Okio.buffer(new Source() { @Override public long read(Buffer sink, long byteCount) { return -1; } @Override public Timeout timeout() { return Timeout.NONE; } @Override public void close() {} }); Variant variant = new Http2(); BufferedSink sink; Socket sock; SSLSession sslSession = null; try { if (proxy == null) { sock = new Socket(address.getAddress(), address.getPort()); } else { sock = createHttpProxySocket( address, proxy.proxyAddress, proxy.username, proxy.password); } if (sslSocketFactory != null) { SSLSocket sslSocket = OkHttpTlsUpgrader.upgrade( sslSocketFactory, hostnameVerifier, sock, getOverridenHost(), getOverridenPort(), connectionSpec); sslSession = sslSocket.getSession(); sock = sslSocket; } sock.setTcpNoDelay(true); source = Okio.buffer(Okio.source(sock)); sink = Okio.buffer(Okio.sink(sock)); attributes = Attributes .newBuilder() .set(Grpc.TRANSPORT_ATTR_REMOTE_ADDR, sock.getRemoteSocketAddress()) .set(Grpc.TRANSPORT_ATTR_LOCAL_ADDR, sock.getLocalSocketAddress()) .set(Grpc.TRANSPORT_ATTR_SSL_SESSION, sslSession) .set(GrpcAttributes.ATTR_SECURITY_LEVEL, sslSession == null ? SecurityLevel.NONE : SecurityLevel.PRIVACY_AND_INTEGRITY) .build(); } catch (StatusException e) { startGoAway(0, ErrorCode.INTERNAL_ERROR, e.getStatus()); return; } catch (Exception e) { onException(e); return; } finally { clientFrameHandler = new ClientFrameHandler(variant.newReader(source, true)); executor.execute(clientFrameHandler); } FrameWriter rawFrameWriter; synchronized (lock) { socket = Preconditions.checkNotNull(sock, "socket"); maxConcurrentStreams = Integer.MAX_VALUE; startPendingStreams(); if (sslSession != null) { securityInfo = new InternalChannelz.Security(new InternalChannelz.Tls(sslSession)); } } rawFrameWriter = variant.newWriter(sink, true); frameWriter.becomeConnected(rawFrameWriter, socket); try { rawFrameWriter.connectionPreface(); Settings settings = new Settings(); rawFrameWriter.settings(settings); } catch (Exception e) { onException(e); return; } } }); return null; } OkHttpClientTransport(InetSocketAddress address, String authority, @Nullable String userAgent,
      Executor executor, @Nullable SSLSocketFactory sslSocketFactory,
      @Nullable HostnameVerifier hostnameVerifier, ConnectionSpec connectionSpec,
      int maxMessageSize, int initialWindowSize, @Nullable ProxyParameters proxy,
      Runnable tooManyPingsRunnable, int maxInboundMetadataSize, TransportTracer transportTracer); @VisibleForTesting  OkHttpClientTransport(
      String userAgent,
      Executor executor,
      FrameReader frameReader,
      FrameWriter testFrameWriter,
      int nextStreamId,
      Socket socket,
      Supplier<Stopwatch> stopwatchFactory,
      @Nullable Runnable connectingCallback,
      SettableFuture<Void> connectedFuture,
      int maxMessageSize,
      int initialWindowSize,
      Runnable tooManyPingsRunnable,
      TransportTracer transportTracer); }
OkHttpClientTransport implements ConnectionClientTransport, TransportExceptionHandler { @Override public Runnable start(Listener listener) { this.listener = Preconditions.checkNotNull(listener, "listener"); if (enableKeepAlive) { scheduler = SharedResourceHolder.get(TIMER_SERVICE); keepAliveManager = new KeepAliveManager( new ClientKeepAlivePinger(this), scheduler, keepAliveTimeNanos, keepAliveTimeoutNanos, keepAliveWithoutCalls); keepAliveManager.onTransportStarted(); } frameWriter = new AsyncFrameWriter(this, serializingExecutor); outboundFlow = new OutboundFlowController(this, frameWriter, initialWindowSize); serializingExecutor.execute(new Runnable() { @Override public void run() { if (isForTest()) { if (connectingCallback != null) { connectingCallback.run(); } clientFrameHandler = new ClientFrameHandler(testFrameReader); executor.execute(clientFrameHandler); synchronized (lock) { maxConcurrentStreams = Integer.MAX_VALUE; startPendingStreams(); } frameWriter.becomeConnected(testFrameWriter, socket); connectedFuture.set(null); return; } BufferedSource source = Okio.buffer(new Source() { @Override public long read(Buffer sink, long byteCount) { return -1; } @Override public Timeout timeout() { return Timeout.NONE; } @Override public void close() {} }); Variant variant = new Http2(); BufferedSink sink; Socket sock; SSLSession sslSession = null; try { if (proxy == null) { sock = new Socket(address.getAddress(), address.getPort()); } else { sock = createHttpProxySocket( address, proxy.proxyAddress, proxy.username, proxy.password); } if (sslSocketFactory != null) { SSLSocket sslSocket = OkHttpTlsUpgrader.upgrade( sslSocketFactory, hostnameVerifier, sock, getOverridenHost(), getOverridenPort(), connectionSpec); sslSession = sslSocket.getSession(); sock = sslSocket; } sock.setTcpNoDelay(true); source = Okio.buffer(Okio.source(sock)); sink = Okio.buffer(Okio.sink(sock)); attributes = Attributes .newBuilder() .set(Grpc.TRANSPORT_ATTR_REMOTE_ADDR, sock.getRemoteSocketAddress()) .set(Grpc.TRANSPORT_ATTR_LOCAL_ADDR, sock.getLocalSocketAddress()) .set(Grpc.TRANSPORT_ATTR_SSL_SESSION, sslSession) .set(GrpcAttributes.ATTR_SECURITY_LEVEL, sslSession == null ? SecurityLevel.NONE : SecurityLevel.PRIVACY_AND_INTEGRITY) .build(); } catch (StatusException e) { startGoAway(0, ErrorCode.INTERNAL_ERROR, e.getStatus()); return; } catch (Exception e) { onException(e); return; } finally { clientFrameHandler = new ClientFrameHandler(variant.newReader(source, true)); executor.execute(clientFrameHandler); } FrameWriter rawFrameWriter; synchronized (lock) { socket = Preconditions.checkNotNull(sock, "socket"); maxConcurrentStreams = Integer.MAX_VALUE; startPendingStreams(); if (sslSession != null) { securityInfo = new InternalChannelz.Security(new InternalChannelz.Tls(sslSession)); } } rawFrameWriter = variant.newWriter(sink, true); frameWriter.becomeConnected(rawFrameWriter, socket); try { rawFrameWriter.connectionPreface(); Settings settings = new Settings(); rawFrameWriter.settings(settings); } catch (Exception e) { onException(e); return; } } }); return null; } OkHttpClientTransport(InetSocketAddress address, String authority, @Nullable String userAgent,
      Executor executor, @Nullable SSLSocketFactory sslSocketFactory,
      @Nullable HostnameVerifier hostnameVerifier, ConnectionSpec connectionSpec,
      int maxMessageSize, int initialWindowSize, @Nullable ProxyParameters proxy,
      Runnable tooManyPingsRunnable, int maxInboundMetadataSize, TransportTracer transportTracer); @VisibleForTesting  OkHttpClientTransport(
      String userAgent,
      Executor executor,
      FrameReader frameReader,
      FrameWriter testFrameWriter,
      int nextStreamId,
      Socket socket,
      Supplier<Stopwatch> stopwatchFactory,
      @Nullable Runnable connectingCallback,
      SettableFuture<Void> connectedFuture,
      int maxMessageSize,
      int initialWindowSize,
      Runnable tooManyPingsRunnable,
      TransportTracer transportTracer); @Override void ping(final PingCallback callback, Executor executor); @Override OkHttpClientStream newStream(final MethodDescriptor<?, ?> method,
      final Metadata headers, CallOptions callOptions); @Override Runnable start(Listener listener); @Override String toString(); @Override InternalLogId getLogId(); @Override void shutdown(Status reason); @Override void shutdownNow(Status reason); @Override Attributes getAttributes(); @Override void onException(Throwable failureCause); @Override ListenableFuture<SocketStats> getStats(); @Override SocketAddress getAddress(); }
OkHttpClientTransport implements ConnectionClientTransport, TransportExceptionHandler { @Override public Runnable start(Listener listener) { this.listener = Preconditions.checkNotNull(listener, "listener"); if (enableKeepAlive) { scheduler = SharedResourceHolder.get(TIMER_SERVICE); keepAliveManager = new KeepAliveManager( new ClientKeepAlivePinger(this), scheduler, keepAliveTimeNanos, keepAliveTimeoutNanos, keepAliveWithoutCalls); keepAliveManager.onTransportStarted(); } frameWriter = new AsyncFrameWriter(this, serializingExecutor); outboundFlow = new OutboundFlowController(this, frameWriter, initialWindowSize); serializingExecutor.execute(new Runnable() { @Override public void run() { if (isForTest()) { if (connectingCallback != null) { connectingCallback.run(); } clientFrameHandler = new ClientFrameHandler(testFrameReader); executor.execute(clientFrameHandler); synchronized (lock) { maxConcurrentStreams = Integer.MAX_VALUE; startPendingStreams(); } frameWriter.becomeConnected(testFrameWriter, socket); connectedFuture.set(null); return; } BufferedSource source = Okio.buffer(new Source() { @Override public long read(Buffer sink, long byteCount) { return -1; } @Override public Timeout timeout() { return Timeout.NONE; } @Override public void close() {} }); Variant variant = new Http2(); BufferedSink sink; Socket sock; SSLSession sslSession = null; try { if (proxy == null) { sock = new Socket(address.getAddress(), address.getPort()); } else { sock = createHttpProxySocket( address, proxy.proxyAddress, proxy.username, proxy.password); } if (sslSocketFactory != null) { SSLSocket sslSocket = OkHttpTlsUpgrader.upgrade( sslSocketFactory, hostnameVerifier, sock, getOverridenHost(), getOverridenPort(), connectionSpec); sslSession = sslSocket.getSession(); sock = sslSocket; } sock.setTcpNoDelay(true); source = Okio.buffer(Okio.source(sock)); sink = Okio.buffer(Okio.sink(sock)); attributes = Attributes .newBuilder() .set(Grpc.TRANSPORT_ATTR_REMOTE_ADDR, sock.getRemoteSocketAddress()) .set(Grpc.TRANSPORT_ATTR_LOCAL_ADDR, sock.getLocalSocketAddress()) .set(Grpc.TRANSPORT_ATTR_SSL_SESSION, sslSession) .set(GrpcAttributes.ATTR_SECURITY_LEVEL, sslSession == null ? SecurityLevel.NONE : SecurityLevel.PRIVACY_AND_INTEGRITY) .build(); } catch (StatusException e) { startGoAway(0, ErrorCode.INTERNAL_ERROR, e.getStatus()); return; } catch (Exception e) { onException(e); return; } finally { clientFrameHandler = new ClientFrameHandler(variant.newReader(source, true)); executor.execute(clientFrameHandler); } FrameWriter rawFrameWriter; synchronized (lock) { socket = Preconditions.checkNotNull(sock, "socket"); maxConcurrentStreams = Integer.MAX_VALUE; startPendingStreams(); if (sslSession != null) { securityInfo = new InternalChannelz.Security(new InternalChannelz.Tls(sslSession)); } } rawFrameWriter = variant.newWriter(sink, true); frameWriter.becomeConnected(rawFrameWriter, socket); try { rawFrameWriter.connectionPreface(); Settings settings = new Settings(); rawFrameWriter.settings(settings); } catch (Exception e) { onException(e); return; } } }); return null; } OkHttpClientTransport(InetSocketAddress address, String authority, @Nullable String userAgent,
      Executor executor, @Nullable SSLSocketFactory sslSocketFactory,
      @Nullable HostnameVerifier hostnameVerifier, ConnectionSpec connectionSpec,
      int maxMessageSize, int initialWindowSize, @Nullable ProxyParameters proxy,
      Runnable tooManyPingsRunnable, int maxInboundMetadataSize, TransportTracer transportTracer); @VisibleForTesting  OkHttpClientTransport(
      String userAgent,
      Executor executor,
      FrameReader frameReader,
      FrameWriter testFrameWriter,
      int nextStreamId,
      Socket socket,
      Supplier<Stopwatch> stopwatchFactory,
      @Nullable Runnable connectingCallback,
      SettableFuture<Void> connectedFuture,
      int maxMessageSize,
      int initialWindowSize,
      Runnable tooManyPingsRunnable,
      TransportTracer transportTracer); @Override void ping(final PingCallback callback, Executor executor); @Override OkHttpClientStream newStream(final MethodDescriptor<?, ?> method,
      final Metadata headers, CallOptions callOptions); @Override Runnable start(Listener listener); @Override String toString(); @Override InternalLogId getLogId(); @Override void shutdown(Status reason); @Override void shutdownNow(Status reason); @Override Attributes getAttributes(); @Override void onException(Throwable failureCause); @Override ListenableFuture<SocketStats> getStats(); @Override SocketAddress getAddress();  }