diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/ServletUtil.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/ServletUtil.java index 3e3955ba8e7..4b12a2d7c46 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/ServletUtil.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/util/ServletUtil.java @@ -114,6 +114,21 @@ public static String encodePath(final String path) { return new URIBuilder().setPath(path).toString(); } + /** + * Decode a string regarded as the path component of an URI. + * + * @param path the path component to decode + * @return decoded path, null if UTF-8 is not supported + * @throws URISyntaxException + */ + public static String decodePath(final String path) { + try { + return new URI(path).getPath(); + } catch (URISyntaxException e) { + throw new AssertionError("Failed to decode URI: " + path); + } + } + /** * Parse and decode the path component from the given request. * @param request Http request to parse diff --git a/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/web/HftpFileSystem.java b/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/web/HftpFileSystem.java index cafe3cb5658..63b793193b9 100644 --- a/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/web/HftpFileSystem.java +++ b/hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/web/HftpFileSystem.java @@ -442,12 +442,14 @@ public void startElement(String ns, String localname, String qname, modif, atime, FsPermission.valueOf(attrs.getValue("permission")), attrs.getValue("owner"), attrs.getValue("group"), HftpFileSystem.this.makeQualified( - new Path(getUri().toString(), attrs.getValue("path")))) + new Path(getUri().toString(), ServletUtil.decodePath( + attrs.getValue("path"))))) : new FileStatus(0L, true, 0, 0L, modif, atime, FsPermission.valueOf(attrs.getValue("permission")), attrs.getValue("owner"), attrs.getValue("group"), HftpFileSystem.this.makeQualified( - new Path(getUri().toString(), attrs.getValue("path")))); + new Path(getUri().toString(), ServletUtil.decodePath( + attrs.getValue("path"))))); fslist.add(fs); } diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/ListPathsServlet.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/ListPathsServlet.java index fcf25f516e5..f6ac6ca1157 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/ListPathsServlet.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/ListPathsServlet.java @@ -69,7 +69,7 @@ static void writeInfo(final Path fullpath, final HdfsFileStatus i, final XMLOutputter doc) throws IOException { final SimpleDateFormat ldf = df.get(); doc.startTag(i.isDir() ? "directory" : "file"); - doc.attribute("path", fullpath.toUri().getPath()); + doc.attribute("path", ServletUtil.encodePath(fullpath.toUri().getPath())); doc.attribute("modified", ldf.format(new Date(i.getModificationTime()))); doc.attribute("accesstime", ldf.format(new Date(i.getAccessTime()))); if (!i.isDir()) { diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/web/TestHftpFileSystem.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/web/TestHftpFileSystem.java index 09bc9b3b890..245e7215e2a 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/web/TestHftpFileSystem.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/web/TestHftpFileSystem.java @@ -83,7 +83,7 @@ public class TestHftpFileSystem { // URI percent encodes, Request#getPathInfo decodes new Path("/foo bar/foo bar"), new Path("/foo?bar/foo?bar"), - new Path("/foo\">bar/foo\">bar"), }; + new Path("/foo\">bar/foo\">bar"), new Path("/节节高@2X.png"), }; @BeforeClass public static void setUp() throws Exception {