You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@servicecomb.apache.org by GitBox <gi...@apache.org> on 2018/01/09 00:37:04 UTC

[GitHub] WillemJiang closed pull request #484: [SCB-199] bug fix: consumer upload file, did not set correct boundary c?

WillemJiang closed pull request #484: [SCB-199] bug fix: consumer upload file, did not set correct boundary c?
URL: https://github.com/apache/incubator-servicecomb-java-chassis/pull/484
 
 
   

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/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 2eda3634c..67a257b20 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 @@ private void attachFile(String boundary, Iterator<Entry<String, Part>> uploadsIt
       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 @@ private Buffer boundaryEndInfo(String boundary) {
         .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 f56e711d7..68a2e1e10 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.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 MultiMap headers() {
     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 d588c22a0..485b05128 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 @@ private void testUpload(RestTemplate template, String cseUrlPrefix) throws IOExc
     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 @@ private void testUpload(RestTemplate template, String cseUrlPrefix) throws IOExc
     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 7176abecd..cfe4bc90f 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 @@ private String _fileUpload(MultipartFile file1, Part file2) {
     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 9a152f8c9..601126197 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.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 InputStream getInputStream() throws IOException {
 
   @Override
   public String getContentType() {
-    return contentType;
+    return contentType != null ? contentType : MediaType.APPLICATION_OCTET_STREAM;
   }
 
   @SuppressWarnings("unchecked")
@@ -57,6 +60,19 @@ public String getSubmittedFileName() {
     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 aed6c6d6f..72ea50e29 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 FilePart(String name, String file) {
   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 22c53e47e..a236c4434 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 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 000000000..3e85536f8
--- /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 dcd5177d4..20c581d53 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 void getInputStream() throws IOException {
 
   @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,10 +68,32 @@ public void getSubmittedFileName() throws IOException {
     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();


 

----------------------------------------------------------------
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:
users@infra.apache.org


With regards,
Apache Git Services