Codebase list async-http-client / d63afff
New upstream version 1.9.24 Emmanuel Bourg 5 years ago
12 changed file(s) with 229 addition(s) and 170 deletion(s). Raw diff Collapse all Expand all
88 <groupId>com.ning</groupId>
99 <artifactId>async-http-client</artifactId>
1010 <name>Asynchronous Http Client</name>
11 <version>1.9.23</version>
11 <version>1.9.24</version>
1212 <packaging>jar</packaging>
1313 <description>
1414 Async Http Client library purpose is to allow Java applications to easily execute HTTP requests and
1616
1717 import com.ning.http.client.cookie.Cookie;
1818 import com.ning.http.client.multipart.Part;
19 import com.ning.http.util.QueryComputer;
19 import com.ning.http.util.UriEncoder;
2020
2121 import java.io.InputStream;
2222 import java.util.Collection;
4242 super(RequestBuilder.class, method, disableUrlEncoding);
4343 }
4444
45 public RequestBuilder(String method, QueryComputer queryComputer) {
46 super(RequestBuilder.class, method, queryComputer);
45 public RequestBuilder(String method, UriEncoder uriEncoder) {
46 super(RequestBuilder.class, method, uriEncoder);
4747 }
4848
4949 public RequestBuilder(Request prototype) {
5050 super(RequestBuilder.class, prototype);
5151 }
5252
53 public RequestBuilder(Request prototype, QueryComputer queryComputer) {
54 super(RequestBuilder.class, prototype, queryComputer);
53 public RequestBuilder(Request prototype, UriEncoder uriEncoder) {
54 super(RequestBuilder.class, prototype, uriEncoder);
5555 }
5656
5757 // Note: For now we keep the delegates in place even though they are not needed
2323 import com.ning.http.client.multipart.Part;
2424 import com.ning.http.client.uri.Uri;
2525 import com.ning.http.util.AsyncHttpProviderUtils;
26 import com.ning.http.util.QueryComputer;
26 import com.ning.http.util.UriEncoder;
2727
2828 import java.io.File;
2929 import java.io.InputStream;
277277
278278 private final Class<T> derived;
279279 protected final RequestImpl request;
280 protected QueryComputer queryComputer;
280 protected UriEncoder uriEncoder;
281281 protected List<Param> queryParams;
282282 protected SignatureCalculator signatureCalculator;
283283
284284 protected RequestBuilderBase(Class<T> derived, String method, boolean disableUrlEncoding) {
285 this(derived, method, QueryComputer.queryComputer(disableUrlEncoding));
286 }
287
288 protected RequestBuilderBase(Class<T> derived, String method, QueryComputer queryComputer) {
285 this(derived, method, UriEncoder.uriEncoder(disableUrlEncoding));
286 }
287
288 protected RequestBuilderBase(Class<T> derived, String method, UriEncoder uriEncoder) {
289289 this.derived = derived;
290290 request = new RequestImpl();
291291 request.method = method;
292 this.queryComputer = queryComputer;
292 this.uriEncoder = uriEncoder;
293293 }
294294
295295 protected RequestBuilderBase(Class<T> derived, Request prototype) {
296 this(derived, prototype, QueryComputer.URL_ENCODING_ENABLED_QUERY_COMPUTER);
297 }
298
299 protected RequestBuilderBase(Class<T> derived, Request prototype, QueryComputer queryComputer) {
296 this(derived, prototype, UriEncoder.FIXING);
297 }
298
299 protected RequestBuilderBase(Class<T> derived, Request prototype, UriEncoder uriEncoder) {
300300 this.derived = derived;
301301 request = new RequestImpl(prototype);
302 this.queryComputer = queryComputer;
302 this.uriEncoder = uriEncoder;
303303 }
304304
305305 public T setUrl(String url) {
626626
627627 private void computeFinalUri() {
628628
629 if (request.uri == null) {
629 Uri originalUri = request.uri;
630 if (originalUri == null) {
630631 logger.debug("setUrl hasn't been invoked. Using {}", DEFAULT_REQUEST_URL);
631632 request.uri = DEFAULT_REQUEST_URL;
632633 }
633634
634 AsyncHttpProviderUtils.validateSupportedScheme(request.uri);
635
636 String newQuery = queryComputer.computeFullQueryString(request.uri.getQuery(), queryParams);
637 request.uri = request.uri.withNewQuery(newQuery);
635 AsyncHttpProviderUtils.validateSupportedScheme(originalUri);
636
637 request.uri = uriEncoder.encode(originalUri, queryParams);
638638 }
639639
640640 public Request build() {
1414 import static com.ning.http.util.MiscUtils.isNonEmpty;
1515 import static java.nio.charset.StandardCharsets.US_ASCII;
1616
17 import com.ning.http.client.FluentStringsMap;
1817 import com.ning.http.client.Param;
1918
2019 import java.io.IOException;
2120 import java.io.OutputStream;
2221 import java.nio.charset.Charset;
22 import java.util.ArrayList;
23 import java.util.List;
2324
2425 public abstract class PartBase implements Part {
2526
5657 /**
5758 * Additional part headers
5859 */
59 private FluentStringsMap customHeaders;
60 private List<Param> customHeaders;
6061
6162 public PartBase(String name, String contentType, Charset charset, String contentId) {
6263 this(name, contentType, charset, contentId, null);
130131
131132 protected void visitCustomHeaders(PartVisitor visitor) throws IOException {
132133 if (isNonEmpty(customHeaders)) {
133 for (Param param: customHeaders.toParams()) {
134 for (Param param: customHeaders) {
134135 visitor.withBytes(CRLF_BYTES);
135136 visitor.withBytes(param.getName().getBytes(US_ASCII));
136137 visitor.withBytes(param.getValue().getBytes(US_ASCII));
254255
255256 public void addCustomHeader(String name, String value) {
256257 if (customHeaders == null) {
257 customHeaders = new FluentStringsMap();
258 }
259 customHeaders.add(name, value);
258 customHeaders = new ArrayList<Param>(2);
259 }
260 customHeaders.add(new Param(name, value));
261 }
262
263 public void setCustomHeaders(List<Param> customHeaders) {
264 this.customHeaders = customHeaders;
260265 }
261266 }
229229 }
230230
231231 public OAuthParameterSet add(String key, String value) {
232 Parameter p = new Parameter(UTF8UrlEncoder.encode(key), UTF8UrlEncoder.encode(value));
232 Parameter p = new Parameter(UTF8UrlEncoder.encodeQueryElement(key), UTF8UrlEncoder.encodeQueryElement(value));
233233 allParameters.add(p);
234234 return this;
235235 }
6464
6565 private void writeRequest(Channel channel) {
6666
67 LOGGER.debug("Request using non cached Channel '{}':\n{}\n", channel, future.getNettyRequest().getHttpRequest());
67 LOGGER.debug("Using non-cached Channel {} for {} '{}'",
68 channel,
69 future.getNettyRequest().getHttpRequest().getMethod(),
70 future.getNettyRequest().getHttpRequest().getUri());
6871
6972 Channels.setAttribute(channel, future);
7073
204204 future.setState(NettyResponseFuture.STATE.POOLED);
205205 future.attachChannel(channel, false);
206206
207 LOGGER.debug("Using cached Channel {}\n for request \n{}\n", channel, future.getNettyRequest().getHttpRequest());
207 LOGGER.debug("Using cached Channel {} for {} '{}'",
208 channel,
209 future.getNettyRequest().getHttpRequest().getMethod(),
210 future.getNettyRequest().getHttpRequest().getUri());
208211
209212 if (Channels.isChannelValid(channel)) {
210213 Channels.setAttribute(channel, future);
8585 }
8686 }
8787
88 @SuppressWarnings("resource")
8988 public final static InputStream contentToInputStream(List<HttpResponseBodyPart> bodyParts) throws UnsupportedEncodingException {
9089 return bodyParts.isEmpty() ? new ByteArrayInputStream(EMPTY_BYTE_ARRAY) : new HttpResponseBodyPartsInputStream(bodyParts);
9190 }
191190 }
192191 sb.append('&');
193192 }
194
195 public static void encodeAndAppendQueryParam(final StringBuilder sb, final CharSequence name, final CharSequence value) {
196 UTF8UrlEncoder.encodeAndAppendQueryElement(sb, name);
197 if (value != null) {
198 sb.append('=');
199 UTF8UrlEncoder.encodeAndAppendQueryElement(sb, value);
200 }
201 sb.append('&');
202 }
203193 }
+0
-115
src/main/java/com/ning/http/util/QueryComputer.java less more
0 /*
1 * Copyright (c) 2014 AsyncHttpClient Project. All rights reserved.
2 *
3 * This program is licensed to you under the Apache License Version 2.0,
4 * and you may not use this file except in compliance with the Apache License Version 2.0.
5 * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
6 *
7 * Unless required by applicable law or agreed to in writing,
8 * software distributed under the Apache License Version 2.0 is distributed on an
9 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
11 */
12 package com.ning.http.util;
13
14 import static com.ning.http.util.MiscUtils.isNonEmpty;
15 import static com.ning.http.util.AsyncHttpProviderUtils.encodeAndAppendQueryParam;
16 import static com.ning.http.util.UTF8UrlEncoder.encodeAndAppendQuery;
17 import com.ning.http.client.Param;
18
19 import java.util.List;
20
21 public enum QueryComputer {
22
23 URL_ENCODING_ENABLED_QUERY_COMPUTER {
24
25 private final void encodeAndAppendQueryParams(final StringBuilder sb, final List<Param> queryParams) {
26 for (Param param : queryParams)
27 encodeAndAppendQueryParam(sb, param.getName(), param.getValue());
28 }
29
30 protected final String withQueryWithParams(final String query, final List<Param> queryParams) {
31 // concatenate encoded query + encoded query params
32 StringBuilder sb = StringUtils.stringBuilder();
33 encodeAndAppendQuery(sb, query);
34 sb.append('&');
35 encodeAndAppendQueryParams(sb, queryParams);
36 sb.setLength(sb.length() - 1);
37 return sb.toString();
38 }
39
40 protected final String withQueryWithoutParams(final String query) {
41 // encode query
42 StringBuilder sb = StringUtils.stringBuilder();
43 encodeAndAppendQuery(sb, query);
44 return sb.toString();
45 }
46
47 protected final String withoutQueryWithParams(final List<Param> queryParams) {
48 // concatenate encoded query params
49 StringBuilder sb = StringUtils.stringBuilder();
50 encodeAndAppendQueryParams(sb, queryParams);
51 sb.setLength(sb.length() - 1);
52 return sb.toString();
53 }
54 }, //
55
56 URL_ENCODING_DISABLED_QUERY_COMPUTER {
57
58 private final void appendRawQueryParam(StringBuilder sb, String name, String value) {
59 sb.append(name);
60 if (value != null)
61 sb.append('=').append(value);
62 sb.append('&');
63 }
64
65 private final void appendRawQueryParams(final StringBuilder sb, final List<Param> queryParams) {
66 for (Param param : queryParams)
67 appendRawQueryParam(sb, param.getName(), param.getValue());
68 }
69
70 protected final String withQueryWithParams(final String query, final List<Param> queryParams) {
71 // concatenate raw query + raw query params
72 StringBuilder sb = StringUtils.stringBuilder();
73 sb.append(query);
74 appendRawQueryParams(sb, queryParams);
75 sb.setLength(sb.length() - 1);
76 return sb.toString();
77 }
78
79 protected final String withQueryWithoutParams(final String query) {
80 // return raw query as is
81 return query;
82 }
83
84 protected final String withoutQueryWithParams(final List<Param> queryParams) {
85 // concatenate raw queryParams
86 StringBuilder sb = StringUtils.stringBuilder();
87 appendRawQueryParams(sb, queryParams);
88 sb.setLength(sb.length() - 1);
89 return sb.toString();
90 }
91 };
92
93 public static QueryComputer queryComputer(boolean disableUrlEncoding) {
94 return disableUrlEncoding ? URL_ENCODING_DISABLED_QUERY_COMPUTER : URL_ENCODING_ENABLED_QUERY_COMPUTER;
95 }
96
97 protected abstract String withQueryWithParams(final String query, final List<Param> queryParams);
98
99 protected abstract String withQueryWithoutParams(final String query);
100
101 protected abstract String withoutQueryWithParams(final List<Param> queryParams);
102
103 private final String withQuery(final String query, final List<Param> queryParams) {
104 return isNonEmpty(queryParams) ? withQueryWithParams(query, queryParams) : withQueryWithoutParams(query);
105 }
106
107 private final String withoutQuery(final List<Param> queryParams) {
108 return isNonEmpty(queryParams) ? withoutQueryWithParams(queryParams) : null;
109 }
110
111 public final String computeFullQueryString(final String query, final List<Param> queryParams) {
112 return isNonEmpty(query) ? withQuery(query, queryParams) : withoutQuery(queryParams);
113 }
114 }
2828 */
2929 public final static BitSet RFC3986_UNRESERVED_CHARS = new BitSet(256);
3030 public final static BitSet RFC3986_RESERVED_CHARS = new BitSet(256);
31 public final static BitSet RFC3986_SUBDELIM_CHARS = new BitSet(256);
32 public final static BitSet BUILT_PATH_UNTOUCHED_CHARS = new BitSet(256);
3133 public final static BitSet BUILT_QUERY_UNTOUCHED_CHARS = new BitSet(256);
3234 // http://www.w3.org/TR/html5/forms.html#application/x-www-form-urlencoded-encoding-algorithm
3335 public final static BitSet FORM_URL_ENCODED_SAFE_CHARS = new BitSet(256);
5052 RFC3986_UNRESERVED_CHARS.set('_');
5153 RFC3986_UNRESERVED_CHARS.set('~');
5254
55 RFC3986_SUBDELIM_CHARS.set('!');
56 RFC3986_SUBDELIM_CHARS.set('$');
57 RFC3986_SUBDELIM_CHARS.set('&');
58 RFC3986_SUBDELIM_CHARS.set('\'');
59 RFC3986_SUBDELIM_CHARS.set('(');
60 RFC3986_SUBDELIM_CHARS.set(')');
61 RFC3986_SUBDELIM_CHARS.set('*');
62 RFC3986_SUBDELIM_CHARS.set('+');
63 RFC3986_SUBDELIM_CHARS.set(',');
64 RFC3986_SUBDELIM_CHARS.set(';');
65 RFC3986_SUBDELIM_CHARS.set('=');
66
5367 FORM_URL_ENCODED_SAFE_CHARS.set('-');
5468 FORM_URL_ENCODED_SAFE_CHARS.set('.');
5569 FORM_URL_ENCODED_SAFE_CHARS.set('_');
7387 RFC3986_RESERVED_CHARS.set('#');
7488 RFC3986_RESERVED_CHARS.set('[');
7589 RFC3986_RESERVED_CHARS.set(']');
76
90
91 BUILT_PATH_UNTOUCHED_CHARS.or(RFC3986_UNRESERVED_CHARS);
92 BUILT_PATH_UNTOUCHED_CHARS.set('%');
93 BUILT_PATH_UNTOUCHED_CHARS.or(RFC3986_SUBDELIM_CHARS);
94 BUILT_PATH_UNTOUCHED_CHARS.set(':');
95 BUILT_PATH_UNTOUCHED_CHARS.set('@');
96 BUILT_PATH_UNTOUCHED_CHARS.set('/');
97
7798 BUILT_QUERY_UNTOUCHED_CHARS.or(RFC3986_UNRESERVED_CHARS);
7899 BUILT_QUERY_UNTOUCHED_CHARS.or(RFC3986_RESERVED_CHARS);
79100 BUILT_QUERY_UNTOUCHED_CHARS.set('%');
84105 private UTF8UrlEncoder() {
85106 }
86107
87 public static String encode(String input) {
88 StringBuilder sb = new StringBuilder(input.length() + 16);
108 public static String encodePath(String input) {
109 StringBuilder sb = new StringBuilder(input.length() + 6);
110 appendEncoded(sb, input, BUILT_PATH_UNTOUCHED_CHARS, false);
111 return sb.toString();
112 }
113
114 public static StringBuilder encodeAndAppendQuery(StringBuilder sb, String query) {
115 return appendEncoded(sb, query, BUILT_QUERY_UNTOUCHED_CHARS, false);
116 }
117
118 public static String encodeQueryElement(String input) {
119 StringBuilder sb = new StringBuilder(input.length() + 6);
89120 encodeAndAppendQueryElement(sb, input);
90121 return sb.toString();
91 }
92
93 public static StringBuilder encodeAndAppendQuery(StringBuilder sb, String query) {
94 return appendEncoded(sb, query, BUILT_QUERY_UNTOUCHED_CHARS, false);
95122 }
96123
97124 public static StringBuilder encodeAndAppendQueryElement(StringBuilder sb, CharSequence input) {
0 /*
1 * Copyright (c) 2014 AsyncHttpClient Project. All rights reserved.
2 *
3 * This program is licensed to you under the Apache License Version 2.0,
4 * and you may not use this file except in compliance with the Apache License Version 2.0.
5 * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
6 *
7 * Unless required by applicable law or agreed to in writing,
8 * software distributed under the Apache License Version 2.0 is distributed on an
9 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
11 */
12 package com.ning.http.util;
13
14 import static com.ning.http.util.MiscUtils.isNonEmpty;
15 import static com.ning.http.util.UTF8UrlEncoder.encodeAndAppendQuery;
16
17 import com.ning.http.client.Param;
18 import com.ning.http.client.uri.Uri;
19
20 import java.util.List;
21
22 public enum UriEncoder {
23
24 FIXING {
25
26 public String encodePath(String path) {
27 return UTF8UrlEncoder.encodePath(path);
28 }
29
30 private void encodeAndAppendQueryParam(final StringBuilder sb, final CharSequence name, final CharSequence value) {
31 UTF8UrlEncoder.encodeAndAppendQueryElement(sb, name);
32 if (value != null) {
33 sb.append('=');
34 UTF8UrlEncoder.encodeAndAppendQueryElement(sb, value);
35 }
36 sb.append('&');
37 }
38
39 private void encodeAndAppendQueryParams(final StringBuilder sb, final List<Param> queryParams) {
40 for (Param param : queryParams)
41 encodeAndAppendQueryParam(sb, param.getName(), param.getValue());
42 }
43
44 protected String withQueryWithParams(final String query, final List<Param> queryParams) {
45 // concatenate encoded query + encoded query params
46 StringBuilder sb = StringUtils.stringBuilder();
47 encodeAndAppendQuery(sb, query);
48 sb.append('&');
49 encodeAndAppendQueryParams(sb, queryParams);
50 sb.setLength(sb.length() - 1);
51 return sb.toString();
52 }
53
54 protected String withQueryWithoutParams(final String query) {
55 // encode query
56 StringBuilder sb = StringUtils.stringBuilder();
57 encodeAndAppendQuery(sb, query);
58 return sb.toString();
59 }
60
61 protected String withoutQueryWithParams(final List<Param> queryParams) {
62 // concatenate encoded query params
63 StringBuilder sb = StringUtils.stringBuilder();
64 encodeAndAppendQueryParams(sb, queryParams);
65 sb.setLength(sb.length() - 1);
66 return sb.toString();
67 }
68 }, //
69
70 RAW {
71
72 public String encodePath(String path) {
73 return path;
74 }
75
76 private void appendRawQueryParam(StringBuilder sb, String name, String value) {
77 sb.append(name);
78 if (value != null)
79 sb.append('=').append(value);
80 sb.append('&');
81 }
82
83 private void appendRawQueryParams(final StringBuilder sb, final List<Param> queryParams) {
84 for (Param param : queryParams)
85 appendRawQueryParam(sb, param.getName(), param.getValue());
86 }
87
88 protected String withQueryWithParams(final String query, final List<Param> queryParams) {
89 // concatenate raw query + raw query params
90 StringBuilder sb = StringUtils.stringBuilder();
91 sb.append(query);
92 appendRawQueryParams(sb, queryParams);
93 sb.setLength(sb.length() - 1);
94 return sb.toString();
95 }
96
97 protected String withQueryWithoutParams(final String query) {
98 // return raw query as is
99 return query;
100 }
101
102 protected String withoutQueryWithParams(final List<Param> queryParams) {
103 // concatenate raw queryParams
104 StringBuilder sb = StringUtils.stringBuilder();
105 appendRawQueryParams(sb, queryParams);
106 sb.setLength(sb.length() - 1);
107 return sb.toString();
108 }
109 };
110
111 public static UriEncoder uriEncoder(boolean disableUrlEncoding) {
112 return disableUrlEncoding ? RAW : FIXING;
113 }
114
115 protected abstract String withQueryWithParams(final String query, final List<Param> queryParams);
116
117 protected abstract String withQueryWithoutParams(final String query);
118
119 protected abstract String withoutQueryWithParams(final List<Param> queryParams);
120
121 private final String withQuery(final String query, final List<Param> queryParams) {
122 return isNonEmpty(queryParams) ? withQueryWithParams(query, queryParams) : withQueryWithoutParams(query);
123 }
124
125 private final String withoutQuery(final List<Param> queryParams) {
126 return isNonEmpty(queryParams) ? withoutQueryWithParams(queryParams) : null;
127 }
128
129 public Uri encode(Uri uri, List<Param> queryParams) {
130 String newPath = encodePath(uri.getPath());
131 String newQuery = encodeQuery(uri.getQuery(), queryParams);
132 return new Uri(uri.getScheme(),//
133 uri.getUserInfo(),//
134 uri.getHost(),//
135 uri.getPort(),//
136 newPath,//
137 newQuery);
138 }
139
140 protected abstract String encodePath(String path);
141
142 private final String encodeQuery(final String query, final List<Param> queryParams) {
143 return isNonEmpty(query) ? withQuery(query, queryParams) : withoutQuery(queryParams);
144 }
145 }
2121
2222 @Test(groups = "fast")
2323 public void testBasics() {
24 Assert.assertEquals(UTF8UrlEncoder.encode("foobar"), "foobar");
25 Assert.assertEquals(UTF8UrlEncoder.encode("a&b"), "a%26b");
26 Assert.assertEquals(UTF8UrlEncoder.encode("a+b"), "a%2Bb");
24 Assert.assertEquals(UTF8UrlEncoder.encodeQueryElement("foobar"), "foobar");
25 Assert.assertEquals(UTF8UrlEncoder.encodeQueryElement("a&b"), "a%26b");
26 Assert.assertEquals(UTF8UrlEncoder.encodeQueryElement("a+b"), "a%2Bb");
2727 }
2828
2929 @Test(groups = "fast")
3030 public void testNonBmp() {
3131 // Plane 1
32 Assert.assertEquals(UTF8UrlEncoder.encode("\uD83D\uDCA9"), "%F0%9F%92%A9");
32 Assert.assertEquals(UTF8UrlEncoder.encodeQueryElement("\uD83D\uDCA9"), "%F0%9F%92%A9");
3333 // Plane 2
34 Assert.assertEquals(UTF8UrlEncoder.encode("\ud84c\uddc8 \ud84f\udfef"), "%F0%A3%87%88%20%F0%A3%BF%AF");
34 Assert.assertEquals(UTF8UrlEncoder.encodeQueryElement("\ud84c\uddc8 \ud84f\udfef"), "%F0%A3%87%88%20%F0%A3%BF%AF");
3535 // Plane 15
36 Assert.assertEquals(UTF8UrlEncoder.encode("\udb80\udc01"), "%F3%B0%80%81");
36 Assert.assertEquals(UTF8UrlEncoder.encodeQueryElement("\udb80\udc01"), "%F3%B0%80%81");
3737 }
3838
3939 @Test(groups = "fast")