Skip to content

Commit 1a6c522

Browse files
committed
Added explicit constructor for -1 contentLength
- Added tests for all combinations of known/unknown contentLength and enabled/disabled zeroCopy for `InputStreamPart` - Fixed how `length()` is computed for `MultipartPart` - returns -1 if contentLength < 0 - Added condition in `NettyBodyBody` to use `BodyChunkedBody` for "zeroCopy" of `RandomAccessBody` if contentLength is -1
1 parent 049ee8d commit 1a6c522

File tree

6 files changed

+73
-23
lines changed

6 files changed

+73
-23
lines changed

client/src/main/java/org/asynchttpclient/netty/request/body/NettyBodyBody.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,13 @@ public void write(final Channel channel, NettyResponseFuture<?> future) {
5454

5555
Object msg;
5656
if (body instanceof RandomAccessBody && !ChannelManager.isSslHandlerConfigured(channel.pipeline()) && !config.isDisableZeroCopy()) {
57-
msg = new BodyFileRegion((RandomAccessBody) body);
57+
long contentLength = getContentLength();
58+
if (contentLength < 0) {
59+
// contentLength unknown in advance, use chunked input
60+
msg = new BodyChunkedInput(body);
61+
} else {
62+
msg = new BodyFileRegion((RandomAccessBody) body);
63+
}
5864

5965
} else {
6066
msg = new BodyChunkedInput(body);

client/src/main/java/org/asynchttpclient/request/body/multipart/InputStreamPart.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,28 @@ public class InputStreamPart extends FileLikePart {
1010
private final InputStream inputStream;
1111
private final long contentLength;
1212

13-
public InputStreamPart(String name, InputStream inputStream, long contentLength, String fileName) {
14-
this(name, inputStream, contentLength, fileName, null);
13+
public InputStreamPart(String name, InputStream inputStream, String fileName) {
14+
this(name, inputStream, fileName, -1);
1515
}
1616

17-
public InputStreamPart(String name, InputStream inputStream, long contentLength, String fileName, String contentType) {
18-
this(name, inputStream, contentLength, fileName, contentType, null);
17+
public InputStreamPart(String name, InputStream inputStream, String fileName, long contentLength) {
18+
this(name, inputStream, fileName, contentLength, null);
1919
}
2020

21-
public InputStreamPart(String name, InputStream inputStream, long contentLength, String fileName, String contentType, Charset charset) {
22-
this(name, inputStream, contentLength, fileName, contentType, charset, null);
21+
public InputStreamPart(String name, InputStream inputStream, String fileName, long contentLength, String contentType) {
22+
this(name, inputStream, fileName, contentLength, contentType, null);
2323
}
2424

25-
public InputStreamPart(String name, InputStream inputStream, long contentLength, String fileName, String contentType, Charset charset,
25+
public InputStreamPart(String name, InputStream inputStream, String fileName, long contentLength, String contentType, Charset charset) {
26+
this(name, inputStream, fileName, contentLength, contentType, charset, null);
27+
}
28+
29+
public InputStreamPart(String name, InputStream inputStream, String fileName, long contentLength, String contentType, Charset charset,
2630
String contentId) {
27-
this(name, inputStream, contentLength, fileName, contentType, charset, contentId, null);
31+
this(name, inputStream, fileName, contentLength, contentType, charset, contentId, null);
2832
}
2933

30-
public InputStreamPart(String name, InputStream inputStream, long contentLength, String fileName, String contentType, Charset charset,
34+
public InputStreamPart(String name, InputStream inputStream, String fileName, long contentLength, String contentType, Charset charset,
3135
String contentId, String transferEncoding) {
3236
super(name,
3337
contentType,

client/src/main/java/org/asynchttpclient/request/body/multipart/part/MultipartPart.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ public abstract class MultipartPart<T extends PartBase> implements Closeable {
106106
}
107107

108108
public long length() {
109+
long contentLength = getContentLength();
110+
if (contentLength < 0) {
111+
return contentLength;
112+
}
109113
return preContentLength + postContentLength + getContentLength();
110114
}
111115

client/src/test/java/org/asynchttpclient/request/body/InputStreamPartLargeFileTest.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import org.asynchttpclient.AbstractBasicTest;
1616
import org.asynchttpclient.AsyncHttpClient;
1717
import org.asynchttpclient.Response;
18-
import org.asynchttpclient.request.body.multipart.FilePart;
1918
import org.asynchttpclient.request.body.multipart.InputStreamPart;
2019
import org.eclipse.jetty.server.Request;
2120
import org.eclipse.jetty.server.handler.AbstractHandler;
@@ -64,7 +63,7 @@ public void handle(String target, Request baseRequest, HttpServletRequest req, H
6463
public void testPutImageFile() throws Exception {
6564
try (AsyncHttpClient client = asyncHttpClient(config().setRequestTimeout(100 * 6000))) {
6665
InputStream inputStream = new BufferedInputStream(new FileInputStream(LARGE_IMAGE_FILE));
67-
Response response = client.preparePut(getTargetUrl()).addBodyPart(new InputStreamPart("test", inputStream, LARGE_IMAGE_FILE.length(), LARGE_IMAGE_FILE.getName(), "application/octet-stream", UTF_8)).execute().get();
66+
Response response = client.preparePut(getTargetUrl()).addBodyPart(new InputStreamPart("test", inputStream, LARGE_IMAGE_FILE.getName(), LARGE_IMAGE_FILE.length(), "application/octet-stream", UTF_8)).execute().get();
6867
assertEquals(response.getStatusCode(), 200);
6968
}
7069
}
@@ -76,7 +75,7 @@ public void testPutLargeTextFile() throws Exception {
7675

7776
try (AsyncHttpClient client = asyncHttpClient(config().setRequestTimeout(100 * 6000))) {
7877
Response response = client.preparePut(getTargetUrl())
79-
.addBodyPart(new InputStreamPart("test", inputStream, file.length(), file.getName(), "application/octet-stream", UTF_8)).execute().get();
78+
.addBodyPart(new InputStreamPart("test", inputStream, file.getName(), file.length(), "application/octet-stream", UTF_8)).execute().get();
8079
assertEquals(response.getStatusCode(), 200);
8180
}
8281
}

client/src/test/java/org/asynchttpclient/request/body/multipart/MultipartBodyTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ private static MultipartBody buildMultipart() {
6666
try {
6767
File testFile = getTestfile();
6868
InputStream inputStream = new BufferedInputStream(new FileInputStream(testFile));
69-
parts.add(new InputStreamPart("isPart", inputStream, testFile.length(), testFile.getName()));
69+
parts.add(new InputStreamPart("isPart", inputStream, testFile.getName(), testFile.length()));
7070
} catch (URISyntaxException | FileNotFoundException e) {
7171
throw new ExceptionInInitializerError(e);
7272
}

client/src/test/java/org/asynchttpclient/request/body/multipart/MultipartUploadTest.java

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,11 @@ public void testSendingSmallFilesAndByteArray() throws Exception {
121121
.addBodyPart(new StringPart("Name", "Dominic"))
122122
.addBodyPart(new FilePart("file3", testResource3File, "text/plain", UTF_8))
123123
.addBodyPart(new StringPart("Age", "3")).addBodyPart(new StringPart("Height", "shrimplike"))
124-
.addBodyPart(new InputStreamPart("inputStream3", inputStreamFile3, testResource3File.length(), testResource3File.getName(), "text/plain", UTF_8))
125-
.addBodyPart(new InputStreamPart("inputStream2", inputStreamFile2, testResource2File.length(), testResource2File.getName(), "application/x-gzip", null))
124+
.addBodyPart(new InputStreamPart("inputStream3", inputStreamFile3, testResource3File.getName(), testResource3File.length(), "text/plain", UTF_8))
125+
.addBodyPart(new InputStreamPart("inputStream2", inputStreamFile2, testResource2File.getName(), testResource2File.length(), "application/x-gzip", null))
126126
.addBodyPart(new StringPart("Hair", "ridiculous")).addBodyPart(new ByteArrayPart("file4",
127127
expectedContents.getBytes(UTF_8), "text/plain", UTF_8, "bytearray.txt"))
128-
.addBodyPart(new InputStreamPart("inputStream1", inputStreamFile1, testResource1File.length(), testResource1File.getName(), "text/plain", UTF_8))
128+
.addBodyPart(new InputStreamPart("inputStream1", inputStreamFile1, testResource1File.getName(), testResource1File.length(), "text/plain", UTF_8))
129129
.build();
130130

131131
Response res = c.executeRequest(r).get();
@@ -157,26 +157,63 @@ public void sendEmptyFileZeroCopy() throws Exception {
157157
sendEmptyFile0(false);
158158
}
159159

160-
private void sendEmptyFileInputStream0(boolean disableZeroCopy) throws Exception {
160+
private void sendEmptyFileInputStream(boolean disableZeroCopy) throws Exception {
161161
File file = getClasspathFile("empty.txt");
162162
try (AsyncHttpClient c = asyncHttpClient(config().setDisableZeroCopy(disableZeroCopy))) {
163163
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
164164
Request r = post("http://localhost" + ":" + port1 + "/upload")
165-
.addBodyPart(new InputStreamPart("file", inputStream, file.length(), file.getName(), "text/plain", UTF_8)).build();
165+
.addBodyPart(new InputStreamPart("file", inputStream, file.getName(), file.length(), "text/plain", UTF_8)).build();
166166

167167
Response res = c.executeRequest(r).get();
168168
assertEquals(res.getStatusCode(), 200);
169169
}
170170
}
171171

172172
@Test
173-
public void sendEmptyFileInputStream() throws Exception {
174-
sendEmptyFileInputStream0(true);
173+
public void testSendEmptyFileInputStream() throws Exception {
174+
sendEmptyFileInputStream(true);
175175
}
176176

177177
@Test
178-
public void sendEmptyFileInputStreamZeroCopy() throws Exception {
179-
sendEmptyFileInputStream0(false);
178+
public void testSendEmptyFileInputStreamZeroCopy() throws Exception {
179+
sendEmptyFileInputStream(false);
180+
}
181+
182+
private void sendFileInputStream(boolean useContentLength, boolean disableZeroCopy) throws Exception {
183+
File file = getClasspathFile("textfile.txt");
184+
try (AsyncHttpClient c = asyncHttpClient(config().setDisableZeroCopy(disableZeroCopy))) {
185+
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
186+
InputStreamPart part;
187+
if (useContentLength) {
188+
part = new InputStreamPart("file", inputStream, file.getName(), file.length());
189+
} else {
190+
part = new InputStreamPart("file", inputStream, file.getName());
191+
}
192+
Request r = post("http://localhost" + ":" + port1 + "/upload").addBodyPart(part).build();
193+
194+
Response res = c.executeRequest(r).get();
195+
assertEquals(res.getStatusCode(), 200);
196+
}
197+
}
198+
199+
@Test
200+
public void testSendFileInputStreamUnknownContentLength() throws Exception {
201+
sendFileInputStream(false, true);
202+
}
203+
204+
@Test
205+
public void testSendFileInputStreamZeroCopyUnknownContentLength() throws Exception {
206+
sendFileInputStream(false, false);
207+
}
208+
209+
@Test
210+
public void testSendFileInputStreamKnownContentLength() throws Exception {
211+
sendFileInputStream(true, true);
212+
}
213+
214+
@Test
215+
public void testSendFileInputStreamZeroCopyKnownContentLength() throws Exception {
216+
sendFileInputStream(true, false);
180217
}
181218

182219
/**

0 commit comments

Comments
 (0)