All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.undefinedlabs.scope.deps.okhttp3.internal.http.CallServerInterceptor Maven / Gradle / Ivy

Go to download

Scope is a APM for tests to give engineering teams unprecedented visibility into their CI process to quickly identify, troubleshoot and fix failed builds. This artifact contains dependencies for Scope.

There is a newer version: 0.14.0-beta.2
Show newest version
package com.undefinedlabs.scope.deps.okhttp3.internal.http;

import com.undefinedlabs.scope.deps.okhttp3.Interceptor;
import com.undefinedlabs.scope.deps.okhttp3.Request;
import com.undefinedlabs.scope.deps.okhttp3.Response;
import com.undefinedlabs.scope.deps.okhttp3.internal.Util;
import com.undefinedlabs.scope.deps.okhttp3.internal.connection.RealConnection;
import com.undefinedlabs.scope.deps.okhttp3.internal.connection.StreamAllocation;
import com.undefinedlabs.scope.deps.okio.BufferedSink;
import com.undefinedlabs.scope.deps.okio.Okio;
import com.undefinedlabs.scope.deps.okio.Sink;

import java.io.IOException;
import java.net.ProtocolException;

public final class CallServerInterceptor implements Interceptor {
    private final boolean forWebSocket;

    public CallServerInterceptor(boolean forWebSocket) {
        this.forWebSocket = forWebSocket;
    }

    @Override public Response intercept(Chain chain) throws IOException {
        RealInterceptorChain realChain = (RealInterceptorChain) chain;
        HttpCodec httpCodec = realChain.httpStream();
        StreamAllocation streamAllocation = realChain.streamAllocation();
        RealConnection connection = (RealConnection) realChain.connection();
        Request request = realChain.request();

        long sentRequestMillis = System.currentTimeMillis();
        httpCodec.writeRequestHeaders(request);

        Response.Builder responseBuilder = null;
        if (HttpMethod.permitsRequestBody(request.method()) && request.body() != null) {
            // If there's a "Expect: 100-continue" header on the request, wait for a "HTTP/1.1 100
            // Continue" response before transmitting the request body. If we don't get that, return what
            // 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);
            }

            if (responseBuilder == null) {
                // Write the request body if the "Expect: 100-continue" expectation was met.
                Sink requestBodyOut = httpCodec.createRequestBody(request, request.body().contentLength());
                BufferedSink bufferedRequestBody = Okio.buffer(requestBodyOut);
                request.body().writeTo(bufferedRequestBody);
                bufferedRequestBody.close();
            } else if (!connection.isMultiplexed()) {
                // If the "Expect: 100-continue" expectation wasn't met, prevent the HTTP/1 connection from
                // being reused. Otherwise we're still obligated to transmit the request body to leave the
                // connection in a consistent state.
                streamAllocation.noNewStreams();
            }
        }

        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;
    }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy