liubao68 closed pull request #670: [SCB-512] download support chinese and space 
in file name
URL: https://github.com/apache/incubator-servicecomb-java-chassis/pull/670
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git 
a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java
 
b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java
index 2303cc01b..79aedb665 100644
--- 
a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java
+++ 
b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java
@@ -113,7 +113,7 @@ protected void testAllTransport(String microserviceName, 
RestTemplate template,
 
   private void testUpload(RestTemplate template, String cseUrlPrefix) throws 
IOException {
     String file1Content = "hello world";
-    File file1 = File.createTempFile("upload1", ".txt");
+    File file1 = File.createTempFile("测 试", ".txt");
     FileUtils.writeStringToFile(file1, file1Content);
 
     String file2Content = " bonjour";
diff --git 
a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestDownload.java
 
b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestDownload.java
index 303c00142..6472171ed 100644
--- 
a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestDownload.java
+++ 
b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestDownload.java
@@ -98,9 +98,15 @@ public void runRest() {
     futures.add(checkFile(intf.file(content)));
     futures.add(checkFuture(templateGet("file").saveAsString()));
 
-    // fix in next PR
-    //    futures.add(checkFile(intf.chineseAndSpaceFile(content)));
-    //    
futures.add(checkFuture(templateGet("chineseAndSpaceFile").saveAsString()));
+    {
+      ReadStreamPart part = intf.chineseAndSpaceFile(content);
+      TestMgr.check("测 试.test.txt", part.getSubmittedFileName());
+      futures.add(checkFile(part));
+
+      part = templateGet("chineseAndSpaceFile");
+      TestMgr.check("测 试.test.txt", part.getSubmittedFileName());
+      futures.add(checkFuture(part.saveAsString()));
+    }
 
     futures.add(checkFile(intf.resource(content)));
     futures.add(checkFuture(templateGet("resource").saveAsString()));
diff --git 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/http/HttpUtils.java
 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/http/HttpUtils.java
index deb6a977d..81c27a489 100644
--- 
a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/http/HttpUtils.java
+++ 
b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/http/HttpUtils.java
@@ -17,10 +17,8 @@
 package org.apache.servicecomb.foundation.common.http;
 
 import java.io.File;
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
+import java.net.URI;
+import java.net.URISyntaxException;
 
 import org.springframework.util.StringUtils;
 
@@ -52,34 +50,35 @@ public static String parseParamFromHeaderValue(String 
headerValue, String paramN
     return null;
   }
 
-  public static String uriEncode(String value) {
-    return uriEncode(value, StandardCharsets.UTF_8.name());
-  }
-
-  public static String uriEncode(String value, String enc) {
+  public static String uriEncodePath(String path) {
     try {
-      return URLEncoder.encode(value, enc).replace("+", "%20");
-    } catch (UnsupportedEncodingException e) {
-      throw new IllegalStateException(String.format("uriEncode failed, 
value=\"%s\", enc=\"%s\".", value, enc), e);
+      URI uri = new URI(null, null, path, null);
+      return uri.toASCIIString();
+    } catch (URISyntaxException e) {
+      throw new IllegalArgumentException(String.format("uriEncode failed, 
path=\"%s\".", path), e);
     }
   }
 
-  public static String uriDecode(String value) {
-    return uriDecode(value, StandardCharsets.UTF_8.name());
-  }
+  public static String uriDecodePath(String path) {
+    if (path == null) {
+      return null;
+    }
 
-  public static String uriDecode(String value, String enc) {
     try {
-      return URLDecoder.decode(value, enc);
-    } catch (UnsupportedEncodingException e) {
-      throw new IllegalStateException(String.format("uriDecode failed, 
value=\"%s\", enc=\"%s\".", value, enc), e);
+      return new URI(path).getPath();
+    } catch (URISyntaxException e) {
+      throw new IllegalArgumentException(String.format("uriDecode failed, 
path=\"%s\".", path), e);
     }
   }
 
+  /**
+   * only used by SDK to download from  serviceComb producer<br>
+   * no need to check rtf6266's "filename*" rule.
+   */
   public static String parseFileNameFromHeaderValue(String headerValue) {
     String fileName = parseParamFromHeaderValue(headerValue, "filename");
     fileName = StringUtils.isEmpty(fileName) ? "default" : fileName;
-    fileName = uriDecode(fileName);
+    fileName = uriDecodePath(fileName);
     return new File(fileName).getName();
   }
 }
diff --git 
a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/http/TestHttpUtils.java
 
b/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/http/TestHttpUtils.java
index 18f8906cf..5fbd603c0 100644
--- 
a/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/http/TestHttpUtils.java
+++ 
b/foundations/foundation-common/src/test/java/org/apache/servicecomb/foundation/common/http/TestHttpUtils.java
@@ -16,7 +16,7 @@
  */
 package org.apache.servicecomb.foundation.common.http;
 
-import java.io.UnsupportedEncodingException;
+import java.net.URISyntaxException;
 
 import org.hamcrest.Matchers;
 import org.junit.Assert;
@@ -59,36 +59,46 @@ public void parseParamFromHeaderValue_keyNotFound() {
     Assert.assertNull(HttpUtils.parseParamFromHeaderValue("xx;k=", "kk"));
   }
 
+  @Test
+  public void uriEncode_null() {
+    Assert.assertEquals("", HttpUtils.uriEncodePath(null));
+  }
+
+  @Test
+  public void uriDecode_null() {
+    Assert.assertNull(HttpUtils.uriDecodePath(null));
+  }
+
   @Test
   public void uriEncode_chineseAndSpace() {
-    String encoded = HttpUtils.uriEncode("测 试");
+    String encoded = HttpUtils.uriEncodePath("测 试");
     Assert.assertEquals("%E6%B5%8B%20%E8%AF%95", encoded);
-    Assert.assertEquals("测 试", HttpUtils.uriDecode(encoded));
+    Assert.assertEquals("测 试", HttpUtils.uriDecodePath(encoded));
   }
 
   @Test
   public void uriEncode_failed() {
-    expectedException.expect(IllegalStateException.class);
-    expectedException.expectMessage(Matchers.is("uriEncode failed, value=\"\", 
enc=\"notExistEnc\"."));
-    
expectedException.expectCause(Matchers.instanceOf(UnsupportedEncodingException.class));
+    expectedException.expect(IllegalArgumentException.class);
+    expectedException.expectMessage(Matchers.is("uriEncode failed, 
path=\":\"."));
+    
expectedException.expectCause(Matchers.instanceOf(URISyntaxException.class));
 
-    HttpUtils.uriEncode("", "notExistEnc");
+    HttpUtils.uriEncodePath(":");
   }
 
   @Test
   public void uriDecode_failed() {
-    expectedException.expect(IllegalStateException.class);
+    expectedException.expect(IllegalArgumentException.class);
     expectedException
-        .expectMessage(Matchers.is("uriDecode failed, 
value=\"%E6%B5%8B%20%E8%AF%95\", enc=\"notExistEnc\"."));
-    
expectedException.expectCause(Matchers.instanceOf(UnsupportedEncodingException.class));
+        .expectMessage(Matchers.is("uriDecode failed, path=\":\"."));
+    
expectedException.expectCause(Matchers.instanceOf(URISyntaxException.class));
 
-    HttpUtils.uriDecode("%E6%B5%8B%20%E8%AF%95", "notExistEnc");
+    HttpUtils.uriDecodePath(":");
   }
 
   @Test
   public void parseFileNameFromHeaderValue() {
     String fileName = "测 试.txt";
-    String encoded = HttpUtils.uriEncode(fileName);
+    String encoded = HttpUtils.uriEncodePath(fileName);
     Assert.assertEquals(fileName, 
HttpUtils.parseFileNameFromHeaderValue("xx;filename=" + encoded));
   }
 
diff --git 
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/VertxServerResponseToHttpServletResponse.java
 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/VertxServerResponseToHttpServletResponse.java
index 8f55886a6..ed776093e 100644
--- 
a/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/VertxServerResponseToHttpServletResponse.java
+++ 
b/foundations/foundation-vertx/src/main/java/org/apache/servicecomb/foundation/vertx/http/VertxServerResponseToHttpServletResponse.java
@@ -29,6 +29,7 @@
 
 import org.apache.commons.io.IOUtils;
 import org.apache.servicecomb.foundation.common.http.HttpStatus;
+import org.apache.servicecomb.foundation.common.http.HttpUtils;
 import org.apache.servicecomb.foundation.common.part.FilePartForSend;
 import org.apache.servicecomb.foundation.vertx.stream.InputStreamToReadStream;
 import org.slf4j.Logger;
@@ -170,8 +171,11 @@ protected void prepareSendPartHeader(Part part) {
     }
 
     if (!serverResponse.headers().contains(HttpHeaders.CONTENT_DISPOSITION)) {
+      // to support chinese and space filename in firefox
+      // must use "filename*", (https://tools.ietf.org/html/rtf6266)
+      String encodedFileName = 
HttpUtils.uriEncodePath(part.getSubmittedFileName());
       serverResponse.putHeader(HttpHeaders.CONTENT_DISPOSITION,
-          "attachment;filename=" + part.getSubmittedFileName());
+          "attachment;filename=" + encodedFileName + ";filename*=utf-8''" + 
encodedFileName);
     }
   }
 
diff --git 
a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestVertxServerResponseToHttpServletResponse.java
 
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestVertxServerResponseToHttpServletResponse.java
index f66dd1b7e..6afd96495 100644
--- 
a/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestVertxServerResponseToHttpServletResponse.java
+++ 
b/foundations/foundation-vertx/src/test/java/org/apache/servicecomb/foundation/vertx/http/TestVertxServerResponseToHttpServletResponse.java
@@ -304,14 +304,16 @@ public void prepareSendPartHeader_update(@Mocked Part 
part) {
         part.getContentType();
         result = "type";
         part.getSubmittedFileName();
-        result = "name";
+        result = "测     试";
       }
     };
     response.prepareSendPartHeader(part);
 
     Assert.assertTrue(serverResponse.isChunked());
     Assert.assertEquals("type", response.getHeader(HttpHeaders.CONTENT_TYPE));
-    Assert.assertEquals("attachment;filename=name", 
response.getHeader(HttpHeaders.CONTENT_DISPOSITION));
+    Assert.assertEquals(
+        
"attachment;filename=%E6%B5%8B%20%20%20%20%20%E8%AF%95;filename*=utf-8''%E6%B5%8B%20%20%20%20%20%E8%AF%95",
+        response.getHeader(HttpHeaders.CONTENT_DISPOSITION));
   }
 
   @Test


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to