protected HTTPSampleResult sample()

in src/protocol/http/src/main/java/org/apache/jmeter/protocol/http/sampler/HTTPJavaImpl.java [502:668]


    protected HTTPSampleResult sample(URL url, String method, boolean areFollowingRedirect, int frameDepth) {
        HttpURLConnection conn = null;

        String urlStr = url.toString();
        if (log.isDebugEnabled()) {
            log.debug("Start : sample {}, method {}, followingRedirect {}, depth {}",
                    urlStr, method, areFollowingRedirect, frameDepth);
        }

        HTTPSampleResult res = new HTTPSampleResult();
        configureSampleLabel(res, url);
        res.setURL(url);
        res.setHTTPMethod(method);

        res.sampleStart(); // Count the retries as well in the time

        // Check cache for an entry with an Expires header in the future
        final CacheManager cacheManager = getCacheManager();
        if (cacheManager != null && HTTPConstants.GET.equalsIgnoreCase(method)) {
           if (cacheManager.inCache(url, getHeaders(getHeaderManager()))) {
               return updateSampleResultForResourceInCache(res);
           }
        }

        try {
            // Sampling proper - establish the connection and read the response:
            // Repeatedly try to connect:
            int retry = -1;
            // Start with -1 so tries at least once, and retries at most MAX_CONN_RETRIES times
            for (; retry < MAX_CONN_RETRIES; retry++) {
                try {
                    conn = setupConnection(url, method, res);
                    // Attempt the connection:
                    savedConn = conn;
                    conn.connect();
                    break;
                } catch (BindException e) {
                    if (retry >= MAX_CONN_RETRIES) {
                        log.error("Can't connect after {} retries, message: {}", retry, e.toString());
                        throw e;
                    }
                    log.debug("Bind exception, try again");
                    if (conn!=null) {
                        savedConn = null; // we don't want interrupt to try disconnection again
                        conn.disconnect();
                    }
                    setUseKeepAlive(false);
                } catch (IOException e) {
                    log.debug("Connection failed, giving up");
                    throw e;
                }
            }
            if (retry > MAX_CONN_RETRIES) {
                // This should never happen, but...
                throw new BindException();
            }
            // Nice, we've got a connection. Finish sending the request:
            if (method.equals(HTTPConstants.POST)) {
                String postBody = sendPostData(conn);
                res.setQueryString(postBody);
            } else if (method.equals(HTTPConstants.PUT)) {
                String putBody = sendPutData(conn);
                res.setQueryString(putBody);
            }
            // Request sent. Now get the response:
            byte[] responseData = readResponse(conn, res);

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

            // Now collect the results into the HTTPSampleResult:

            res.setResponseData(responseData);

            int errorLevel = conn.getResponseCode();
            String respMsg = conn.getResponseMessage();
            String hdr=conn.getHeaderField(0);
            if (hdr == null) {
                hdr="(null)";  // $NON-NLS-1$
            }
            if (errorLevel == -1){// Bug 38902 - sometimes -1 seems to be returned unnecessarily
                if (respMsg != null) {// Bug 41902 - NPE
                    try {
                        errorLevel = Integer.parseInt(respMsg.substring(0, 3));
                        log.warn("ResponseCode==-1; parsed {} as {}", respMsg, errorLevel);
                      } catch (NumberFormatException e) {
                        log.warn("ResponseCode==-1; could not parse {} hdr: {}", respMsg, hdr);
                      }
                } else {
                    respMsg=hdr; // for result
                    log.warn("ResponseCode==-1 & null ResponseMessage. Header(0)= {} ", hdr);
                }
            }
            if (errorLevel == -1) {
                res.setResponseCode("(null)"); // $NON-NLS-1$
            } else {
                res.setResponseCode(Integer.toString(errorLevel));
            }
            res.setSuccessful(isSuccessCode(errorLevel));

            if (respMsg == null) {// has been seen in a redirect
                respMsg=hdr; // use header (if possible) if no message found
            }
            res.setResponseMessage(respMsg);

            String ct = conn.getContentType();
            if (ct != null){
                res.setContentType(ct);// e.g. text/html; charset=ISO-8859-1
                res.setEncodingAndType(ct);
            }

            String responseHeaders = getResponseHeaders(conn);
            res.setResponseHeaders(responseHeaders);
            if (res.isRedirect()) {
                res.setRedirectLocation(conn.getHeaderField(HTTPConstants.HEADER_LOCATION));
            }

            // record headers size to allow HTTPSampleResult.getBytes() with different options
            // It used to be responseHeaders.replaceAll("\n", "\r\n").length(),
            // however we don't need the resulting string, just the length
            // So we add the number of \n in the string to account for \n
            res.setHeadersSize(
                    responseHeaders.length()
                            + StringUtilities.count(responseHeaders, '\n')
                            + 2); // add 2 for a '\r\n' at end of headers (before data)
            if (log.isDebugEnabled()) {
                log.debug("Response headersSize={}, bodySize={}, Total={}",
                        res.getHeadersSize(),  res.getBodySizeAsLong(),
                        res.getHeadersSize() + res.getBodySizeAsLong());
            }

            // If we redirected automatically, the URL may have changed
            if (getAutoRedirects()){
                res.setURL(conn.getURL());
            }

            // Store any cookies received in the cookie manager:
            saveConnectionCookies(conn, url, getCookieManager());

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

            res = resultProcessing(areFollowingRedirect, frameDepth, res);

            log.debug("End : sample");
            return res;
        } catch (IOException e) {
            if (res.getEndTime() == 0) {
                res.sampleEnd();
            }
            savedConn = null; // we don't want interrupt to try disconnection again
            // We don't want to continue using this connection, even if KeepAlive is set
            if (conn != null) { // May not exist
                conn.disconnect();
            }
            conn=null; // Don't process again
            return errorResult(e, res);
        } finally {
            // calling disconnect doesn't close the connection immediately,
            // but indicates we're through with it. The JVM should close
            // it when necessary.
            savedConn = null; // we don't want interrupt to try disconnection again
            disconnect(conn); // Disconnect unless using KeepAlive
        }
    }