Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions src/core/org/apache/jmeter/testelement/AbstractTestElement.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,15 @@ public JMeterProperty getProperty(String key) {
}
return prop;
}

/**
* Null property are wrapped in a {@link NullProperty}
* for internal use only
* @since 3.1
*/
private JMeterProperty getRawProperty(String key) {
return propMap.get(key);
}

@Override
public void traverse(TestElementTraverser traverser) {
Expand Down Expand Up @@ -230,8 +239,8 @@ public int getPropertyAsInt(String key) {

@Override
public int getPropertyAsInt(String key, int defaultValue) {
JMeterProperty jmp = getProperty(key);
return jmp instanceof NullProperty ? defaultValue : jmp.getIntValue();
JMeterProperty jmp = getRawProperty(key);
return jmp == null || jmp instanceof NullProperty ? defaultValue : jmp.getIntValue();
}

@Override
Expand All @@ -241,8 +250,8 @@ public boolean getPropertyAsBoolean(String key) {

@Override
public boolean getPropertyAsBoolean(String key, boolean defaultVal) {
JMeterProperty jmp = getProperty(key);
return jmp instanceof NullProperty ? defaultVal : jmp.getBooleanValue();
JMeterProperty jmp = getRawProperty(key);
return jmp == null || jmp instanceof NullProperty ? defaultVal : jmp.getBooleanValue();
}

@Override
Expand All @@ -257,8 +266,8 @@ public long getPropertyAsLong(String key) {

@Override
public long getPropertyAsLong(String key, long defaultValue) {
JMeterProperty jmp = getProperty(key);
return jmp instanceof NullProperty ? defaultValue : jmp.getLongValue();
JMeterProperty jmp = getRawProperty(key);
return jmp == null || jmp instanceof NullProperty ? defaultValue : jmp.getLongValue();
}

@Override
Expand All @@ -273,8 +282,8 @@ public String getPropertyAsString(String key) {

@Override
public String getPropertyAsString(String key, String defaultValue) {
JMeterProperty jmp = getProperty(key);
return jmp instanceof NullProperty ? defaultValue : jmp.getStringValue();
JMeterProperty jmp = getRawProperty(key);
return jmp == null || jmp instanceof NullProperty ? defaultValue : jmp.getStringValue();
}

/**
Expand Down
14 changes: 9 additions & 5 deletions src/core/org/apache/jmeter/threads/JMeterThread.java
Original file line number Diff line number Diff line change
Expand Up @@ -457,16 +457,20 @@ private void executeSamplePackage(Sampler current,

// Perform the actual sample
currentSampler = sampler;
for(SampleMonitor monitor : sampleMonitors) {
monitor.sampleStarting(sampler);
if(!sampleMonitors.isEmpty()) {
for(SampleMonitor monitor : sampleMonitors) {
monitor.sampleStarting(sampler);
}
}
SampleResult result = null;
try {
result = sampler.sample(null); // TODO: remove this useless Entry parameter
} finally {
for(SampleMonitor monitor : sampleMonitors) {
monitor.sampleEnded(sampler);
}
if(sampleMonitors.isEmpty()) {
for(SampleMonitor monitor : sampleMonitors) {
monitor.sampleEnded(sampler);
}
}
}
currentSampler = null;

Expand Down
19 changes: 13 additions & 6 deletions src/jorphan/org/apache/jorphan/util/JOrphanUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -262,15 +262,22 @@ public static String replaceFirst(String source, String search, String replace)
* @return the output string
*/
public static String replaceAllChars(String source, char search, String replace) {
int indexOf = source.indexOf(search);
if(indexOf == -1) {
return source;
}

int offset = 0;
char[] chars = source.toCharArray();
StringBuilder sb = new StringBuilder(source.length()+20);
for(char c : chars){
if (c == search){
sb.append(replace);
} else {
sb.append(c);
}
while(indexOf != -1) {
sb.append(chars, offset, indexOf-offset);
sb.append(replace);
offset = indexOf +1;
indexOf = source.indexOf(search, offset);
}
sb.append(chars, offset, chars.length- offset);

return sb.toString();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.conn.SystemDefaultDnsResolver;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.message.BufferedHeader;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.CoreProtocolPNames;
Expand All @@ -106,6 +107,7 @@
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpCoreContext;
import org.apache.http.util.CharArrayBuffer;
import org.apache.jmeter.protocol.http.control.AuthManager;
import org.apache.jmeter.protocol.http.control.CacheManager;
import org.apache.jmeter.protocol.http.control.CookieManager;
Expand Down Expand Up @@ -747,7 +749,8 @@ private HttpClient setupClient(URL url, SampleResult res) {
HttpClientKey key = new HttpClientKey(url, useProxy, proxyHost, proxyPort, proxyUser, proxyPass);

HttpClient httpClient = null;
if(this.testElement.isConcurrentDwn()) {
boolean concurrentDwn = this.testElement.isConcurrentDwn();
if(concurrentDwn) {
httpClient = (HttpClient) JMeterContextService.getContext().getSamplerContext().get(HTTPCLIENT_TOKEN);
}

Expand Down Expand Up @@ -782,7 +785,7 @@ private HttpClient setupClient(URL url, SampleResult res) {
// Modern browsers use more connections per host than the current httpclient default (2)
// when using parallel download the httpclient and connection manager are shared by the downloads threads
// to be realistic JMeter must set an higher value to DefaultMaxPerRoute
if(this.testElement.isConcurrentDwn()) {
if(concurrentDwn) {
try {
int maxConcurrentDownloads = Integer.parseInt(this.testElement.getConcurrentPool());
connManager.setDefaultMaxPerRoute(Math.max(maxConcurrentDownloads, connManager.getDefaultMaxPerRoute()));
Expand Down Expand Up @@ -841,7 +844,7 @@ protected HttpRequestRetryHandler createHttpRequestRetryHandler() {
}
}

if(this.testElement.isConcurrentDwn()) {
if(concurrentDwn) {
JMeterContextService.getContext().getSamplerContext().put(HTTPCLIENT_TOKEN, httpClient);
}

Expand Down Expand Up @@ -951,11 +954,12 @@ protected void setDefaultRequestHeaders(HttpRequest request) {
* @return string containing the headers, one per line
*/
private String getResponseHeaders(HttpResponse response, HttpContext localContext) {
StringBuilder headerBuf = new StringBuilder();
Header[] rh = response.getAllHeaders();

StringBuilder headerBuf = new StringBuilder(40 * (rh.length+1));
headerBuf.append(response.getStatusLine());// header[0] is not the status line...
headerBuf.append("\n"); // $NON-NLS-1$

Header[] rh = response.getAllHeaders();
for (Header responseHeader : rh) {
writeResponseHeader(headerBuf, responseHeader);
}
Expand All @@ -967,12 +971,17 @@ private String getResponseHeaders(HttpResponse response, HttpContext localContex
* @param headerBuffer {@link StringBuilder}
* @param responseHeader {@link Header}
*/
private void writeResponseHeader(StringBuilder headerBuffer,
Header responseHeader) {
headerBuffer.append(responseHeader.getName())
private void writeResponseHeader(StringBuilder headerBuffer, Header responseHeader) {
if(responseHeader instanceof BufferedHeader) {
CharArrayBuffer buffer = ((BufferedHeader)responseHeader).getBuffer();
headerBuffer.append(buffer.buffer(), 0, buffer.length()).append("\n"); // $NON-NLS-1$;
}
else {
headerBuffer.append(responseHeader.getName())
.append(": ") // $NON-NLS-1$
.append(responseHeader.getValue())
.append("\n"); // $NON-NLS-1$
}
}

/**
Expand Down Expand Up @@ -1075,7 +1084,7 @@ private int getPortFromHostHeader(String hostHeaderValue, int defaultValue) {
private String getConnectionHeaders(HttpRequest method) {
if(method != null) {
// Get all the request headers
StringBuilder hdrs = new StringBuilder(100);
StringBuilder hdrs = new StringBuilder(150);
Header[] requestHeaders = method.getAllHeaders();
for (Header requestHeader : requestHeaders) {
// Exclude the COOKIE header, since cookie is reported separately in the sample
Expand Down Expand Up @@ -1218,7 +1227,7 @@ protected String sendPostData(HttpPost post) throws IOException {
}
bos.flush();
// We get the posted bytes using the encoding used to create it
postedBody.append(new String(bos.toByteArray(),
postedBody.append(bos.toString(
contentEncoding == null ? "US-ASCII" // $NON-NLS-1$ this is the default used by HttpClient
: contentEncoding));
bos.close();
Expand Down Expand Up @@ -1341,11 +1350,8 @@ protected String sendPostData(HttpPost post) throws IOException {
post.getEntity().writeTo(bos);
bos.flush();
// We get the posted bytes using the encoding used to create it
if (contentEncoding != null) {
postedBody.append(new String(bos.toByteArray(), contentEncoding));
} else {
postedBody.append(new String(bos.toByteArray(), SampleResult.DEFAULT_HTTP_ENCODING));
}
postedBody.append(bos.toString(contentEncoding != null?contentEncoding:SampleResult.DEFAULT_HTTP_ENCODING));

bos.close();
} else {
postedBody.append("<RequestEntity was not repeatable, cannot view what was sent>");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
Expand Down Expand Up @@ -56,6 +57,7 @@
import org.apache.jmeter.protocol.http.parser.LinkExtractorParser;
import org.apache.jmeter.protocol.http.sampler.ResourcesDownloader.AsynSamplerResultHolder;
import org.apache.jmeter.protocol.http.util.ConversionUtils;
import org.apache.jmeter.protocol.http.util.DirectAccessByteArrayOutputStream;
import org.apache.jmeter.protocol.http.util.EncoderCache;
import org.apache.jmeter.protocol.http.util.HTTPArgument;
import org.apache.jmeter.protocol.http.util.HTTPConstants;
Expand Down Expand Up @@ -682,9 +684,13 @@ public static int getDefaultPort(String protocol, int port) {
* @return port number or UNSPECIFIED_PORT (== 0)
*/
public int getPortIfSpecified() {
String port_s = getPropertyAsString(PORT, UNSPECIFIED_PORT_AS_STRING);
String portAsString = getPropertyAsString(PORT);
if(portAsString == null || portAsString.isEmpty()) {
return UNSPECIFIED_PORT;
}

try {
return Integer.parseInt(port_s.trim());
return Integer.parseInt(portAsString.trim());
} catch (NumberFormatException e) {
return UNSPECIFIED_PORT;
}
Expand Down Expand Up @@ -992,13 +998,20 @@ public String getQueryString() {
* @return the QueryString value
*/
public String getQueryString(String contentEncoding) {

CollectionProperty arguments = getArguments().getArguments();
if(arguments.size() == 0) {
return "";
}

// Check if the sampler has a specified content encoding
if (JOrphanUtils.isBlank(contentEncoding)) {
// We use the encoding which should be used according to the HTTP spec, which is UTF-8
contentEncoding = EncoderCache.URL_ARGUMENT_ENCODING;
}
StringBuilder buf = new StringBuilder();
PropertyIterator iter = getArguments().iterator();

StringBuilder buf = new StringBuilder(arguments.size() * 15);
PropertyIterator iter = arguments.iterator();
boolean first = true;
while (iter.hasNext()) {
HTTPArgument item = null;
Expand Down Expand Up @@ -1598,15 +1611,18 @@ private String computeMethodForRedirect(String initialMethod, String responseCod
protected HTTPSampleResult resultProcessing(boolean areFollowingRedirect, int frameDepth, HTTPSampleResult res) {
boolean wasRedirected = false;
if (!areFollowingRedirect && res.isRedirect()) {
log.debug("Location set to - " + res.getRedirectLocation());
if(log.isDebugEnabled()) {
log.debug("Location set to - " + res.getRedirectLocation());
}

if (getFollowRedirects()) {
res = followRedirects(res, frameDepth);
areFollowingRedirect = true;
wasRedirected = true;
}
}
if (isImageParser() && (SampleResult.TEXT).equals(res.getDataType()) && res.isSuccessful()) {

if (res.isSuccessful() && SampleResult.TEXT.equals(res.getDataType()) && isImageParser() ) {
if (frameDepth > MAX_FRAME_DEPTH) {
HTTPSampleResult errSubResult = new HTTPSampleResult(res);
errSubResult.removeSubResults();
Expand Down Expand Up @@ -1751,12 +1767,15 @@ public void testIterationStart(LoopIterationEvent event) {
* @throws IOException if reading the result fails
*/
public byte[] readResponse(SampleResult sampleResult, InputStream in, int length) throws IOException {

OutputStream w = null;
try {
byte[] readBuffer = new byte[8192]; // 8kB is the (max) size to have the latency ('the first packet')
int bufferSize = 32;// Enough for MD5

MessageDigest md = null;
boolean asMD5 = useMD5();
boolean knownResponseLength = length > 0;// may also happen if long value > int.max
if (asMD5) {
try {
md = MessageDigest.getInstance("MD5"); //$NON-NLS-1$
Expand All @@ -1765,45 +1784,71 @@ public byte[] readResponse(SampleResult sampleResult, InputStream in, int length
asMD5 = false;
}
} else {
if (length <= 0) {// may also happen if long value > int.max
if (!knownResponseLength) {
bufferSize = 4 * 1024;
} else {
bufferSize = length;
}
}
ByteArrayOutputStream w = new ByteArrayOutputStream(bufferSize);


int bytesRead = 0;
int totalBytes = 0;
boolean first = true;
while ((bytesRead = in.read(readBuffer)) > -1) {
if (first) {
sampleResult.latencyEnd();
first = false;
if(!asMD5) {
if(knownResponseLength) {
w = new DirectAccessByteArrayOutputStream(bufferSize);
}
else {
w = new org.apache.commons.io.output.ByteArrayOutputStream(bufferSize);
}
}
}
if (asMD5 && md != null) {

if (asMD5) {
md.update(readBuffer, 0, bytesRead);
totalBytes += bytesRead;
} else {
w.write(readBuffer, 0, bytesRead);
}
}

if (first) { // Bug 46838 - if there was no data, still need to set latency
sampleResult.latencyEnd();
return new byte[0];
}
in.close();
w.flush();
if (asMD5 && md != null) {

if (asMD5) {
byte[] md5Result = md.digest();
w.write(JOrphanUtils.baToHexBytes(md5Result));
sampleResult.setBytes(totalBytes);
return JOrphanUtils.baToHexBytes(md5Result);
}
w.close();
return w.toByteArray();

return toByteArray(w);
} finally {
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(w);
}
}

private byte[] toByteArray(OutputStream w) {
if(w instanceof DirectAccessByteArrayOutputStream) {
return ((DirectAccessByteArrayOutputStream) w).toByteArray();
}

if(w instanceof org.apache.commons.io.output.ByteArrayOutputStream) {
return ((org.apache.commons.io.output.ByteArrayOutputStream) w).toByteArray();
}

log.warn("Unknown stream type " + w.getClass());

return null;
}

/**
* JMeter 2.3.1 and earlier only had fields for one file on the GUI:
* <ul>
Expand Down
Loading