Skip to content

Commit fce3a23

Browse files
authored
Merge pull request #30 from Blazemeter/FIX_BUFFER_SIZE_ISSUE
Fixing buffer size issue
2 parents 1ae0498 + 0ff7f70 commit fce3a23

File tree

4 files changed

+116
-43
lines changed

4 files changed

+116
-43
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,5 @@ Currently, we only give support to the Basic and Digest authentication mechanism
6262
To make use of Basic preemptive authentication results, make sure to create and set the property `httpJettyClient.auth.preemptive`
6363
to true in the jmeter.properties file.
6464

65+
## Buffer capacity
66+
By default, the size of the downloaded resources is set to 2 MB (2097152 bytes) but, the limit can be increased by adding the `httpJettyClient.maxBufferSize` property on the jmeter.properties file in bytes.

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<groupId>com.blazemeter.jmeter</groupId>
88
<artifactId>jmeter-bzm-http2</artifactId>
99
<packaging>jar</packaging>
10-
<version>2.0</version>
10+
<version>2.0.1</version>
1111
<name>HTTP/2 Sampler</name>
1212
<description>HTTP/2 protocol sampler</description>
1313

src/main/java/com/blazemeter/jmeter/http2/core/HTTP2JettyClient.java

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,6 @@
11
package com.blazemeter.jmeter.http2.core;
22

33
import com.blazemeter.jmeter.http2.sampler.HTTP2Sampler;
4-
import java.io.ByteArrayInputStream;
5-
import java.io.IOException;
6-
import java.io.InputStream;
7-
import java.io.UnsupportedEncodingException;
8-
import java.net.URI;
9-
import java.net.URISyntaxException;
10-
import java.net.URL;
11-
import java.net.URLDecoder;
12-
import java.nio.charset.Charset;
13-
import java.nio.charset.StandardCharsets;
14-
import java.nio.file.Path;
15-
import java.nio.file.Paths;
16-
import java.util.Arrays;
17-
import java.util.HashSet;
18-
import java.util.Set;
19-
import java.util.concurrent.TimeUnit;
20-
import java.util.regex.Pattern;
21-
import java.util.stream.StreamSupport;
224
import org.apache.commons.lang3.StringUtils;
235
import org.apache.jmeter.protocol.http.control.AuthManager;
246
import org.apache.jmeter.protocol.http.control.Authorization;
@@ -45,6 +27,7 @@
4527
import org.eclipse.jetty.client.util.BasicAuthentication;
4628
import org.eclipse.jetty.client.util.DigestAuthentication;
4729
import org.eclipse.jetty.client.util.FormRequestContent;
30+
import org.eclipse.jetty.client.util.FutureResponseListener;
4831
import org.eclipse.jetty.client.util.MultiPartRequestContent;
4932
import org.eclipse.jetty.client.util.PathRequestContent;
5033
import org.eclipse.jetty.client.util.StringRequestContent;
@@ -63,6 +46,27 @@
6346
import org.slf4j.Logger;
6447
import org.slf4j.LoggerFactory;
6548

49+
import java.io.ByteArrayInputStream;
50+
import java.io.IOException;
51+
import java.io.InputStream;
52+
import java.io.UnsupportedEncodingException;
53+
import java.net.URI;
54+
import java.net.URISyntaxException;
55+
import java.net.URL;
56+
import java.net.URLDecoder;
57+
import java.nio.charset.Charset;
58+
import java.nio.charset.StandardCharsets;
59+
import java.nio.file.Path;
60+
import java.nio.file.Paths;
61+
import java.util.Arrays;
62+
import java.util.HashSet;
63+
import java.util.Set;
64+
import java.util.concurrent.ExecutionException;
65+
import java.util.concurrent.TimeUnit;
66+
import java.util.concurrent.TimeoutException;
67+
import java.util.regex.Pattern;
68+
import java.util.stream.StreamSupport;
69+
6670
public class HTTP2JettyClient {
6771

6872
private static final Logger LOG = LoggerFactory.getLogger(HTTP2JettyClient.class);
@@ -147,7 +151,7 @@ public HTTPSampleResult sample(HTTP2Sampler sampler, HTTPSampleResult result,
147151
throw new UnsupportedOperationException(String.format("Method %s is not supported", method));
148152
}
149153

150-
ContentResponse contentResponse = request.send();
154+
ContentResponse contentResponse = send(request);
151155
http1UpgradeRequired = contentResponse.getVersion() != HttpVersion.HTTP_2;
152156
result.setRequestHeaders(buildHeadersString(request.getHeaders()));
153157
setResultContentResponse(result, contentResponse, sampler);
@@ -160,6 +164,34 @@ public HTTPSampleResult sample(HTTP2Sampler sampler, HTTPSampleResult result,
160164
return sampler.resultProcessing(areFollowingRedirect, depth, result);
161165
}
162166

167+
public ContentResponse send(HttpRequest request) throws InterruptedException,
168+
TimeoutException, ExecutionException {
169+
String maxBufferSizeString = JMeterUtils.getPropDefault("httpJettyClient.maxBufferSize",
170+
String.valueOf(2 * 1024 * 1024));
171+
172+
LOG.debug("Setting max buffer size to {}", maxBufferSizeString);
173+
FutureResponseListener listener =
174+
new FutureResponseListener(request, Integer.parseInt(maxBufferSizeString));
175+
request.send(listener);
176+
177+
try {
178+
return listener.get(JMeterUtils.getPropDefault(
179+
"HTTPSampler.response_timeout", 2000), TimeUnit.MILLISECONDS);
180+
} catch (TimeoutException | ExecutionException e) {
181+
if (e instanceof TimeoutException || e.getCause() instanceof TimeoutException) {
182+
throw (TimeoutException) e.getCause();
183+
} else if (e.getMessage().matches(
184+
"java.lang.IllegalArgumentException: Buffering capacity \\d+ exceeded")) {
185+
throw new IllegalArgumentException("Buffer capacity " + maxBufferSizeString + " exceeded. "
186+
+ "To modify buffer size, set the property httpJettyClient.maxBufferSize "
187+
+ "in the jmeter.properties file");
188+
} else if (e.getCause() instanceof TimeoutException) {
189+
throw (TimeoutException) e.getCause();
190+
}
191+
throw e;
192+
}
193+
}
194+
163195
private void setAuthManager(HTTP2Sampler sampler) {
164196
AuthManager authManager = sampler.getAuthManager();
165197
if (authManager != null) {

src/test/java/com/blazemeter/jmeter/http2/core/HTTP2JettyClientTest.java

Lines changed: 62 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,12 @@
11
package com.blazemeter.jmeter.http2.core;
22

3-
import static org.assertj.core.api.Assertions.assertThat;
4-
import static org.junit.Assert.assertThrows;
5-
63
import com.blazemeter.jmeter.http2.sampler.HTTP2Sampler;
74
import com.blazemeter.jmeter.http2.sampler.JMeterTestUtils;
85
import com.google.common.base.Stopwatch;
96
import com.google.common.io.Resources;
107
import jakarta.servlet.http.HttpServlet;
118
import jakarta.servlet.http.HttpServletRequest;
129
import jakarta.servlet.http.HttpServletResponse;
13-
import java.io.ByteArrayOutputStream;
14-
import java.io.IOException;
15-
import java.io.InputStream;
16-
import java.net.MalformedURLException;
17-
import java.net.URL;
18-
import java.nio.charset.StandardCharsets;
19-
import java.nio.file.Files;
20-
import java.nio.file.Paths;
21-
import java.util.Arrays;
22-
import java.util.Base64;
23-
import java.util.Collections;
24-
import java.util.List;
25-
import java.util.concurrent.ExecutionException;
26-
import java.util.concurrent.TimeUnit;
27-
import java.util.concurrent.TimeoutException;
28-
import java.util.stream.Collectors;
29-
import java.util.zip.GZIPOutputStream;
3010
import jodd.net.MimeTypes;
3111
import org.apache.jmeter.config.Arguments;
3212
import org.apache.jmeter.protocol.http.control.AuthManager;
@@ -75,6 +55,27 @@
7555
import org.junit.runner.RunWith;
7656
import org.mockito.junit.MockitoJUnitRunner;
7757

58+
import java.io.ByteArrayOutputStream;
59+
import java.io.IOException;
60+
import java.io.InputStream;
61+
import java.net.MalformedURLException;
62+
import java.net.URL;
63+
import java.nio.charset.StandardCharsets;
64+
import java.nio.file.Files;
65+
import java.nio.file.Paths;
66+
import java.util.Arrays;
67+
import java.util.Base64;
68+
import java.util.Collections;
69+
import java.util.List;
70+
import java.util.concurrent.ExecutionException;
71+
import java.util.concurrent.TimeUnit;
72+
import java.util.concurrent.TimeoutException;
73+
import java.util.stream.Collectors;
74+
import java.util.zip.GZIPOutputStream;
75+
76+
import static org.assertj.core.api.Assertions.assertThat;
77+
import static org.junit.Assert.assertThrows;
78+
7879
@RunWith(MockitoJUnitRunner.class)
7980
public class HTTP2JettyClientTest {
8081

@@ -91,6 +92,7 @@ public class HTTP2JettyClientTest {
9192
private static final String SERVER_PATH_200_GZIP = "/test/gzip";
9293
private static final String SERVER_PATH_200_EMBEDDED = "/test/embedded";
9394
private static final String SERVER_PATH_200_FILE_SENT = "/test/file";
95+
private static final String SERVER_PATH_BIG_RESPONSE = "/test/big-response";
9496
private static final String SERVER_PATH_400 = "/test/400";
9597
private static final String SERVER_PATH_302 = "/test/302";
9698
private static final String SERVER_PATH_200_WITH_BODY = "/test/body";
@@ -104,6 +106,7 @@ public class HTTP2JettyClientTest {
104106
private static final String AUTH_PASSWORD = "password";
105107
private static final String AUTH_REALM = "realm";
106108
private static final String KEYSTORE_PASSWORD = "storepwd";
109+
private static final int BIG_BUFFER_SIZE = 4 * 1024 * 1024;
107110

108111
@Rule
109112
public final JUnitSoftAssertions softly = new JUnitSoftAssertions();
@@ -239,6 +242,11 @@ protected void service(HttpServletRequest req, HttpServletResponse resp) throws
239242
break;
240243
case SERVER_PATH_DELETE_DATA:
241244
resp.setStatus(HttpStatus.OK_200);
245+
break;
246+
case SERVER_PATH_BIG_RESPONSE:
247+
resp.getOutputStream().write(new byte[(int) BIG_BUFFER_SIZE]);
248+
resp.setContentType("image/jpg");
249+
break;
242250
}
243251
}
244252
};
@@ -293,12 +301,12 @@ public void shouldSendBodyInformationWhenRequestWithBodyRaw() throws Exception {
293301
}
294302

295303
private HTTPSampleResult buildOkResult(String requestBody, String requestContentType) {
296-
return buildResult(true, HttpStatus.Code.OK, null,
304+
return buildResult(true, Code.OK, null,
297305
requestBody != null ? requestBody.getBytes(StandardCharsets.UTF_8) : null,
298306
requestContentType);
299307
}
300308

301-
private HTTPSampleResult buildResult(boolean successful, HttpStatus.Code statusCode,
309+
private HTTPSampleResult buildResult(boolean successful, Code statusCode,
302310
HttpFields headers, byte[] requestBody, String requestContentType) {
303311

304312
Mutable httpFields = HttpFields.build()
@@ -861,7 +869,7 @@ public void shouldNotUseMultipartWhenHasOneFileWithEmptyParamName() throws Excep
861869
buildStartedServer();
862870
URL file = getClass().getResource("blazemeter-labs-logo.png");
863871
sampler.setHTTPFiles(new HTTPFileArg[]{new HTTPFileArg(file.getPath(), "", "image/png")});
864-
HTTPSampleResult expected = buildResult(true, HttpStatus.Code.OK, null,
872+
HTTPSampleResult expected = buildResult(true, Code.OK, null,
865873
Resources.toByteArray(file), "image/png");
866874
validateResponse(sample(SERVER_PATH_200_FILE_SENT, HTTPConstants.POST), expected);
867875
}
@@ -899,4 +907,35 @@ public void shouldGetSuccessResponseWhenServerRequiresClientCertAndOneIsConfigur
899907
}
900908
}
901909

910+
@Test
911+
public void shouldGetResponseWhenBufferSizeIsSmallerOrTheSameAsMaxBufferSize() throws Exception {
912+
buildStartedServer();
913+
JMeterUtils.setProperty("httpJettyClient.maxBufferSize", String.valueOf(BIG_BUFFER_SIZE));
914+
HTTPSampleResult result = sampleWithGet(SERVER_PATH_BIG_RESPONSE);
915+
//Since no text response was set, we validate the size of the response body instead.
916+
assertThat(result.getBodySizeAsLong()).isEqualTo(BIG_BUFFER_SIZE);
917+
}
918+
919+
@Test(expected = IllegalArgumentException.class)
920+
public void shouldThrowAnExceptionWhenBufferSizeIsBiggerThanMaxBufferSize() throws Exception {
921+
buildStartedServer();
922+
JMeterUtils.setProperty("httpJettyClient.maxBufferSize", String.valueOf(BIG_BUFFER_SIZE - 1));
923+
sampleWithGet(SERVER_PATH_BIG_RESPONSE);
924+
}
925+
926+
@Test
927+
public void shouldNotGetAResponseWhenBufferSizeIsBiggerThanMaxBufferSize() throws Exception {
928+
buildStartedServer();
929+
JMeterUtils.setProperty("httpJettyClient.maxBufferSize", String.valueOf(BIG_BUFFER_SIZE - 1));
930+
//There is no response, since an exception is thrown in this case
931+
932+
Exception exception = assertThrows(IllegalArgumentException.class,
933+
() -> sampleWithGet(SERVER_PATH_BIG_RESPONSE));
934+
935+
assertThat(exception.toString()).contains(
936+
"java.lang.IllegalArgumentException: Buffer capacity 4194303 exceeded."
937+
+ " To modify buffer size, set the property httpJettyClient.maxBufferSize"
938+
+ " in the jmeter.properties file");
939+
}
940+
902941
}

0 commit comments

Comments
 (0)