Skip to content

Commit 819b2df

Browse files
authored
Correct Encoding and restore decodeSlash in QueryTemplate (#1160)
Fixes #1156 Collection Format was encoding query string values unnecessarily due to changes introduced in #1138 and #1139 that encode template values before appending them to the query string. In addition, `decodeSlash` flags that were accidentally removed, have been restored in QueryTemplate. * Restoring decodeSlash in QueryTemplate * Correcting Readme with regards to decodeSlash usage
1 parent 49e1373 commit 819b2df

File tree

32 files changed

+98
-81
lines changed

32 files changed

+98
-81
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,8 @@ http://localhost:8080/test
216216
See [Advanced Usage](#advanced-usage) for more examples.
217217
218218
> **What about slashes? `/`**
219-
>
220-
> @RequestLine and @QueryMap Templates do encode slash `/` characters by default. To change this behavior, set the `decodeSlash` property on the `@RequestLine` to `true`.
219+
>
220+
> @RequestLine templates do not encode slash `/` characters by default. To change this behavior, set the `decodeSlash` property on the `@RequestLine` to `false`.
221221
222222
> **What about plus? `+`**
223223
>

benchmark/src/main/java/feign/benchmark/RealRequestBenchmarks.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2012-2019 The Feign Authors
2+
* Copyright 2012-2020 The Feign Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
55
* in compliance with the License. You may obtain a copy of the License at
@@ -20,17 +20,12 @@
2020
import feign.Logger.Level;
2121
import feign.Response;
2222
import feign.Retryer;
23-
import io.reactivex.netty.protocol.http.HttpHandlerNames;
2423
import io.reactivex.netty.protocol.http.server.HttpServer;
25-
import io.reactivex.netty.protocol.http.server.HttpServerRequest;
26-
import io.reactivex.netty.protocol.http.server.HttpServerResponse;
27-
import io.reactivex.netty.protocol.http.server.RequestHandler;
2824
import java.io.IOException;
2925
import java.util.concurrent.TimeUnit;
3026
import io.netty.buffer.ByteBuf;
3127
import okhttp3.OkHttpClient;
3228
import okhttp3.Request;
33-
import okhttp3.internal.http.HttpHeaders;
3429
import org.openjdk.jmh.annotations.Benchmark;
3530
import org.openjdk.jmh.annotations.BenchmarkMode;
3631
import org.openjdk.jmh.annotations.Fork;
@@ -42,7 +37,6 @@
4237
import org.openjdk.jmh.annotations.State;
4338
import org.openjdk.jmh.annotations.TearDown;
4439
import org.openjdk.jmh.annotations.Warmup;
45-
import rx.Observable;
4640

4741
@Measurement(iterations = 5, time = 1)
4842
@Warmup(iterations = 10, time = 1)

core/src/main/java/feign/Client.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import static feign.Util.ENCODING_GZIP;
2020
import static feign.Util.checkArgument;
2121
import static feign.Util.checkNotNull;
22-
import static feign.Util.isBlank;
2322
import static feign.Util.isNotBlank;
2423
import static java.lang.String.format;
2524
import java.io.IOException;

core/src/main/java/feign/CollectionFormat.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2012-2019 The Feign Authors
2+
* Copyright 2012-2020 The Feign Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
55
* in compliance with the License. You may obtain a copy of the License at
@@ -77,7 +77,7 @@ public CharSequence join(String field, Collection<String> values, Charset charse
7777
builder.append(UriUtils.encode(field, charset));
7878
if (value != null) {
7979
builder.append('=');
80-
builder.append(UriUtils.encode(value, charset));
80+
builder.append(value);
8181
}
8282
} else {
8383
// delimited with a separator character
@@ -87,8 +87,8 @@ public CharSequence join(String field, Collection<String> values, Charset charse
8787
if (value == null) {
8888
continue;
8989
}
90-
builder.append(valueCount++ == 0 ? "=" : separator);
91-
builder.append(UriUtils.encode(value, charset));
90+
builder.append(valueCount++ == 0 ? "=" : UriUtils.encode(separator, charset));
91+
builder.append(value);
9292
}
9393
}
9494
return builder;

core/src/main/java/feign/RequestTemplate.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,13 @@ public RequestTemplate decodeSlash(boolean decodeSlash) {
327327
this.decodeSlash = decodeSlash;
328328
this.uriTemplate =
329329
UriTemplate.create(this.uriTemplate.toString(), !this.decodeSlash, this.charset);
330+
if (!this.queries.isEmpty()) {
331+
this.queries.replaceAll((key, queryTemplate) -> QueryTemplate.create(
332+
/* replace the current template with new ones honoring the decode value */
333+
queryTemplate.getName(), queryTemplate.getValues(), charset, collectionFormat,
334+
decodeSlash));
335+
336+
}
330337
return this;
331338
}
332339

@@ -636,9 +643,9 @@ private RequestTemplate appendQuery(String name,
636643
/* create a new query template out of the information here */
637644
this.queries.compute(name, (key, queryTemplate) -> {
638645
if (queryTemplate == null) {
639-
return QueryTemplate.create(name, values, this.charset, collectionFormat);
646+
return QueryTemplate.create(name, values, this.charset, collectionFormat, this.decodeSlash);
640647
} else {
641-
return QueryTemplate.append(queryTemplate, values, collectionFormat);
648+
return QueryTemplate.append(queryTemplate, values, collectionFormat, this.decodeSlash);
642649
}
643650
});
644651
return this;

core/src/main/java/feign/Types.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2012-2019 The Feign Authors
2+
* Copyright 2012-2020 The Feign Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
55
* in compliance with the License. You may obtain a copy of the License at
@@ -21,7 +21,6 @@
2121
import java.lang.reflect.TypeVariable;
2222
import java.lang.reflect.WildcardType;
2323
import java.util.Arrays;
24-
import java.util.Map;
2524
import java.util.NoSuchElementException;
2625

2726
/**

core/src/main/java/feign/Util.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2012-2019 The Feign Authors
2+
* Copyright 2012-2020 The Feign Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
55
* in compliance with the License. You may obtain a copy of the License at
@@ -37,7 +37,6 @@
3737
import java.util.LinkedHashMap;
3838
import java.util.List;
3939
import java.util.Map;
40-
import java.util.NoSuchElementException;
4140
import java.util.Optional;
4241
import java.util.Set;
4342
import java.util.function.Predicate;

core/src/main/java/feign/stream/StreamDecoder.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2012-2019 The Feign Authors
2+
* Copyright 2012-2020 The Feign Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
55
* in compliance with the License. You may obtain a copy of the License at
@@ -21,7 +21,6 @@
2121
import java.lang.reflect.ParameterizedType;
2222
import java.lang.reflect.Type;
2323
import java.util.Iterator;
24-
import java.util.Spliterator;
2524
import java.util.Spliterators;
2625
import java.util.stream.Stream;
2726
import java.util.stream.StreamSupport;

core/src/main/java/feign/template/Expression.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2012-2019 The Feign Authors
2+
* Copyright 2012-2020 The Feign Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
55
* in compliance with the License. You may obtain a copy of the License at
@@ -13,7 +13,6 @@
1313
*/
1414
package feign.template;
1515

16-
import feign.CollectionFormat;
1716
import java.util.Optional;
1817
import java.util.regex.Pattern;
1918

core/src/main/java/feign/template/QueryTemplate.java

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2012-2019 The Feign Authors
2+
* Copyright 2012-2020 The Feign Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
55
* in compliance with the License. You may obtain a copy of the License at
@@ -13,6 +13,10 @@
1313
*/
1414
package feign.template;
1515

16+
import feign.CollectionFormat;
17+
import feign.Util;
18+
import feign.template.Template.EncodingOptions;
19+
import feign.template.Template.ExpansionOptions;
1620
import java.nio.charset.Charset;
1721
import java.nio.charset.StandardCharsets;
1822
import java.util.ArrayList;
@@ -24,10 +28,6 @@
2428
import java.util.concurrent.CopyOnWriteArrayList;
2529
import java.util.stream.Collectors;
2630
import java.util.stream.StreamSupport;
27-
import feign.CollectionFormat;
28-
import feign.Util;
29-
import feign.template.Template.EncodingOptions;
30-
import feign.template.Template.ExpansionOptions;
3131

3232
/**
3333
* Template for a Query String parameter.
@@ -49,7 +49,14 @@ public final class QueryTemplate {
4949
* @return a QueryTemplate.
5050
*/
5151
public static QueryTemplate create(String name, Iterable<String> values, Charset charset) {
52-
return create(name, values, charset, CollectionFormat.EXPLODED);
52+
return create(name, values, charset, CollectionFormat.EXPLODED, true);
53+
}
54+
55+
public static QueryTemplate create(String name,
56+
Iterable<String> values,
57+
Charset charset,
58+
CollectionFormat collectionFormat) {
59+
return create(name, values, charset, collectionFormat, true);
5360
}
5461

5562
/**
@@ -59,12 +66,14 @@ public static QueryTemplate create(String name, Iterable<String> values, Charset
5966
* @param values in the template.
6067
* @param charset for the template.
6168
* @param collectionFormat to use.
69+
* @param decodeSlash if slash characters should be decoded
6270
* @return a QueryTemplate
6371
*/
6472
public static QueryTemplate create(String name,
6573
Iterable<String> values,
6674
Charset charset,
67-
CollectionFormat collectionFormat) {
75+
CollectionFormat collectionFormat,
76+
boolean decodeSlash) {
6877
if (Util.isBlank(name)) {
6978
throw new IllegalArgumentException("name is required.");
7079
}
@@ -78,7 +87,7 @@ public static QueryTemplate create(String name,
7887
.filter(Util::isNotBlank)
7988
.collect(Collectors.toList());
8089

81-
return new QueryTemplate(name, remaining, charset, collectionFormat);
90+
return new QueryTemplate(name, remaining, charset, collectionFormat, decodeSlash);
8291
}
8392

8493
/**
@@ -90,13 +99,14 @@ public static QueryTemplate create(String name,
9099
*/
91100
public static QueryTemplate append(QueryTemplate queryTemplate,
92101
Iterable<String> values,
93-
CollectionFormat collectionFormat) {
102+
CollectionFormat collectionFormat,
103+
boolean decodeSlash) {
94104
List<String> queryValues = new ArrayList<>(queryTemplate.getValues());
95105
queryValues.addAll(StreamSupport.stream(values.spliterator(), false)
96106
.filter(Util::isNotBlank)
97107
.collect(Collectors.toList()));
98108
return create(queryTemplate.getName(), queryValues, StandardCharsets.UTF_8,
99-
collectionFormat);
109+
collectionFormat, decodeSlash);
100110
}
101111

102112
/**
@@ -110,10 +120,11 @@ private QueryTemplate(
110120
String name,
111121
Iterable<String> values,
112122
Charset charset,
113-
CollectionFormat collectionFormat) {
123+
CollectionFormat collectionFormat,
124+
boolean decodeSlash) {
114125
this.values = new CopyOnWriteArrayList<>();
115126
this.name = new Template(name, ExpansionOptions.ALLOW_UNRESOLVED, EncodingOptions.REQUIRED,
116-
false, charset);
127+
!decodeSlash, charset);
117128
this.collectionFormat = collectionFormat;
118129

119130
/* parse each value into a template chunk for resolution later */
@@ -128,7 +139,7 @@ private QueryTemplate(
128139
value,
129140
ExpansionOptions.REQUIRED,
130141
EncodingOptions.REQUIRED,
131-
false,
142+
!decodeSlash,
132143
charset));
133144
}
134145

0 commit comments

Comments
 (0)