Skip to content

Commit 7f5ebe5

Browse files
author
Stephane Landelle
committed
Let one pass a List<byte[]> request body, close AsyncHttpClient#763
1 parent eb348c5 commit 7f5ebe5

File tree

9 files changed

+202
-57
lines changed

9 files changed

+202
-57
lines changed

api/src/main/java/org/asynchttpclient/Request.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ public interface Request {
7979
*/
8080
byte[] getByteData();
8181

82+
/**
83+
* @return the current request's body as a composite of byte arrays
84+
*/
85+
List<byte[]> getCompositeByteData();
86+
8287
/**
8388
* Return the current request's body as a string
8489
*

api/src/main/java/org/asynchttpclient/RequestBuilderBase.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ private static final class RequestImpl implements Request {
5252
private FluentCaseInsensitiveStringsMap headers = new FluentCaseInsensitiveStringsMap();
5353
private ArrayList<Cookie> cookies;
5454
private byte[] byteData;
55+
private List<byte[]> compositeByteData;
5556
private String stringData;
5657
private InputStream streamData;
5758
private BodyGenerator bodyGenerator;
@@ -81,6 +82,7 @@ public RequestImpl(Request prototype) {
8182
this.headers = new FluentCaseInsensitiveStringsMap(prototype.getHeaders());
8283
this.cookies = new ArrayList<Cookie>(prototype.getCookies());
8384
this.byteData = prototype.getByteData();
85+
this.compositeByteData = prototype.getCompositeByteData();
8486
this.stringData = prototype.getStringData();
8587
this.streamData = prototype.getStreamData();
8688
this.bodyGenerator = prototype.getBodyGenerator();
@@ -139,6 +141,11 @@ public byte[] getByteData() {
139141
return byteData;
140142
}
141143

144+
@Override
145+
public List<byte[]> getCompositeByteData() {
146+
return compositeByteData;
147+
}
148+
142149
@Override
143150
public String getStringData() {
144151
return stringData;
@@ -394,6 +401,7 @@ public void resetFormParams() {
394401

395402
public void resetNonMultipartData() {
396403
request.byteData = null;
404+
request.compositeByteData = null;
397405
request.stringData = null;
398406
request.streamData = null;
399407
request.bodyGenerator = null;
@@ -417,6 +425,14 @@ public T setBody(byte[] data) {
417425
return derived.cast(this);
418426
}
419427

428+
public T setBody(List<byte[]> data) {
429+
resetFormParams();
430+
resetNonMultipartData();
431+
resetMultipartData();
432+
request.compositeByteData = data;
433+
return derived.cast(this);
434+
}
435+
420436
public T setBody(String data) {
421437
resetFormParams();
422438
resetNonMultipartData();

providers/netty3/src/main/java/org/asynchttpclient/providers/netty3/request/NettyRequestFactory.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
*/
1414
package org.asynchttpclient.providers.netty3.request;
1515

16-
import static org.asynchttpclient.providers.netty.commons.util.HttpUtils.*;
16+
import static org.asynchttpclient.providers.netty.commons.util.HttpUtils.getNTLM;
17+
import static org.asynchttpclient.providers.netty.commons.util.HttpUtils.isSecure;
18+
import static org.asynchttpclient.providers.netty.commons.util.HttpUtils.isWebSocket;
19+
import static org.asynchttpclient.providers.netty.commons.util.HttpUtils.useProxyConnect;
1720
import static org.asynchttpclient.providers.netty.commons.util.WebSocketUtils.getKey;
1821
import static org.asynchttpclient.util.AsyncHttpProviderUtils.DEFAULT_CHARSET;
1922
import static org.asynchttpclient.util.AsyncHttpProviderUtils.getAuthority;
@@ -41,13 +44,15 @@
4144
import org.asynchttpclient.providers.netty3.request.body.NettyBody;
4245
import org.asynchttpclient.providers.netty3.request.body.NettyBodyBody;
4346
import org.asynchttpclient.providers.netty3.request.body.NettyByteArrayBody;
47+
import org.asynchttpclient.providers.netty3.request.body.NettyCompositeByteArrayBody;
48+
import org.asynchttpclient.providers.netty3.request.body.NettyDirectBody;
4449
import org.asynchttpclient.providers.netty3.request.body.NettyFileBody;
4550
import org.asynchttpclient.providers.netty3.request.body.NettyInputStreamBody;
4651
import org.asynchttpclient.providers.netty3.request.body.NettyMultipartBody;
4752
import org.asynchttpclient.spnego.SpnegoEngine;
4853
import org.asynchttpclient.uri.Uri;
4954
import org.asynchttpclient.util.UTF8UrlEncoder;
50-
import org.jboss.netty.buffer.ChannelBuffers;
55+
import org.jboss.netty.buffer.ChannelBuffer;
5156
import org.jboss.netty.handler.codec.http.DefaultHttpRequest;
5257
import org.jboss.netty.handler.codec.http.HttpHeaders;
5358
import org.jboss.netty.handler.codec.http.HttpMethod;
@@ -202,6 +207,9 @@ private NettyBody body(Request request, HttpMethod method) throws IOException {
202207
if (request.getByteData() != null)
203208
nettyBody = new NettyByteArrayBody(request.getByteData());
204209

210+
else if (request.getCompositeByteData() != null)
211+
nettyBody = new NettyCompositeByteArrayBody(request.getCompositeByteData());
212+
205213
else if (request.getStringData() != null)
206214
nettyBody = new NettyByteArrayBody(request.getStringData().getBytes(bodyCharset));
207215

@@ -259,11 +267,11 @@ public NettyRequest newNettyRequest(Request request, Uri uri, boolean forceConne
259267

260268
HttpRequest httpRequest;
261269
NettyRequest nettyRequest;
262-
if (body instanceof NettyByteArrayBody) {
263-
byte[] bytes = NettyByteArrayBody.class.cast(body).getBytes();
270+
if (body instanceof NettyDirectBody) {
271+
ChannelBuffer buffer = NettyDirectBody.class.cast(body).channelBuffer();
264272
httpRequest = new DefaultHttpRequest(httpVersion, method, requestUri);
265273
// body is passed as null as it's written directly with the request
266-
httpRequest.setContent(ChannelBuffers.wrappedBuffer(bytes));
274+
httpRequest.setContent(buffer);
267275
nettyRequest = new NettyRequest(httpRequest, null);
268276

269277
} else {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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+
*/
14+
package org.asynchttpclient.providers.netty3.request.body;
15+
16+
import java.util.List;
17+
18+
import org.jboss.netty.buffer.ChannelBuffer;
19+
import org.jboss.netty.buffer.ChannelBuffers;
20+
21+
public class NettyCompositeByteArrayBody extends NettyDirectBody {
22+
23+
private final byte[][] bytes;
24+
private final String contentType;
25+
private final long contentLength;
26+
27+
public NettyCompositeByteArrayBody(List<byte[]> bytes) {
28+
this(bytes, null);
29+
}
30+
31+
public NettyCompositeByteArrayBody(List<byte[]> bytes, String contentType) {
32+
this.bytes = new byte[bytes.size()][];
33+
bytes.toArray(this.bytes);
34+
this.contentType = contentType;
35+
long l = 0;
36+
for (byte[] b : bytes)
37+
l += b.length;
38+
contentLength = l;
39+
}
40+
41+
@Override
42+
public long getContentLength() {
43+
return contentLength;
44+
}
45+
46+
@Override
47+
public String getContentType() {
48+
return contentType;
49+
}
50+
51+
@Override
52+
public ChannelBuffer channelBuffer() {
53+
return ChannelBuffers.wrappedBuffer(bytes);
54+
}
55+
}
Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,35 +17,12 @@
1717

1818
import org.asynchttpclient.AsyncHttpClientConfig;
1919
import org.asynchttpclient.providers.netty3.future.NettyResponseFuture;
20+
import org.jboss.netty.buffer.ChannelBuffer;
2021
import org.jboss.netty.channel.Channel;
2122

22-
public class NettyByteArrayBody implements NettyBody {
23+
public abstract class NettyDirectBody implements NettyBody {
2324

24-
private final byte[] bytes;
25-
private final String contentType;
26-
27-
public NettyByteArrayBody(byte[] bytes) {
28-
this(bytes, null);
29-
}
30-
31-
public NettyByteArrayBody(byte[] bytes, String contentType) {
32-
this.bytes = bytes;
33-
this.contentType = contentType;
34-
}
35-
36-
public byte[] getBytes() {
37-
return bytes;
38-
}
39-
40-
@Override
41-
public long getContentLength() {
42-
return bytes.length;
43-
}
44-
45-
@Override
46-
public String getContentType() {
47-
return contentType;
48-
}
25+
public abstract ChannelBuffer channelBuffer();
4926

5027
@Override
5128
public void write(Channel channel, NettyResponseFuture<?> future, AsyncHttpClientConfig config) throws IOException {

providers/netty4/src/main/java/org/asynchttpclient/providers/netty4/request/NettyRequestFactory.java

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import static org.asynchttpclient.util.AuthenticatorUtils.computeBasicAuthentication;
2626
import static org.asynchttpclient.util.AuthenticatorUtils.computeDigestAuthentication;
2727
import static org.asynchttpclient.util.MiscUtils.isNonEmpty;
28-
import io.netty.buffer.Unpooled;
28+
import io.netty.buffer.ByteBuf;
2929
import io.netty.handler.codec.http.DefaultFullHttpRequest;
3030
import io.netty.handler.codec.http.DefaultHttpRequest;
3131
import io.netty.handler.codec.http.HttpHeaders;
@@ -51,6 +51,8 @@
5151
import org.asynchttpclient.providers.netty4.request.body.NettyBody;
5252
import org.asynchttpclient.providers.netty4.request.body.NettyBodyBody;
5353
import org.asynchttpclient.providers.netty4.request.body.NettyByteArrayBody;
54+
import org.asynchttpclient.providers.netty4.request.body.NettyCompositeByteArrayBody;
55+
import org.asynchttpclient.providers.netty4.request.body.NettyDirectBody;
5456
import org.asynchttpclient.providers.netty4.request.body.NettyFileBody;
5557
import org.asynchttpclient.providers.netty4.request.body.NettyInputStreamBody;
5658
import org.asynchttpclient.providers.netty4.request.body.NettyMultipartBody;
@@ -203,39 +205,41 @@ private NettyBody body(Request request, HttpMethod method) throws IOException {
203205

204206
Charset bodyCharset = request.getBodyEncoding() == null ? DEFAULT_CHARSET : Charset.forName(request.getBodyEncoding());
205207

206-
if (request.getByteData() != null) {
208+
if (request.getByteData() != null)
207209
nettyBody = new NettyByteArrayBody(request.getByteData());
208210

209-
} else if (request.getStringData() != null) {
211+
else if (request.getCompositeByteData() != null)
212+
nettyBody = new NettyCompositeByteArrayBody(request.getCompositeByteData());
213+
214+
else if (request.getStringData() != null)
210215
nettyBody = new NettyByteArrayBody(request.getStringData().getBytes(bodyCharset));
211216

212-
} else if (request.getStreamData() != null) {
217+
else if (request.getStreamData() != null)
213218
nettyBody = new NettyInputStreamBody(request.getStreamData());
214219

215-
} else if (isNonEmpty(request.getFormParams())) {
220+
else if (isNonEmpty(request.getFormParams())) {
216221

217222
String contentType = null;
218223
if (!request.getHeaders().containsKey(HttpHeaders.Names.CONTENT_TYPE))
219224
contentType = HttpHeaders.Values.APPLICATION_X_WWW_FORM_URLENCODED;
220225

221226
nettyBody = new NettyByteArrayBody(computeBodyFromParams(request.getFormParams(), bodyCharset), contentType);
222227

223-
} else if (isNonEmpty(request.getParts())) {
228+
} else if (isNonEmpty(request.getParts()))
224229
nettyBody = new NettyMultipartBody(request.getParts(), request.getHeaders(), nettyConfig);
225230

226-
} else if (request.getFile() != null) {
231+
else if (request.getFile() != null)
227232
nettyBody = new NettyFileBody(request.getFile(), nettyConfig);
228233

229-
} else if (request.getBodyGenerator() instanceof FileBodyGenerator) {
234+
else if (request.getBodyGenerator() instanceof FileBodyGenerator) {
230235
FileBodyGenerator fileBodyGenerator = (FileBodyGenerator) request.getBodyGenerator();
231236
nettyBody = new NettyFileBody(fileBodyGenerator.getFile(), fileBodyGenerator.getRegionSeek(), fileBodyGenerator.getRegionLength(), nettyConfig);
232237

233-
} else if (request.getBodyGenerator() instanceof InputStreamBodyGenerator) {
238+
} else if (request.getBodyGenerator() instanceof InputStreamBodyGenerator)
234239
nettyBody = new NettyInputStreamBody(InputStreamBodyGenerator.class.cast(request.getBodyGenerator()).getInputStream());
235240

236-
} else if (request.getBodyGenerator() != null) {
241+
else if (request.getBodyGenerator() != null)
237242
nettyBody = new NettyBodyBody(request.getBodyGenerator().createBody(), nettyConfig);
238-
}
239243
}
240244

241245
return nettyBody;
@@ -262,9 +266,9 @@ public NettyRequest newNettyRequest(Request request, Uri uri, boolean forceConne
262266

263267
HttpRequest httpRequest;
264268
NettyRequest nettyRequest;
265-
if (body instanceof NettyByteArrayBody) {
266-
byte[] bytes = NettyByteArrayBody.class.cast(body).getBytes();
267-
httpRequest = new DefaultFullHttpRequest(httpVersion, method, requestUri, Unpooled.wrappedBuffer(bytes));
269+
if (body instanceof NettyDirectBody) {
270+
ByteBuf buf = NettyDirectBody.class.cast(body).byteBuf();
271+
httpRequest = new DefaultFullHttpRequest(httpVersion, method, requestUri, buf);
268272
// body is passed as null as it's written directly with the request
269273
nettyRequest = new NettyRequest(httpRequest, null);
270274

providers/netty4/src/main/java/org/asynchttpclient/providers/netty4/request/body/NettyByteArrayBody.java

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,11 @@
1313
*/
1414
package org.asynchttpclient.providers.netty4.request.body;
1515

16-
import org.asynchttpclient.AsyncHttpClientConfig;
17-
import org.asynchttpclient.providers.netty4.future.NettyResponseFuture;
16+
import io.netty.buffer.ByteBuf;
17+
import io.netty.buffer.Unpooled;
1818

19-
import io.netty.channel.Channel;
2019

21-
import java.io.IOException;
22-
23-
public class NettyByteArrayBody implements NettyBody {
20+
public class NettyByteArrayBody extends NettyDirectBody {
2421

2522
private final byte[] bytes;
2623
private final String contentType;
@@ -34,10 +31,6 @@ public NettyByteArrayBody(byte[] bytes, String contentType) {
3431
this.contentType = contentType;
3532
}
3633

37-
public byte[] getBytes() {
38-
return bytes;
39-
}
40-
4134
@Override
4235
public long getContentLength() {
4336
return bytes.length;
@@ -49,7 +42,7 @@ public String getContentType() {
4942
}
5043

5144
@Override
52-
public void write(Channel channel, NettyResponseFuture<?> future, AsyncHttpClientConfig config) throws IOException {
53-
throw new UnsupportedOperationException("This kind of body is supposed to be writen directly");
45+
public ByteBuf byteBuf() {
46+
return Unpooled.wrappedBuffer(bytes);
5447
}
5548
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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+
*/
14+
package org.asynchttpclient.providers.netty4.request.body;
15+
16+
import io.netty.buffer.ByteBuf;
17+
import io.netty.buffer.Unpooled;
18+
19+
import java.util.List;
20+
21+
public class NettyCompositeByteArrayBody extends NettyDirectBody {
22+
23+
private final byte[][] bytes;
24+
private final String contentType;
25+
private final long contentLength;
26+
27+
public NettyCompositeByteArrayBody(List<byte[]> bytes) {
28+
this(bytes, null);
29+
}
30+
31+
public NettyCompositeByteArrayBody(List<byte[]> bytes, String contentType) {
32+
this.bytes = new byte[bytes.size()][];
33+
bytes.toArray(this.bytes);
34+
this.contentType = contentType;
35+
long l = 0;
36+
for (byte[] b : bytes)
37+
l += b.length;
38+
contentLength = l;
39+
}
40+
41+
@Override
42+
public long getContentLength() {
43+
return contentLength;
44+
}
45+
46+
@Override
47+
public String getContentType() {
48+
return contentType;
49+
}
50+
51+
@Override
52+
public ByteBuf byteBuf() {
53+
return Unpooled.wrappedBuffer(bytes);
54+
}
55+
}

0 commit comments

Comments
 (0)