You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ni...@apache.org on 2018/01/09 00:37:03 UTC

[incubator-servicecomb-java-chassis] branch master updated: SCB-199 bug fix: consumer upload file, did not set correct boundary contentType

This is an automated email from the ASF dual-hosted git repository.

ningjiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git


The following commit(s) were added to refs/heads/master by this push:
     new 8369fab  SCB-199 bug fix: consumer upload file, did not set correct boundary contentType
8369fab is described below

commit 8369fab8767d3983fbeb9b84f9d715cb8e9cade0
Author: wujimin <wu...@huawei.com>
AuthorDate: Thu Jan 4 10:17:34 2018 +0800

    SCB-199 bug fix: consumer upload file, did not set correct boundary contentType
---
 .../rest/codec/param/RestClientRequestImpl.java    |  12 +-
 .../codec/param/TestRestClientRequestImpl.java     |  46 +++++-
 .../client/CodeFirstRestTemplateSpringmvc.java     |  17 ++-
 .../demo/springmvc/server/CodeFirstSpringmvc.java  |  10 +-
 .../foundation/common/part/AbstractPart.java       |  22 ++-
 .../foundation/common/part/FilePart.java           |   2 +-
 .../foundation/common/part/ResourcePart.java       |   2 +-
 .../src/main/resources/META-INF/mime.types         | 157 +++++++++++++++++++++
 .../foundation/common/part/TestAbstractPart.java   |  26 +++-
 9 files changed, 278 insertions(+), 16 deletions(-)

diff --git a/common/common-rest/src/main/java/io/servicecomb/common/rest/codec/param/RestClientRequestImpl.java b/common/common-rest/src/main/java/io/servicecomb/common/rest/codec/param/RestClientRequestImpl.java
index 2eda363..67a257b 100644
--- a/common/common-rest/src/main/java/io/servicecomb/common/rest/codec/param/RestClientRequestImpl.java
+++ b/common/common-rest/src/main/java/io/servicecomb/common/rest/codec/param/RestClientRequestImpl.java
@@ -192,7 +192,7 @@ public class RestClientRequestImpl implements RestClientRequest {
       attachFile(boundary, uploadsIterator);
     });
 
-    Buffer fileHeader = fileBoundaryInfo(boundary, name, filename);
+    Buffer fileHeader = fileBoundaryInfo(boundary, name, part);
     request.write(fileHeader);
     Pump.pump(fileStream, request).start();
   }
@@ -203,12 +203,16 @@ public class RestClientRequestImpl implements RestClientRequest {
         .appendString("--" + boundary + "--\r\n");
   }
 
-  private Buffer fileBoundaryInfo(String boundary, String name, String filename) {
+  protected Buffer fileBoundaryInfo(String boundary, String name, Part part) {
     Buffer buffer = Buffer.buffer();
     buffer.appendString("\r\n");
     buffer.appendString("--" + boundary + "\r\n");
-    buffer.appendString("Content-Disposition: form-data; name=\"" + name + "\"; filename=\"" + filename + "\"\r\n");
-    buffer.appendString("Content-Type: multipart/form-data\r\n");
+    buffer.appendString("Content-Disposition: form-data; name=\"")
+        .appendString(name)
+        .appendString("\"; filename=\"")
+        .appendString(part.getSubmittedFileName() != null ? part.getSubmittedFileName() : "null")
+        .appendString("\"\r\n");
+    buffer.appendString("Content-Type: ").appendString(part.getContentType()).appendString("\r\n");
     buffer.appendString("Content-Transfer-Encoding: binary\r\n");
     buffer.appendString("\r\n");
     return buffer;
diff --git a/common/common-rest/src/test/java/io/servicecomb/common/rest/codec/param/TestRestClientRequestImpl.java b/common/common-rest/src/test/java/io/servicecomb/common/rest/codec/param/TestRestClientRequestImpl.java
index f56e711..68a2e1e 100644
--- a/common/common-rest/src/test/java/io/servicecomb/common/rest/codec/param/TestRestClientRequestImpl.java
+++ b/common/common-rest/src/test/java/io/servicecomb/common/rest/codec/param/TestRestClientRequestImpl.java
@@ -16,6 +16,9 @@
  */
 package io.servicecomb.common.rest.codec.param;
 
+import javax.servlet.http.Part;
+import javax.ws.rs.core.MediaType;
+
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -24,6 +27,7 @@ import io.vertx.core.buffer.Buffer;
 import io.vertx.core.http.CaseInsensitiveHeaders;
 import io.vertx.core.http.HttpClientRequest;
 import io.vertx.core.http.HttpHeaders;
+import mockit.Expectations;
 import mockit.Mock;
 import mockit.MockUp;
 import mockit.Mocked;
@@ -66,7 +70,47 @@ public class TestRestClientRequestImpl {
     restClientRequest.end();
     Buffer buffer = restClientRequest.getBodyBuffer();
     Assert.assertEquals("I love servicecomb", buffer.toString());
-    Assert.assertEquals("sessionid=abcdefghijklmnopqrstuvwxyz; region=china-north; ", 
+    Assert.assertEquals("sessionid=abcdefghijklmnopqrstuvwxyz; region=china-north; ",
         restClientRequest.request.headers().get(HttpHeaders.COOKIE));
   }
+
+  @Test
+  public void fileBoundaryInfo_nullSubmittedFileName(@Mocked Part part) {
+    new Expectations() {
+      {
+        part.getSubmittedFileName();
+        result = null;
+        part.getContentType();
+        result = "abc";
+      }
+    };
+    RestClientRequestImpl restClientRequest = new RestClientRequestImpl(request, null, null);
+    Buffer buffer = restClientRequest.fileBoundaryInfo("boundary", "name", part);
+    Assert.assertEquals("\r\n" +
+        "--boundary\r\n" +
+        "Content-Disposition: form-data; name=\"name\"; filename=\"null\"\r\n" +
+        "Content-Type: abc\r\n" +
+        "Content-Transfer-Encoding: binary\r\n" +
+        "\r\n", buffer.toString());
+  }
+
+  @Test
+  public void fileBoundaryInfo_validSubmittedFileName(@Mocked Part part) {
+    new Expectations() {
+      {
+        part.getSubmittedFileName();
+        result = "a.txt";
+        part.getContentType();
+        result = MediaType.TEXT_PLAIN;
+      }
+    };
+    RestClientRequestImpl restClientRequest = new RestClientRequestImpl(request, null, null);
+    Buffer buffer = restClientRequest.fileBoundaryInfo("boundary", "name", part);
+    Assert.assertEquals("\r\n" +
+        "--boundary\r\n" +
+        "Content-Disposition: form-data; name=\"name\"; filename=\"a.txt\"\r\n" +
+        "Content-Type: text/plain\r\n" +
+        "Content-Transfer-Encoding: binary\r\n" +
+        "\r\n", buffer.toString());
+  }
 }
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/io/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java b/demo/demo-springmvc/springmvc-client/src/main/java/io/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java
index d588c22..485b051 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/java/io/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/io/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java
@@ -100,7 +100,14 @@ public class CodeFirstRestTemplateSpringmvc extends CodeFirstRestTemplate {
     File someFile = File.createTempFile("upload2", ".txt");
     FileUtils.writeStringToFile(someFile, file2Content);
 
-    String expect = file1.getName() + ":" + file1Content + "\n" + someFile.getName() + ":" + file2Content;
+    String expect = String.format("%s:%s:%s\n"
+        + "%s:%s:%s",
+        file1.getName(),
+        MediaType.TEXT_PLAIN_VALUE,
+        file1Content,
+        someFile.getName(),
+        MediaType.TEXT_PLAIN_VALUE,
+        file2Content);
 
     String result = testRestTemplateUpload(template, cseUrlPrefix, file1, someFile);
     TestMgr.check(expect, result);
@@ -108,7 +115,13 @@ public class CodeFirstRestTemplateSpringmvc extends CodeFirstRestTemplate {
     result = uploadPartAndFile.fileUpload(new FilePart(null, file1), someFile);
     TestMgr.check(expect, result);
 
-    expect = "null:" + file1Content + "\n" + someFile.getName() + ":" + file2Content;
+    expect = String.format("null:%s:%s\n"
+        + "%s:%s:%s",
+        MediaType.APPLICATION_OCTET_STREAM_VALUE,
+        file1Content,
+        someFile.getName(),
+        MediaType.TEXT_PLAIN_VALUE,
+        file2Content);
     result = uploadStreamAndResource
         .fileUpload(new ByteArrayInputStream(file1Content.getBytes(StandardCharsets.UTF_8)),
             new PathResource(someFile.getAbsolutePath()));
diff --git a/demo/demo-springmvc/springmvc-server/src/main/java/io/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java b/demo/demo-springmvc/springmvc-server/src/main/java/io/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java
index 7176abe..cfe4bc9 100644
--- a/demo/demo-springmvc/springmvc-server/src/main/java/io/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java
+++ b/demo/demo-springmvc/springmvc-server/src/main/java/io/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java
@@ -94,8 +94,14 @@ public class CodeFirstSpringmvc {
     try (InputStream is1 = file1.getInputStream(); InputStream is2 = file2.getInputStream()) {
       String content1 = IOUtils.toString(is1);
       String content2 = IOUtils.toString(is2);
-      return file1.getOriginalFilename() + ":" + content1 + "\n" +
-          file2.getSubmittedFileName() + ":" + content2;
+      return String.format("%s:%s:%s\n"
+          + "%s:%s:%s",
+          file1.getOriginalFilename(),
+          file1.getContentType(),
+          content1,
+          file2.getSubmittedFileName(),
+          file2.getContentType(),
+          content2);
     } catch (IOException e) {
       throw new IllegalArgumentException(e);
     }
diff --git a/foundations/foundation-common/src/main/java/io/servicecomb/foundation/common/part/AbstractPart.java b/foundations/foundation-common/src/main/java/io/servicecomb/foundation/common/part/AbstractPart.java
index 9a152f8..6011261 100644
--- a/foundations/foundation-common/src/main/java/io/servicecomb/foundation/common/part/AbstractPart.java
+++ b/foundations/foundation-common/src/main/java/io/servicecomb/foundation/common/part/AbstractPart.java
@@ -21,15 +21,18 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.util.Collection;
 
+import javax.activation.MimetypesFileTypeMap;
 import javax.servlet.http.Part;
 import javax.ws.rs.core.MediaType;
 
 public class AbstractPart implements Part {
+  private static MimetypesFileTypeMap mimetypesFileTypeMap = new MimetypesFileTypeMap();
+
   protected String name;
 
-  protected String submittedFileName;
+  private String submittedFileName;
 
-  protected String contentType = MediaType.MULTIPART_FORM_DATA;
+  protected String contentType;
 
   @Override
   public InputStream getInputStream() throws IOException {
@@ -38,7 +41,7 @@ public class AbstractPart implements Part {
 
   @Override
   public String getContentType() {
-    return contentType;
+    return contentType != null ? contentType : MediaType.APPLICATION_OCTET_STREAM;
   }
 
   @SuppressWarnings("unchecked")
@@ -57,6 +60,19 @@ public class AbstractPart implements Part {
     return submittedFileName;
   }
 
+  public void setSubmittedFileName(String submittedFileName) {
+    this.submittedFileName = submittedFileName;
+    updateContentType();
+  }
+
+  private void updateContentType() {
+    if (contentType != null || submittedFileName == null) {
+      return;
+    }
+
+    contentType = mimetypesFileTypeMap.getContentType(submittedFileName);
+  }
+
   @Override
   public long getSize() {
     throw new Error("not supported method");
diff --git a/foundations/foundation-common/src/main/java/io/servicecomb/foundation/common/part/FilePart.java b/foundations/foundation-common/src/main/java/io/servicecomb/foundation/common/part/FilePart.java
index aed6c6d..72ea50e 100644
--- a/foundations/foundation-common/src/main/java/io/servicecomb/foundation/common/part/FilePart.java
+++ b/foundations/foundation-common/src/main/java/io/servicecomb/foundation/common/part/FilePart.java
@@ -34,7 +34,7 @@ public class FilePart extends AbstractPart {
   public FilePart(String name, File file) {
     this.name = name;
     this.file = file;
-    this.submittedFileName = this.file.getName();
+    this.setSubmittedFileName(this.file.getName());
   }
 
   @Override
diff --git a/foundations/foundation-common/src/main/java/io/servicecomb/foundation/common/part/ResourcePart.java b/foundations/foundation-common/src/main/java/io/servicecomb/foundation/common/part/ResourcePart.java
index 22c53e4..a236c44 100644
--- a/foundations/foundation-common/src/main/java/io/servicecomb/foundation/common/part/ResourcePart.java
+++ b/foundations/foundation-common/src/main/java/io/servicecomb/foundation/common/part/ResourcePart.java
@@ -28,7 +28,7 @@ public class ResourcePart extends AbstractPart {
   public ResourcePart(String name, Resource resource) {
     this.name = name;
     this.resource = resource;
-    this.submittedFileName = resource.getFilename();
+    this.setSubmittedFileName(resource.getFilename());
   }
 
   @Override
diff --git a/foundations/foundation-common/src/main/resources/META-INF/mime.types b/foundations/foundation-common/src/main/resources/META-INF/mime.types
new file mode 100644
index 0000000..3e85536
--- /dev/null
+++ b/foundations/foundation-common/src/main/resources/META-INF/mime.types
@@ -0,0 +1,157 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+application/octet-stream                    bin
+application/astound                         asd,asn
+application/fastman                         lcc
+application/java-archive                    jar
+application/java-serialized-object          ser
+application/java-vm                         class
+application/mac-binhex40                    hqx
+application/x-stuffit                       sit
+application/mbedlet                         mbd
+application/msword                          doc,dot,wiz,rtf
+application/oda                             oda
+application/pdf                             pdf
+application/postscript                      ai,eps,ps
+application/studiom                         smp
+application/timbuktu                        tbt
+application/vnd.ms-excel                    xls,xlw,xla,xlc,xlm,xlt
+application/vnd.ms-powerpoint               ppt,pps,pot
+application/vnd.ms-project                  mpp
+application/winhlp                          hlp
+application/x-javascript                    js
+application/x-javascript;charset=UTF-8      jsu
+application/x-java-jnlp-file                jnlp
+application/x-aim                           aim
+application/x-asap                          asp
+application/x-csh                           csh
+application/x-dvi                           dvi
+application/x-earthtime                     etc
+application/x-envoy                         evy
+application/x-gtar                          gtar
+application/x-cpio                          cpio
+application/x-hdf                           hdf
+application/x-latex                         latex
+application/x-javascript-config             jsc
+application/x-maker                         fm
+application/x-mif                           mif,mi
+application/x-mocha                         mocha,moc
+application/x-msaccess                      mdb
+application/x-mscardfile                    crd
+application/x-msclip                        clp
+application/x-msmediaview                   m13,m14
+application/x-msmetafile                    wmf
+application/x-msmoney                       mny
+application/x-mspublisher                   pub
+application/x-msschedule                    scd
+application/x-msterminal                    trm
+application/x-mswrite                       wri
+application/x-NET-Install                   ins
+application/x-netcdf                        nc,cdf
+application/x-ns-proxy-autoconfig           proxy
+application/x-salsa                         slc
+application/x-sh                            sh
+application/x-shar                          shar
+application/x-sprite                        spr,sprite
+application/x-tar                           tar
+application/x-tcl                           tcl
+application/x-perl                          pl
+application/x-tex                           tex
+application/x-texinfo                       texinfo,texi
+application/x-timbuktu                      tbp
+application/x-tkined                        tki,tkined
+application/x-troff-man                     man
+application/x-troff-me                      me
+application/x-troff-ms                      ms
+application/x-troff                         t,tr,roff
+application/x-wais-source                   src
+application/zip                             zip
+application/pre-encrypted                   enc
+application/x-pkcs7-crl                     crl
+application/x-fortezza-ckl                  ckl
+application/xml-dtd                         dtd
+
+audio/basic                                 au,snd
+audio/echospeech                            es,esl
+audio/midi                                  midi,mid
+audio/x-aiff                                aif,aiff,aifc
+audio/x-wav                                 wav
+audio/x-pn-realaudio                        ra,ram
+audio/x-pac                                 pac
+audio/x-epac                                pae
+audio/x-liveaudio                           lam
+
+drawing/x-dwf                               dwf
+
+image/fif                                   fif
+image/x-icon                                ico
+image/gif                                   gif
+image/ief                                   ief
+image/ifs                                   ifs
+image/jpeg                                  jpeg,jpg,jpe,jfif,pjpeg,pjp
+image/png                                   png
+image/tiff                                  tiff,tif
+image/vnd                                   dwg,svf
+image/wavelet                               wi
+image/bmp                                   bmp
+image/x-photo-cd                            pcd
+image/x-cmu-raster                          ras
+image/x-portable-anymap                     pnm
+image/x-portable-bitmap                     pbm
+image/x-portable-graymap                    pgm
+image/x-portable-pixmap                     ppm
+image/x-rgb                                 rgb
+image/x-xbitmap                             xbm
+image/x-xpixmap                             xpm
+image/x-xwindowdump                         xwd
+
+text/css                                    css
+
+text/html                                   htm,html
+text/plain                                  txt
+text/richtext                               rtx
+text/tab-separated-values                   tsv
+text/x-setext                               etx
+text/x-speech                               talk
+text/xml                                    xml
+text/xul                                    xul
+
+video/isivideo                              fvi
+video/mpeg                                  mpeg,mpg,mpe,mpv,vbs,mpegv
+video/x-mpeg2                               mpv2,mp2v
+video/msvideo                               avi
+video/quicktime                             qt,mov,moov
+video/vivo                                  viv,vivo
+video/wavelet                               wv
+video/x-sgi-movie                           movie
+
+x-world/x-svr                               svr
+x-world/x-vrml                              wrl
+x-world/x-vrt                               vrt
+
+x-conference/x-cooltalk                     ice
+
+magnus-internal/imagemap                    map
+magnus-internal/parsed-html                 shtml
+magnus-internal/cgi                         cgi,exe,bat
+
+application/x-x509-ca-cert                  cacert
+
+application/x-x509-server-cert              scert
+application/x-x509-user-cert                ucert
+application/x-x509-email-cert               ecert
+
diff --git a/foundations/foundation-common/src/test/java/io/servicecomb/foundation/common/part/TestAbstractPart.java b/foundations/foundation-common/src/test/java/io/servicecomb/foundation/common/part/TestAbstractPart.java
index dcd5177..20c581d 100644
--- a/foundations/foundation-common/src/test/java/io/servicecomb/foundation/common/part/TestAbstractPart.java
+++ b/foundations/foundation-common/src/test/java/io/servicecomb/foundation/common/part/TestAbstractPart.java
@@ -47,7 +47,7 @@ public class TestAbstractPart {
 
   @Test
   public void getContentType() throws IOException {
-    Assert.assertEquals(MediaType.MULTIPART_FORM_DATA, part.getContentType());
+    Assert.assertEquals(MediaType.APPLICATION_OCTET_STREAM, part.getContentType());
 
     String contentType = "abc";
     part.contentType(contentType);
@@ -68,11 +68,33 @@ public class TestAbstractPart {
     Assert.assertNull(part.getSubmittedFileName());
 
     String submittedFileName = "abc";
-    part.submittedFileName = submittedFileName;
+    part.setSubmittedFileName(submittedFileName);
     Assert.assertEquals(submittedFileName, part.getSubmittedFileName());
   }
 
   @Test
+  public void setSubmittedFileName_contentTypeNotNull() {
+    part.contentType(MediaType.TEXT_PLAIN);
+    part.setSubmittedFileName("a.zip");
+
+    Assert.assertEquals(MediaType.TEXT_PLAIN, part.getContentType());
+  }
+
+  @Test
+  public void setSubmittedFileName_setNull() {
+    part.setSubmittedFileName(null);
+
+    Assert.assertEquals(MediaType.APPLICATION_OCTET_STREAM, part.getContentType());
+  }
+
+  @Test
+  public void setSubmittedFileName_setNormal() {
+    part.setSubmittedFileName("a.zip");
+
+    Assert.assertEquals("application/zip", part.getContentType());
+  }
+
+  @Test
   public void getSize() {
     initExpectedException();
 

-- 
To stop receiving notification emails like this one, please contact
['"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>'].