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)) {
return updateSampleResultForResourceInCache(res);
}
}
try {
// Sampling proper - establish the connection and read the response:
// Repeatedly try to connect:
int retry;
// Start with 0 so tries at least once, and retries at most MAX_CONN_RETRIES times
for (retry = 0; 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 "+retry+" retries, "+e);
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);
continue; // try again
} 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);
@SuppressWarnings("null") // Cannot be null here
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 "+respMsg+ " as "+errorLevel);
} catch (NumberFormatException e) {
log.warn("ResponseCode==-1; could not parse "+respMsg+" hdr: "+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
res.setHeadersSize(responseHeaders.replaceAll("\n", "\r\n") // $NON-NLS-1$ $NON-NLS-2$
.length() + 2); // add 2 for a '\r\n' at end of headers (before data)
if (log.isDebugEnabled()) {
log.debug("Response headersSize=" + res.getHeadersSize() + " bodySize=" + res.getBodySize()
+ " Total=" + (res.getHeadersSize() + res.getBodySize()));
}
// 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");