diff --git a/src/main/java/com/wizzardo/http/FileTreeHandler.java b/src/main/java/com/wizzardo/http/FileTreeHandler.java index 29e6545..33966a3 100644 --- a/src/main/java/com/wizzardo/http/FileTreeHandler.java +++ b/src/main/java/com/wizzardo/http/FileTreeHandler.java @@ -8,13 +8,14 @@ import com.wizzardo.http.response.RangeResponseHelper; import com.wizzardo.http.response.Response; import com.wizzardo.http.response.Status; +import com.wizzardo.http.utils.PercentEncoding; import com.wizzardo.tools.misc.DateIso8601; import com.wizzardo.tools.misc.Unchecked; import java.io.File; import java.io.IOException; -import java.net.URLDecoder; import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Comparator; import java.util.Date; @@ -263,8 +264,10 @@ protected String encodeName(String name) { return Unchecked.call(() -> URLEncoder.encode(name, "utf-8").replace("+", "%20")); } - private String decodePath(String path) { - return Unchecked.call(() -> URLDecoder.decode(VERSION_PATTERN.matcher(path).replaceAll(""), "utf-8")); + protected String decodePath(String path) { + byte[] bytes = VERSION_PATTERN.matcher(path).replaceAll("").getBytes(StandardCharsets.UTF_8); + int decodedLength = PercentEncoding.decode(bytes, 0, bytes.length, true); + return new String(bytes, 0, decodedLength, StandardCharsets.UTF_8); } public static class HandlerContext { diff --git a/src/main/java/com/wizzardo/http/utils/PercentEncoding.java b/src/main/java/com/wizzardo/http/utils/PercentEncoding.java index 6ae1673..15bd14b 100644 --- a/src/main/java/com/wizzardo/http/utils/PercentEncoding.java +++ b/src/main/java/com/wizzardo/http/utils/PercentEncoding.java @@ -3,16 +3,13 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; -/** - * Created by Mikhail Bobrutskov on 20.08.17. - */ public class PercentEncoding { static byte[] mapping; static { mapping = new byte[128]; - Arrays.fill(mapping, (byte) 128); + Arrays.fill(mapping, (byte) 127); mapping['0'] = 0; mapping['1'] = 1; mapping['2'] = 2; @@ -40,6 +37,10 @@ public class PercentEncoding { } public static int decode(byte[] bytes, int from, int to) { + return decode(bytes, from, to, false); + } + + public static int decode(byte[] bytes, int from, int to, boolean ignorePlus) { int position = from; int i = from; try { @@ -51,7 +52,7 @@ public static int decode(byte[] bytes, int from, int to) { byte value = (byte) ((getHexValue(bytes[++i]) << 4) + getHexValue(bytes[++i])); bytes[position++] = value; - } else if (b == '+') { + } else if (!ignorePlus && b == '+') { bytes[position++] = ' '; } else if (position == i) { position++; @@ -72,7 +73,7 @@ public static int getHexValue(int c) { throw new IllegalStateException("unexpected char for hex value: " + (char) c); c = mapping[c]; - if (c == 128) + if (c == 127) throw new IllegalStateException("unexpected char for hex value"); return c;