Search in sources :

Example 1 with StreamAllocation

use of okhttp3.internal.connection.StreamAllocation in project okhttp by square.

the class ConnectionPoolTest method inUseConnectionsNotEvicted.

@Test
public void inUseConnectionsNotEvicted() throws Exception {
    ConnectionPool pool = new ConnectionPool(Integer.MAX_VALUE, 100L, TimeUnit.NANOSECONDS);
    // Prevent the cleanup runnable from being started.
    pool.cleanupRunning = true;
    RealConnection c1 = newConnection(pool, routeA1, 50L);
    synchronized (pool) {
        StreamAllocation streamAllocation = new StreamAllocation(pool, addressA, null);
        streamAllocation.acquire(c1);
    }
    // Running at time 50, the pool returns that nothing can be evicted until time 150.
    assertEquals(100L, pool.cleanup(50L));
    assertEquals(1, pool.connectionCount());
    assertFalse(c1.socket().isClosed());
    // Running at time 60, the pool returns that nothing can be evicted until time 160.
    assertEquals(100L, pool.cleanup(60L));
    assertEquals(1, pool.connectionCount());
    assertFalse(c1.socket().isClosed());
    // Running at time 160, the pool returns that nothing can be evicted until time 260.
    assertEquals(100L, pool.cleanup(160L));
    assertEquals(1, pool.connectionCount());
    assertFalse(c1.socket().isClosed());
}
Also used : StreamAllocation(okhttp3.internal.connection.StreamAllocation) RealConnection(okhttp3.internal.connection.RealConnection) Test(org.junit.Test)

Example 2 with StreamAllocation

use of okhttp3.internal.connection.StreamAllocation in project okhttp by square.

the class CallServerInterceptor method intercept.

@Override
public Response intercept(Chain chain) throws IOException {
    HttpCodec httpCodec = ((RealInterceptorChain) chain).httpStream();
    StreamAllocation streamAllocation = ((RealInterceptorChain) chain).streamAllocation();
    Request request = chain.request();
    long sentRequestMillis = System.currentTimeMillis();
    httpCodec.writeRequestHeaders(request);
    Response.Builder responseBuilder = null;
    if (HttpMethod.permitsRequestBody(request.method()) && request.body() != null) {
        // we did get (such as a 4xx response) without ever transmitting the request body.
        if ("100-continue".equalsIgnoreCase(request.header("Expect"))) {
            httpCodec.flushRequest();
            responseBuilder = httpCodec.readResponseHeaders(true);
        }
        // Write the request body, unless an "Expect: 100-continue" expectation failed.
        if (responseBuilder == null) {
            Sink requestBodyOut = httpCodec.createRequestBody(request, request.body().contentLength());
            BufferedSink bufferedRequestBody = Okio.buffer(requestBodyOut);
            request.body().writeTo(bufferedRequestBody);
            bufferedRequestBody.close();
        }
    }
    httpCodec.finishRequest();
    if (responseBuilder == null) {
        responseBuilder = httpCodec.readResponseHeaders(false);
    }
    Response response = responseBuilder.request(request).handshake(streamAllocation.connection().handshake()).sentRequestAtMillis(sentRequestMillis).receivedResponseAtMillis(System.currentTimeMillis()).build();
    int code = response.code();
    if (forWebSocket && code == 101) {
        // Connection is upgrading, but we need to ensure interceptors see a non-null response body.
        response = response.newBuilder().body(Util.EMPTY_RESPONSE).build();
    } else {
        response = response.newBuilder().body(httpCodec.openResponseBody(response)).build();
    }
    if ("close".equalsIgnoreCase(response.request().header("Connection")) || "close".equalsIgnoreCase(response.header("Connection"))) {
        streamAllocation.noNewStreams();
    }
    if ((code == 204 || code == 205) && response.body().contentLength() > 0) {
        throw new ProtocolException("HTTP " + code + " had non-zero Content-Length: " + response.body().contentLength());
    }
    return response;
}
Also used : StreamAllocation(okhttp3.internal.connection.StreamAllocation) Response(okhttp3.Response) ProtocolException(java.net.ProtocolException) BufferedSink(okio.BufferedSink) Sink(okio.Sink) Request(okhttp3.Request) BufferedSink(okio.BufferedSink)

Example 3 with StreamAllocation

use of okhttp3.internal.connection.StreamAllocation in project okhttp by square.

the class RetryAndFollowUpInterceptor method cancel.

/**
   * Immediately closes the socket connection if it's currently held. Use this to interrupt an
   * in-flight request from any thread. It's the caller's responsibility to close the request body
   * and response body streams; otherwise resources may be leaked.
   *
   * <p>This method is safe to be called concurrently, but provides limited guarantees. If a
   * transport layer connection has been established (such as a HTTP/2 stream) that is terminated.
   * Otherwise if a socket connection is being established, that is terminated.
   */
public void cancel() {
    canceled = true;
    StreamAllocation streamAllocation = this.streamAllocation;
    if (streamAllocation != null)
        streamAllocation.cancel();
}
Also used : StreamAllocation(okhttp3.internal.connection.StreamAllocation)

Example 4 with StreamAllocation

use of okhttp3.internal.connection.StreamAllocation in project okhttp by square.

the class RetryAndFollowUpInterceptor method intercept.

@Override
public Response intercept(Chain chain) throws IOException {
    Request request = chain.request();
    streamAllocation = new StreamAllocation(client.connectionPool(), createAddress(request.url()), callStackTrace);
    int followUpCount = 0;
    Response priorResponse = null;
    while (true) {
        if (canceled) {
            streamAllocation.release();
            throw new IOException("Canceled");
        }
        Response response = null;
        boolean releaseConnection = true;
        try {
            response = ((RealInterceptorChain) chain).proceed(request, streamAllocation, null, null);
            releaseConnection = false;
        } catch (RouteException e) {
            // The attempt to connect via a route failed. The request will not have been sent.
            if (!recover(e.getLastConnectException(), false, request)) {
                throw e.getLastConnectException();
            }
            releaseConnection = false;
            continue;
        } catch (IOException e) {
            // An attempt to communicate with a server failed. The request may have been sent.
            boolean requestSendStarted = !(e instanceof ConnectionShutdownException);
            if (!recover(e, requestSendStarted, request))
                throw e;
            releaseConnection = false;
            continue;
        } finally {
            // We're throwing an unchecked exception. Release any resources.
            if (releaseConnection) {
                streamAllocation.streamFailed(null);
                streamAllocation.release();
            }
        }
        // Attach the prior response if it exists. Such responses never have a body.
        if (priorResponse != null) {
            response = response.newBuilder().priorResponse(priorResponse.newBuilder().body(null).build()).build();
        }
        Request followUp = followUpRequest(response);
        if (followUp == null) {
            if (!forWebSocket) {
                streamAllocation.release();
            }
            return response;
        }
        closeQuietly(response.body());
        if (++followUpCount > MAX_FOLLOW_UPS) {
            streamAllocation.release();
            throw new ProtocolException("Too many follow-up requests: " + followUpCount);
        }
        if (followUp.body() instanceof UnrepeatableRequestBody) {
            streamAllocation.release();
            throw new HttpRetryException("Cannot retry streamed HTTP body", response.code());
        }
        if (!sameConnection(response, followUp.url())) {
            streamAllocation.release();
            streamAllocation = new StreamAllocation(client.connectionPool(), createAddress(followUp.url()), callStackTrace);
        } else if (streamAllocation.codec() != null) {
            throw new IllegalStateException("Closing the body of " + response + " didn't close its backing stream. Bad interceptor?");
        }
        request = followUp;
        priorResponse = response;
    }
}
Also used : StreamAllocation(okhttp3.internal.connection.StreamAllocation) Response(okhttp3.Response) RouteException(okhttp3.internal.connection.RouteException) ProtocolException(java.net.ProtocolException) ConnectionShutdownException(okhttp3.internal.http2.ConnectionShutdownException) Request(okhttp3.Request) InterruptedIOException(java.io.InterruptedIOException) IOException(java.io.IOException) HttpRetryException(java.net.HttpRetryException)

Example 5 with StreamAllocation

use of okhttp3.internal.connection.StreamAllocation in project okhttp by square.

the class Http1Codec method readResponseHeaders.

@Override
public Response.Builder readResponseHeaders(boolean expectContinue) throws IOException {
    if (state != STATE_OPEN_REQUEST_BODY && state != STATE_READ_RESPONSE_HEADERS) {
        throw new IllegalStateException("state: " + state);
    }
    try {
        StatusLine statusLine = StatusLine.parse(source.readUtf8LineStrict());
        Response.Builder responseBuilder = new Response.Builder().protocol(statusLine.protocol).code(statusLine.code).message(statusLine.message).headers(readHeaders());
        if (expectContinue && statusLine.code == HTTP_CONTINUE) {
            return null;
        }
        state = STATE_OPEN_RESPONSE_BODY;
        return responseBuilder;
    } catch (EOFException e) {
        // Provide more context if the server ends the stream before sending a response.
        IOException exception = new IOException("unexpected end of stream on " + streamAllocation);
        exception.initCause(e);
        throw exception;
    }
}
Also used : StatusLine(okhttp3.internal.http.StatusLine) Response(okhttp3.Response) EOFException(java.io.EOFException) IOException(java.io.IOException)

Aggregations

StreamAllocation (okhttp3.internal.connection.StreamAllocation)6 Response (okhttp3.Response)5 Request (okhttp3.Request)4 IOException (java.io.IOException)3 ProtocolException (java.net.ProtocolException)3 EOFException (java.io.EOFException)1 InterruptedIOException (java.io.InterruptedIOException)1 HttpRetryException (java.net.HttpRetryException)1 Call (okhttp3.Call)1 Callback (okhttp3.Callback)1 Interceptor (okhttp3.Interceptor)1 RealConnection (okhttp3.internal.connection.RealConnection)1 RouteException (okhttp3.internal.connection.RouteException)1 HttpCodec (okhttp3.internal.http.HttpCodec)1 RealInterceptorChain (okhttp3.internal.http.RealInterceptorChain)1 StatusLine (okhttp3.internal.http.StatusLine)1 ConnectionShutdownException (okhttp3.internal.http2.ConnectionShutdownException)1 BufferedSink (okio.BufferedSink)1 ByteString (okio.ByteString)1 Sink (okio.Sink)1