Skip to content

Commit

Permalink
Merge pull request #840 from HubSpot/url-decode-filter
Browse files Browse the repository at this point in the history
Add URL decode filter
  • Loading branch information
mattcoley authored Apr 6, 2022
2 parents 1d93ab4 + 144f7fc commit 5736b70
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ protected void registerDefaults() {
ForceEscapeFilter.class,
StripTagsFilter.class,
UrlEncodeFilter.class,
UrlDecodeFilter.class,
XmlAttrFilter.class,
EscapeJsonFilter.class,
EscapeJinjavaFilter.class,
Expand Down
75 changes: 75 additions & 0 deletions src/main/java/com/hubspot/jinjava/lib/filter/UrlDecodeFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.hubspot.jinjava.lib.filter;

import com.hubspot.jinjava.doc.annotations.JinjavaDoc;
import com.hubspot.jinjava.doc.annotations.JinjavaParam;
import com.hubspot.jinjava.doc.annotations.JinjavaSnippet;
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.apache.commons.lang3.StringUtils;

@JinjavaDoc(
value = "Decodes encoded URL strings back to the original URL. It accepts both dictionaries and regular strings as well as pairwise iterables.",
input = @JinjavaParam(
value = "url",
type = "string",
desc = "the url to decode",
required = true
),
snippets = {
@JinjavaSnippet(
code = "{{ \"http%3A%2F%2Ffoo.com%3Fbar%26food\"|urldecode }}",
output = "http://foo.com?bar&food"
)
}
)
public class UrlDecodeFilter implements Filter {

@Override
public String getName() {
return "urldecode";
}

@Override
public Object filter(Object var, JinjavaInterpreter interpreter, String... args) {
if (var == null && args.length == 0) {
return "";
}

if (var != null) {
if (Map.class.isAssignableFrom(var.getClass())) {
@SuppressWarnings("unchecked")
Map<Object, Object> dict = (Map<Object, Object>) var;

List<String> paramPairs = new ArrayList<>();

for (Map.Entry<Object, Object> param : dict.entrySet()) {
StringBuilder paramPair = new StringBuilder();
paramPair.append(urlDecode(Objects.toString(param.getKey())));
paramPair.append("=");
paramPair.append(urlDecode(Objects.toString(param.getValue())));

paramPairs.add(paramPair.toString());
}

return StringUtils.join(paramPairs, "&");
}

return urlDecode(var.toString());
}

return urlDecode(args[0]);
}

private String urlDecode(String s) {
try {
return URLDecoder.decode(s, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.hubspot.jinjava.lib.filter;

import static org.assertj.core.api.Assertions.assertThat;

import com.hubspot.jinjava.BaseInterpretingTest;
import java.util.LinkedHashMap;
import java.util.Map;
import org.junit.Before;
import org.junit.Test;

public class UrlDecodeFilterTest extends BaseInterpretingTest {
private UrlDecodeFilter filter;

@Before
public void setup() {
filter = new UrlDecodeFilter();
}

@Test
public void itDecodesDictAsParamPairs() {
Map<String, String> dict = new LinkedHashMap<>();
dict.put("foo", "bar%3Dset");
dict.put("other", "val");

assertThat(filter.filter(dict, interpreter)).isEqualTo("foo=bar=set&other=val");
}

@Test
public void itDecodesVarString() {
assertThat(filter.filter("http%3A%2F%2Ffoo.com%3Fbar%26food", interpreter))
.isEqualTo("http://foo.com?bar&food");
}

@Test
public void itDecodesArgWhenNoVar() {
assertThat(filter.filter(null, interpreter, "foo%26you")).isEqualTo("foo&you");
}
}

0 comments on commit 5736b70

Please sign in to comment.