diff --git a/google-http-client/src/main/java/com/google/api/client/http/UrlEncodedContent.java b/google-http-client/src/main/java/com/google/api/client/http/UrlEncodedContent.java index eb6428b18..ea08b1e18 100644 --- a/google-http-client/src/main/java/com/google/api/client/http/UrlEncodedContent.java +++ b/google-http-client/src/main/java/com/google/api/client/http/UrlEncodedContent.java @@ -42,20 +42,43 @@ * *
Implementation is not thread-safe.
*
- * @since 1.0
* @author Yaniv Inbar
+ * @since 1.0
*/
public class UrlEncodedContent extends AbstractHttpContent {
/** Key name/value data. */
private Object data;
- /** @param data key name/value data */
+ /** Use URI Path encoder flag. False by default (use legacy and deprecated escapeUri) */
+ private boolean uriPathEncodingFlag;
+
+ /**
+ * Initialize the UrlEncodedContent with the legacy and deprecated escapeUri encoder
+ *
+ * @param data key name/value data
+ */
public UrlEncodedContent(Object data) {
super(UrlEncodedParser.MEDIA_TYPE);
setData(data);
+ this.uriPathEncodingFlag = false;
}
+ /**
+ * Initialize the UrlEncodedContent with or without the legacy and deprecated escapeUri encoder
+ *
+ * @param data key name/value data
+ * @param useUriPathEncoding escapes the string value so it can be safely included in URI path
+ * segments. For details on escaping URIs, see RFC 3986 - section 2.4
+ */
+ public UrlEncodedContent(Object data, boolean useUriPathEncoding) {
+ super(UrlEncodedParser.MEDIA_TYPE);
+ setData(data);
+ this.uriPathEncodingFlag = useUriPathEncoding;
+ }
+
+ @Override
public void writeTo(OutputStream out) throws IOException {
Writer writer = new BufferedWriter(new OutputStreamWriter(out, getCharset()));
boolean first = true;
@@ -66,10 +89,10 @@ public void writeTo(OutputStream out) throws IOException {
Class extends Object> valueClass = value.getClass();
if (value instanceof Iterable> || valueClass.isArray()) {
for (Object repeatedValue : Types.iterableOf(value)) {
- first = appendParam(first, writer, name, repeatedValue);
+ first = appendParam(first, writer, name, repeatedValue, this.uriPathEncodingFlag);
}
} else {
- first = appendParam(first, writer, name, value);
+ first = appendParam(first, writer, name, value, this.uriPathEncodingFlag);
}
}
}
@@ -125,7 +148,8 @@ public static UrlEncodedContent getContent(HttpRequest request) {
return result;
}
- private static boolean appendParam(boolean first, Writer writer, String name, Object value)
+ private static boolean appendParam(
+ boolean first, Writer writer, String name, Object value, boolean uriPathEncodingFlag)
throws IOException {
// ignore nulls
if (value == null || Data.isNull(value)) {
@@ -139,8 +163,13 @@ private static boolean appendParam(boolean first, Writer writer, String name, Ob
}
writer.write(name);
String stringValue =
- CharEscapers.escapeUri(
- value instanceof Enum> ? FieldInfo.of((Enum>) value).getName() : value.toString());
+ value instanceof Enum> ? FieldInfo.of((Enum>) value).getName() : value.toString();
+
+ if (uriPathEncodingFlag) {
+ stringValue = CharEscapers.escapeUriPath(stringValue);
+ } else {
+ stringValue = CharEscapers.escapeUri(stringValue);
+ }
if (stringValue.length() != 0) {
writer.write("=");
writer.write(stringValue);
diff --git a/google-http-client/src/test/java/com/google/api/client/http/UrlEncodedContentTest.java b/google-http-client/src/test/java/com/google/api/client/http/UrlEncodedContentTest.java
index f0e0768a9..059d9e2c9 100644
--- a/google-http-client/src/test/java/com/google/api/client/http/UrlEncodedContentTest.java
+++ b/google-http-client/src/test/java/com/google/api/client/http/UrlEncodedContentTest.java
@@ -33,19 +33,32 @@
public class UrlEncodedContentTest extends TestCase {
public void testWriteTo() throws IOException {
- subtestWriteTo("a=x", ArrayMap.of("a", "x"));
- subtestWriteTo("noval", ArrayMap.of("noval", ""));
- subtestWriteTo("multi=a&multi=b&multi=c", ArrayMap.of("multi", Arrays.asList("a", "b", "c")));
- subtestWriteTo("multi=a&multi=b&multi=c", ArrayMap.of("multi", new String[] {"a", "b", "c"}));
+ subtestWriteTo("a=x", ArrayMap.of("a", "x"), false);
+ subtestWriteTo("noval", ArrayMap.of("noval", ""), false);
+ subtestWriteTo(
+ "multi=a&multi=b&multi=c", ArrayMap.of("multi", Arrays.asList("a", "b", "c")), false);
+ subtestWriteTo(
+ "multi=a&multi=b&multi=c", ArrayMap.of("multi", new String[] {"a", "b", "c"}), false);
// https://github.com/googleapis/google-http-java-client/issues/202
final Map