URI parser changes to support decoding of percentage encoded special characters
According to RFC8040, yang list node keys that contains specical
chararcters such as "/" or ":" are percentage encoded by the restconf
client when sending URIs to the restconf server.
I have made the changes accordingly on restconf server to pass
pass percentage encoded key strings to yang runtime. This submission
is to change the URI utility code to accordingly. With this submission,
restconf GET/POST operations will be able to support list nodes whose
keys contain "/" or ":".
Note that this submission does not depend on the restconf server
changes, and thus can be merged in directly.
Change-Id: I000e31ada9c4e0ad1f0196c45487b326e5a7741c
diff --git a/serializers/utils/src/main/java/org/onosproject/yang/serializers/utils/SerializersUtil.java b/serializers/utils/src/main/java/org/onosproject/yang/serializers/utils/SerializersUtil.java
index d728a2a..0c5ec1e 100644
--- a/serializers/utils/src/main/java/org/onosproject/yang/serializers/utils/SerializersUtil.java
+++ b/serializers/utils/src/main/java/org/onosproject/yang/serializers/utils/SerializersUtil.java
@@ -63,6 +63,8 @@
private static final String COMMA = ",";
private static final String COLON = ":";
private static final String SLASH = "/";
+ private static final String URI_ENCODED_SLASH = "%2F";
+ private static final String URI_ENCODED_COLON = "%3A";
// no instantiation
private SerializersUtil() {
@@ -201,15 +203,7 @@
private static void processSinglePathSegment(String pathSegment,
ResourceId.Builder builder) {
- String name = getPreSegment(pathSegment, EQUAL);
- if (name != null) {
- String c = getPreSegment(name, COLON);
- if (c == null) {
- processPathSegmentWithoutNamespace(pathSegment, builder);
- } else {
- // TODO
- }
- } else if (pathSegment.contains(COLON)) {
+ if (pathSegment.contains(COLON)) {
processPathSegmentWithNamespace(pathSegment, builder);
} else {
processPathSegmentWithoutNamespace(pathSegment, builder);
@@ -248,14 +242,41 @@
throw new SerializerUtilException(ERROR_LIST_MSG);
}
+ List<String> keys = uriDecodedKeys(keyStr);
+ SerializerHelper.addToResourceId(builder, nodeName, namespace, keys);
+ }
+
+ private static List<String> uriDecodedKeys(String keyStr) {
+ List<String> decodedKeys = Lists.newArrayList();
+
if (keyStr.contains(COMMA)) {
- List<String> keys = Lists.
- newArrayList(COMMA_SPLITTER.split(keyStr));
- SerializerHelper.addToResourceId(builder, nodeName, namespace, keys);
+ List<String> encodedKeys = Lists.newArrayList(COMMA_SPLITTER.split(keyStr));
+ for (String encodedKey : encodedKeys) {
+ decodedKeys.add(uriDecodedString(encodedKey));
+ }
} else {
- SerializerHelper.addToResourceId(builder, nodeName, namespace,
- Lists.newArrayList(keyStr));
+ decodedKeys.add(uriDecodedString(keyStr));
}
+
+ return decodedKeys;
+ }
+
+
+ private static String uriDecodedString(String keyStr) {
+ /*
+ * replaceAll() may be an expensive operation. So, call
+ * contains() to determine if replaceAll() is really need
+ * to be invoked.
+ */
+ if (keyStr.contains(URI_ENCODED_SLASH)) {
+ keyStr = keyStr.replaceAll(URI_ENCODED_SLASH, SLASH);
+ }
+ if (keyStr.contains(URI_ENCODED_COLON)) {
+ keyStr = keyStr.replaceAll(URI_ENCODED_COLON, COLON);
+ }
+ //TODO: need to decode other percentage encoded characters.
+
+ return keyStr;
}
private static void addLeaf(String nodeName,