Skip to content

Commit f5f9b4b

Browse files
committed
default behavior should target Netty 4, see AsyncHttpClient#948
1 parent 77bbdfd commit f5f9b4b

File tree

4 files changed

+92
-77
lines changed

4 files changed

+92
-77
lines changed

api/src/main/java/org/asynchttpclient/request/body/generator/FeedableBodyGenerator.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ public final class FeedableBodyGenerator implements BodyGenerator {
3232
private final Queue<BodyPart> queue = new ConcurrentLinkedQueue<>();
3333
private FeedListener listener;
3434

35-
private boolean writeChunkBoundaries = true;
35+
// must be set to true when using Netty 3 where native chunking is broken
36+
private boolean writeChunkBoundaries = false;
3637

3738
@Override
3839
public Body createBody() {
@@ -54,8 +55,8 @@ public void setListener(FeedListener listener) {
5455
this.listener = listener;
5556
}
5657

57-
public void setWriteChunkBoundaries(boolean writeChunkBoundaries) {
58-
this.writeChunkBoundaries = writeChunkBoundaries;
58+
public void writeChunkBoundaries() {
59+
this.writeChunkBoundaries = true;
5960
}
6061

6162
private static enum PushBodyState {
@@ -89,7 +90,7 @@ public long read(final ByteBuffer buffer) throws IOException {
8990
return -1;
9091
}
9192
}
92-
if(nextPart.buffer.remaining() == 0) {
93+
if (nextPart.buffer.remaining() == 0) {
9394
// skip empty buffers
9495
// if we return 0 here it would suspend the stream - we don't want that
9596
queue.remove();
Lines changed: 83 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,16 @@
1+
/*
2+
* Copyright (c) 2014 AsyncHttpClient Project. All rights reserved.
3+
*
4+
* This program is licensed to you under the Apache License Version 2.0,
5+
* and you may not use this file except in compliance with the Apache License Version 2.0.
6+
* You may obtain a copy of the Apache License Version 2.0 at
7+
* http://www.apache.org/licenses/LICENSE-2.0.
8+
*
9+
* Unless required by applicable law or agreed to in writing,
10+
* software distributed under the Apache License Version 2.0 is distributed on an
11+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
13+
*/
114
package org.asynchttpclient.request.body.generator;
215

316
import org.asynchttpclient.request.body.Body;
@@ -12,76 +25,77 @@
1225

1326
public class FeedableBodyGeneratorTest {
1427

15-
private FeedableBodyGenerator feedableBodyGenerator;
16-
private TestFeedListener listener;
17-
18-
@BeforeMethod
19-
public void setUp() throws Exception {
20-
feedableBodyGenerator = new FeedableBodyGenerator();
21-
listener = new TestFeedListener();
22-
feedableBodyGenerator.setListener(listener);
23-
}
24-
25-
@Test(groups = "standalone")
26-
public void feedNotifiesListener() throws Exception {
27-
feedableBodyGenerator.feed(ByteBuffer.allocate(0), false);
28-
feedableBodyGenerator.feed(ByteBuffer.allocate(0), true);
29-
assertEquals(listener.getCalls(), 2);
30-
}
31-
32-
@Test(groups = "standalone")
33-
public void readingBytesReturnsFedContentWithEmptyLastBuffer() throws Exception {
34-
byte[] content = "Test123".getBytes(StandardCharsets.US_ASCII);
35-
feedableBodyGenerator.feed(ByteBuffer.wrap(content), false);
36-
feedableBodyGenerator.feed(ByteBuffer.allocate(0), true);
37-
Body body = feedableBodyGenerator.createBody();
38-
assertEquals(readFromBody(body), "7\r\nTest123\r\n".getBytes(StandardCharsets.US_ASCII));
39-
assertEquals(readFromBody(body), "0\r\n\r\n".getBytes(StandardCharsets.US_ASCII));
40-
assertEquals(body.read(ByteBuffer.allocate(1)), -1);
41-
42-
}
43-
44-
@Test(groups = "standalone")
45-
public void readingBytesReturnsFedContentWithFilledLastBuffer() throws Exception {
46-
byte[] content = "Test123".getBytes(StandardCharsets.US_ASCII);
47-
feedableBodyGenerator.feed(ByteBuffer.wrap(content), true);
48-
Body body = feedableBodyGenerator.createBody();
49-
assertEquals(readFromBody(body), "7\r\nTest123\r\n".getBytes(StandardCharsets.US_ASCII));
50-
assertEquals(readFromBody(body), "0\r\n\r\n".getBytes(StandardCharsets.US_ASCII));
51-
assertEquals(body.read(ByteBuffer.allocate(1)), -1);
52-
53-
}
54-
55-
@Test(groups = "standalone")
56-
public void readingBytesReturnsFedContentWithoutChunkBoundariesWhenDisabled() throws Exception {
57-
byte[] content = "Test123".getBytes(StandardCharsets.US_ASCII);
58-
feedableBodyGenerator.setWriteChunkBoundaries(false);
59-
feedableBodyGenerator.feed(ByteBuffer.wrap(content), true);
60-
Body body = feedableBodyGenerator.createBody();
61-
assertEquals(readFromBody(body), "Test123".getBytes(StandardCharsets.US_ASCII));
62-
assertEquals(body.read(ByteBuffer.allocate(1)), -1);
63-
64-
}
65-
66-
private byte[] readFromBody(Body body) throws IOException {
67-
ByteBuffer byteBuffer = ByteBuffer.allocate(512);
68-
body.read(byteBuffer);
69-
byteBuffer.flip();
70-
byte[] readBytes = new byte[byteBuffer.remaining()];
71-
byteBuffer.get(readBytes);
72-
return readBytes;
73-
}
74-
75-
private static class TestFeedListener implements FeedableBodyGenerator.FeedListener {
76-
77-
private int calls;
78-
@Override
79-
public void onContentAdded() {
80-
calls++;
28+
private FeedableBodyGenerator feedableBodyGenerator;
29+
private TestFeedListener listener;
30+
31+
@BeforeMethod
32+
public void setUp() throws Exception {
33+
feedableBodyGenerator = new FeedableBodyGenerator();
34+
listener = new TestFeedListener();
35+
feedableBodyGenerator.setListener(listener);
36+
}
37+
38+
@Test(groups = "standalone")
39+
public void feedNotifiesListener() throws Exception {
40+
feedableBodyGenerator.feed(ByteBuffer.allocate(0), false);
41+
feedableBodyGenerator.feed(ByteBuffer.allocate(0), true);
42+
assertEquals(listener.getCalls(), 2);
43+
}
44+
45+
@Test(groups = "standalone")
46+
public void readingBytesReturnsFedContentWithEmptyLastBufferWhenChunkBoundariesEnabled() throws Exception {
47+
feedableBodyGenerator.writeChunkBoundaries();
48+
byte[] content = "Test123".getBytes(StandardCharsets.US_ASCII);
49+
feedableBodyGenerator.feed(ByteBuffer.wrap(content), false);
50+
feedableBodyGenerator.feed(ByteBuffer.allocate(0), true);
51+
Body body = feedableBodyGenerator.createBody();
52+
assertEquals(readFromBody(body), "7\r\nTest123\r\n".getBytes(StandardCharsets.US_ASCII));
53+
assertEquals(readFromBody(body), "0\r\n\r\n".getBytes(StandardCharsets.US_ASCII));
54+
assertEquals(body.read(ByteBuffer.allocate(1)), -1);
55+
56+
}
57+
58+
@Test(groups = "standalone")
59+
public void readingBytesReturnsFedContentWithFilledLastBufferWhenChunkBoundariesEnabled() throws Exception {
60+
feedableBodyGenerator.writeChunkBoundaries();
61+
byte[] content = "Test123".getBytes(StandardCharsets.US_ASCII);
62+
feedableBodyGenerator.feed(ByteBuffer.wrap(content), true);
63+
Body body = feedableBodyGenerator.createBody();
64+
assertEquals(readFromBody(body), "7\r\nTest123\r\n".getBytes(StandardCharsets.US_ASCII));
65+
assertEquals(readFromBody(body), "0\r\n\r\n".getBytes(StandardCharsets.US_ASCII));
66+
assertEquals(body.read(ByteBuffer.allocate(1)), -1);
67+
68+
}
69+
70+
@Test(groups = "standalone")
71+
public void readingBytesReturnsFedContentWithoutChunkBoundariesWhenNotEnabled() throws Exception {
72+
byte[] content = "Test123".getBytes(StandardCharsets.US_ASCII);
73+
feedableBodyGenerator.feed(ByteBuffer.wrap(content), true);
74+
Body body = feedableBodyGenerator.createBody();
75+
assertEquals(readFromBody(body), "Test123".getBytes(StandardCharsets.US_ASCII));
76+
assertEquals(body.read(ByteBuffer.allocate(1)), -1);
77+
}
78+
79+
private byte[] readFromBody(Body body) throws IOException {
80+
ByteBuffer byteBuffer = ByteBuffer.allocate(512);
81+
body.read(byteBuffer);
82+
byteBuffer.flip();
83+
byte[] readBytes = new byte[byteBuffer.remaining()];
84+
byteBuffer.get(readBytes);
85+
return readBytes;
8186
}
8287

83-
public int getCalls() {
84-
return calls;
88+
private static class TestFeedListener implements FeedableBodyGenerator.FeedListener {
89+
90+
private int calls;
91+
92+
@Override
93+
public void onContentAdded() {
94+
calls++;
95+
}
96+
97+
public int getCalls() {
98+
return calls;
99+
}
85100
}
86-
}
87101
}

providers/netty3/src/main/java/org/asynchttpclient/netty/request/body/NettyBodyBody.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ public void write(final Channel channel, NettyResponseFuture<?> future) throws I
6666

6767
BodyGenerator bg = future.getRequest().getBodyGenerator();
6868
if (bg instanceof FeedableBodyGenerator) {
69-
FeedableBodyGenerator.class.cast(bg).setListener(new FeedListener() {
69+
final FeedableBodyGenerator feedableBodyGenerator = (FeedableBodyGenerator) bg;
70+
feedableBodyGenerator.writeChunkBoundaries();
71+
feedableBodyGenerator.setListener(new FeedListener() {
7072
@Override
7173
public void onContentAdded() {
7274
channel.getPipeline().get(ChunkedWriteHandler.class).resumeTransfer();

providers/netty4/src/main/java/org/asynchttpclient/netty/request/body/NettyBodyBody.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,7 @@ public void write(final Channel channel, NettyResponseFuture<?> future) throws I
6868

6969
BodyGenerator bg = future.getRequest().getBodyGenerator();
7070
if (bg instanceof FeedableBodyGenerator) {
71-
final FeedableBodyGenerator feedableBodyGenerator = (FeedableBodyGenerator) bg;
72-
feedableBodyGenerator.setWriteChunkBoundaries(false);
73-
feedableBodyGenerator.setListener(new FeedListener() {
71+
FeedableBodyGenerator.class.cast(bg).setListener(new FeedListener() {
7472
@Override
7573
public void onContentAdded() {
7674
channel.pipeline().get(ChunkedWriteHandler.class).resumeTransfer();

0 commit comments

Comments
 (0)