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