protected HTTPSampleResult sample()

in src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/HTTPHC4Impl.java [604:768]


    protected HTTPSampleResult sample(URL url, String method,
            boolean areFollowingRedirect, int frameDepth) {

        if (log.isDebugEnabled()) {
            log.debug("Start : sample {} method {} followingRedirect {} depth {}",
                    url, method, areFollowingRedirect, frameDepth);
        }
        JMeterVariables jMeterVariables = JMeterContextService.getContext().getVariables();

        HTTPSampleResult res = createSampleResult(url, method);

        CloseableHttpClient httpClient = null;
        HttpRequestBase httpRequest = null;
        HttpContext localContext = new BasicHttpContext();
        HttpClientContext clientContext = HttpClientContext.adapt(localContext);
        clientContext.setAttribute(CONTEXT_ATTRIBUTE_AUTH_MANAGER, getAuthManager());
        HttpClientKey key = createHttpClientKey(url);
        MutableTriple<CloseableHttpClient, AuthState, PoolingHttpClientConnectionManager> triple;
        try {
            triple = setupClient(key, jMeterVariables, clientContext);
            httpClient = triple.getLeft();
            URI uri = url.toURI();
            httpRequest = createHttpRequest(uri, method, areFollowingRedirect);
            setupRequest(url, httpRequest, res); // can throw IOException
        } catch (Exception e) {
            res.sampleStart();
            res.sampleEnd();
            errorResult(e, res);
            return res;
        }

        setupClientContextBeforeSample(jMeterVariables, localContext);

        res.sampleStart();

        final CacheManager cacheManager = getCacheManager();
        if (cacheManager != null && HTTPConstants.GET.equalsIgnoreCase(method) && cacheManager.inCache(url, httpRequest.getAllHeaders())) {
            return updateSampleResultForResourceInCache(res);
        }
        CloseableHttpResponse httpResponse = null;
        try {
            currentRequest = httpRequest;
            handleMethod(method, res, httpRequest, localContext);
            // store the SampleResult in LocalContext to compute connect time
            localContext.setAttribute(CONTEXT_ATTRIBUTE_SAMPLER_RESULT, res);
            // perform the sample
            httpResponse =
                    executeRequest(httpClient, httpRequest, localContext, url);
            saveProxyAuth(triple, localContext);
            if (log.isDebugEnabled()) {
                log.debug("Headers in request before:{}", Arrays.asList(httpRequest.getAllHeaders()));
            }
            // Needs to be done after execute to pick up all the headers
            final HttpRequest request = (HttpRequest) localContext.getAttribute(HttpCoreContext.HTTP_REQUEST);
            if (log.isDebugEnabled()) {
                log.debug("Headers in request after:{}, in localContext#request:{}",
                        Arrays.asList(httpRequest.getAllHeaders()),
                        Arrays.asList(request.getAllHeaders()));
            }
            extractClientContextAfterSample(jMeterVariables, localContext);
            // We've finished with the request, so we can add the LocalAddress to it for display
            if (localAddress != null) {
                request.addHeader(HEADER_LOCAL_ADDRESS, localAddress.toString());
            }
            res.setRequestHeaders(getAllHeadersExceptCookie(request));

            Header contentType = httpResponse.getLastHeader(HTTPConstants.HEADER_CONTENT_TYPE);
            if (contentType != null){
                String ct = contentType.getValue();
                res.setContentType(ct);
                res.setEncodingAndType(ct);
            }
            HttpEntity entity = httpResponse.getEntity();
            if (entity != null) {
                res.setResponseData(readResponse(res, entity.getContent(), entity.getContentLength()));
            }

            res.sampleEnd(); // Done with the sampling proper.
            currentRequest = null;

            // Now collect the results into the HTTPSampleResult:
            StatusLine statusLine = httpResponse.getStatusLine();
            int statusCode = statusLine.getStatusCode();
            res.setResponseCode(Integer.toString(statusCode));
            res.setResponseMessage(statusLine.getReasonPhrase());
            res.setSuccessful(isSuccessCode(statusCode));
            res.setResponseHeaders(getResponseHeaders(httpResponse));
            if (res.isRedirect()) {
                final Header headerLocation = httpResponse.getLastHeader(HTTPConstants.HEADER_LOCATION);
                if (headerLocation == null) { // HTTP protocol violation, but avoids NPE
                    throw new IllegalArgumentException("Missing location header in redirect for " + httpRequest.getRequestLine());
                }
                String redirectLocation = headerLocation.getValue();
                res.setRedirectLocation(redirectLocation);
            }

            // record some sizes to allow HTTPSampleResult.getBytes() with different options
            long headerBytes =
                (long)res.getResponseHeaders().length()   // condensed length (without \r)
              + (long) httpResponse.getAllHeaders().length // Add \r for each header
              + 1L // Add \r for initial header
              + 2L; // final \r\n before data
            HttpConnectionMetrics metrics = (HttpConnectionMetrics) localContext.getAttribute(CONTEXT_ATTRIBUTE_METRICS);
            long totalBytes = metrics.getReceivedBytesCount();
            res.setHeadersSize((int)headerBytes);
            res.setBodySize(totalBytes - headerBytes);
            res.setSentBytes((Long) localContext.getAttribute(CONTEXT_ATTRIBUTE_SENT_BYTES));
            if (log.isDebugEnabled()) {
                long total = res.getHeadersSize() + res.getBodySizeAsLong();
                log.debug("ResponseHeadersSize={} Content-Length={} Total={}",
                        res.getHeadersSize(), res.getBodySizeAsLong(), total);
            }

            // If we redirected automatically, the URL may have changed
            if (getAutoRedirects()) {
                HttpUriRequest req = (HttpUriRequest) localContext.getAttribute(HttpCoreContext.HTTP_REQUEST);
                HttpHost target = (HttpHost) localContext.getAttribute(HttpCoreContext.HTTP_TARGET_HOST);
                URI redirectURI = req.getURI();
                if (redirectURI.isAbsolute()) {
                    res.setURL(redirectURI.toURL());
                } else {
                    res.setURL(new URL(new URL(target.toURI()),redirectURI.toString()));
                }
            }

            // Store any cookies received in the cookie manager:
            saveConnectionCookies(httpResponse, res.getURL(), getCookieManager());

            // Save cache information
            if (cacheManager != null){
                cacheManager.saveDetails(httpResponse, res);
            }

            // Follow redirects and download page resources if appropriate:
            res = resultProcessing(areFollowingRedirect, frameDepth, res);
            if(!isSuccessCode(statusCode)) {
                EntityUtils.consumeQuietly(httpResponse.getEntity());
            }

        } catch (IOException e) {
            log.debug("IOException", e);
            if (res.getEndTime() == 0) {
                res.sampleEnd();
            }
           // pick up headers if failed to execute the request
            if (res.getRequestHeaders() != null) {
                log.debug("Overwriting request old headers: {}", res.getRequestHeaders());
            }
            res.setRequestHeaders(getAllHeadersExceptCookie((HttpRequest) localContext.getAttribute(HttpCoreContext.HTTP_REQUEST)));
            errorResult(e, res);
            return res;
        } catch (RuntimeException e) {
            log.debug("RuntimeException", e);
            if (res.getEndTime() == 0) {
                res.sampleEnd();
            }
            errorResult(e, res);
            return res;
        } finally {
            JOrphanUtils.closeQuietly(httpResponse);
            currentRequest = null;
            JMeterContextService.getContext().getSamplerContext().remove(CONTEXT_ATTRIBUTE_PARENT_SAMPLE_CLIENT_STATE);
        }
        return res;
    }